diff options
Diffstat (limited to 'release/scripts/modules/bpy/path.py')
-rw-r--r--[-rwxr-xr-x] | release/scripts/modules/bpy/path.py | 140 |
1 files changed, 98 insertions, 42 deletions
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index 63149f2fce8..9a29b713882 100755..100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -26,12 +26,16 @@ functions for dealing with paths in Blender. import bpy as _bpy import os as _os -def abspath(path): + +def abspath(path, start=None): """ Returns the absolute path relative to the current blend file using the "//" prefix. + + :arg start: Relative to this path, when not set the current filename is used. + :type start: string """ if path.startswith("//"): - return _os.path.join(_os.path.dirname(_bpy.data.filepath), path[2:]) + return _os.path.join(_os.path.dirname(_bpy.data.filepath if start is None else start), path[2:]) return path @@ -51,6 +55,17 @@ def relpath(path, start=None): return path +def is_subdir(path, directory): + """ + Returns true if *path* in a subdirectory of *directory*. + Both paths must be absolute. + """ + from os.path import normpath, normcase + path = normpath(normcase(path)) + directory = normpath(normcase(directory)) + return path.startswith(directory) + + def clean_name(name, replace="_"): """ Returns a name with characters replaced that may cause problems under various circumstances, such as writing to a file. @@ -93,64 +108,71 @@ def display_name(name): name_base = name_base.replace("_", " ") if name_base.islower(): - return name_base.capitalize() + return name_base.lower().title() else: return name_base +def display_name_from_filepath(name): + """ + Returns the path stripped of directort and extension, ensured to be utf8 compatible. + """ + return _os.path.splitext(_os.path.basename(name))[0].encode("utf8", "replace").decode("utf8") + + def resolve_ncase(path): - """ - Resolve a case insensitive path on a case sensitive system, - returning a string with the path if found else return the original path. - """ + """ + Resolve a case insensitive path on a case sensitive system, + returning a string with the path if found else return the original path. + """ - import os + import os - def _ncase_path_found(path): - if path=='' or os.path.exists(path): - return path, True + def _ncase_path_found(path): + if not path or os.path.exists(path): + return path, True - filename = os.path.basename(path) # filename may be a directory or a file - dirpath = os.path.dirname(path) + filename = os.path.basename(path) # filename may be a directory or a file + dirpath = os.path.dirname(path) - suffix = "" - if not filename: # dir ends with a slash? - if len(dirpath) < len(path): - suffix = path[:len(path)-len(dirpath)] + suffix = "" + if not filename: # dir ends with a slash? + if len(dirpath) < len(path): + suffix = path[:len(path) - len(dirpath)] - filename = os.path.basename(dirpath) - dirpath = os.path.dirname(dirpath) + filename = os.path.basename(dirpath) + dirpath = os.path.dirname(dirpath) - if not os.path.exists(dirpath): - dirpath, found = _ncase_path_found(dirpath) + if not os.path.exists(dirpath): + dirpath, found = _ncase_path_found(dirpath) - if not found: - return path, False + if not found: + return path, False - # at this point, the directory exists but not the file + # at this point, the directory exists but not the file - # we are expecting 'dirpath' to be a directory, but it could be a file - if os.path.isdir(dirpath): - files = os.listdir(dirpath) - else: - return path, False + # we are expecting 'dirpath' to be a directory, but it could be a file + if os.path.isdir(dirpath): + files = os.listdir(dirpath) + else: + return path, False - filename_low = filename.lower() - f_iter_nocase = None + filename_low = filename.lower() + f_iter_nocase = None - for f_iter in files: - if f_iter.lower() == filename_low: - f_iter_nocase = f_iter - break + for f_iter in files: + if f_iter.lower() == filename_low: + f_iter_nocase = f_iter + break - if f_iter_nocase: - return os.path.join(dirpath, f_iter_nocase) + suffix, True - else: - # cant find the right one, just return the path as is. - return path, False + if f_iter_nocase: + return os.path.join(dirpath, f_iter_nocase) + suffix, True + else: + # cant find the right one, just return the path as is. + return path, False - ncase_path, found = _ncase_path_found(path) - return ncase_path if found else path + ncase_path, found = _ncase_path_found(path) + return ncase_path if found else path def ensure_ext(filepath, ext, case_sensitive=False): @@ -172,3 +194,37 @@ def ensure_ext(filepath, ext, case_sensitive=False): else: return filepath + ext + + +def module_names(path, recursive=False): + """ + Return a list of modules which can be imported from *path*. + + :arg path: a directory to scan. + :type path: string + :arg recursive: Also return submodule names for packages. + :type recursive: bool + :return: a list of string pairs (module_name, module_file). + :rtype: list + """ + + from os.path import join, isfile + + modules = [] + + for filename in sorted(_os.listdir(path)): + if filename == "modules": + pass # XXX, hard coded exception. + elif filename.endswith(".py") and filename != "__init__.py": + fullpath = join(path, filename) + modules.append((filename[0:-3], fullpath)) + elif ("." not in filename): + directory = join(path, filename) + fullpath = join(directory, "__init__.py") + if isfile(fullpath): + modules.append((filename, fullpath)) + if recursive: + for mod_name, mod_path in module_names(directory, True): + modules.append(("%s.%s" % (filename, mod_name), mod_path)) + + return modules |