Source code for ways.core.pathrip

#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''Tools for dealing with file paths.

All of these functions should be OS-independent or at least indicate if not.

'''

# IMPORT STANDARD LIBRARIES
import os

# IMPORT THIRD-PARTY LIBRARIES
import six

# IMPORT LOCAL LIBRARIES
from . import check


[docs]def split_os_path_asunder(path): '''Split up a path, even if it is in Windows and has a letter drive. Args: path (str): The path to split up into parts. Returns: list[str]: The split path. ''' drive, path = os.path.splitdrive(path) paths = split_path_asunder(path) if drive: return [drive] + paths return paths
[docs]def split_path_asunder(path): r'''Split a path up into individual folders. This function is OS-independent but does not take into account Windows drive letters. For that, check out split_os_path_asunder. Reference: http://www.stackoverflow.com/questions/4579908. Note: If this method is used on Windows paths, it's recommended to os.path.splitdrive() before running this method on some path, to handle edge cases where driver letters have different meanings (example: c:path versus c:\path) Args: path (str): The path to split up into parts. Returns: list[str]: The split path. ''' parts = [] while True: newpath, tail = os.path.split(path) if newpath == path: assert not tail if path: parts.append(path) break parts.append(tail) path = newpath parts.reverse() return parts
[docs]def get_subfolder_root(path, subfolders, method='tail'): '''Find the path of some path, using some consecutive subfolders. Args: path (str): The path to get the root of. subfolders (list[str] or str): The folders to search for in the path. method (:obj:`callable[str, list[str]] or str`, optional): The strategy used to get the root subfolders. A function is acceptable or a preset string can be used. String options: 'tail': Search a path to get the longest possible match (the last tail). Returns: str: The root path that contains the subfolders. ''' subfolders = check.force_itertype(subfolders) subfolders_copy = list(subfolders) subfolders = [] for folder in subfolders_copy: subfolders.extend(split_os_path_asunder(folder)) if isinstance(method, six.string_types): methods = { 'tail': get_subfolder_root_tail, } method = methods[method.lower()] return method(path, subfolders)
[docs]def get_subfolder_root_tail(path, subfolders): '''Get the longest match of some path, using some subfolders. Example: >>> root = '/jobs/rnd_ftrack/shots/sh01/maya/scenes/modeling/RELEASE/some_file_name.ma' >>> subfolders = ['maya/scenes'] >>> get_subfolder_root_tail(root, subfolders) '/jobs/rnd_ftrack/shots/sh01/maya/scenes' Note: If a path has more than one match for subfolders, the last match is used. Args: path (str): The path to get the root of. subfolders (list[str] or str): The folders to search for in the path. Returns: str: The path that matches some subfolder or an empty string. ''' root_parts = split_os_path_asunder(path) subfolders = list(reversed(subfolders)) current_subfolder_index = 0 final_index = -1 for index, part in enumerate(reversed(root_parts)): try: current_part_to_find = subfolders[current_subfolder_index] except IndexError: final_index = index break if part == current_part_to_find: current_subfolder_index += 1 else: # The subfolders are assumed to be consecutive - so if it's not a # match, restart from the beginning and keep iterating over the # path # current_subfolder_index = 0 if final_index == -1: return '' return os.path.join(*root_parts[:-1 * (final_index - len(subfolders))])