| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | # ##### BEGIN GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | #  modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | #  as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | #  of the License, or (at your option) any later version. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | #  GNU General Public License for more details. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | #  along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  | #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # ##### END GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  | # <pep8-80 compliant> | 
					
						
							| 
									
										
										
										
											2010-08-06 03:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | This module has a similar scope to os.path, containing utility | 
					
						
							|  |  |  | functions for dealing with paths in Blender. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  | __all__ = ( | 
					
						
							|  |  |  |     "abspath", | 
					
						
							|  |  |  |     "basename", | 
					
						
							|  |  |  |     "clean_name", | 
					
						
							|  |  |  |     "display_name", | 
					
						
							|  |  |  |     "display_name_from_filepath", | 
					
						
							|  |  |  |     "ensure_ext", | 
					
						
							| 
									
										
										
										
											2013-01-04 03:47:37 +00:00
										 |  |  |     "extensions_image", | 
					
						
							|  |  |  |     "extensions_movie", | 
					
						
							|  |  |  |     "extensions_audio", | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     "is_subdir", | 
					
						
							|  |  |  |     "module_names", | 
					
						
							|  |  |  |     "relpath", | 
					
						
							|  |  |  |     "resolve_ncase", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | import bpy as _bpy | 
					
						
							| 
									
										
										
										
											2010-08-06 13:06:13 +00:00
										 |  |  | import os as _os | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-04 03:47:37 +00:00
										 |  |  | from _bpy_path import (extensions_audio, | 
					
						
							|  |  |  |                        extensions_movie, | 
					
						
							|  |  |  |                        extensions_image, | 
					
						
							|  |  |  |                        ) | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-15 23:15:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  | def _getattr_bytes(var, attr): | 
					
						
							|  |  |  |     return var.path_resolve(attr, False).as_bytes() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-11 04:09:11 +00:00
										 |  |  | def abspath(path, start=None, library=None): | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     Returns the absolute path relative to the current blend file | 
					
						
							|  |  |  |     using the "//" prefix. | 
					
						
							| 
									
										
										
										
											2011-01-15 20:35:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     :arg start: Relative to this path, | 
					
						
							|  |  |  |        when not set the current filename is used. | 
					
						
							| 
									
										
										
										
											2011-01-15 20:35:31 +00:00
										 |  |  |     :type start: string | 
					
						
							| 
									
										
										
										
											2011-10-11 04:09:11 +00:00
										 |  |  |     :arg library: The library this path is from. This is only included for | 
					
						
							|  |  |  |        convenience, when the library is not None its path replaces *start*. | 
					
						
							|  |  |  |     :type library: :class:`bpy.types.Library` | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  |     if isinstance(path, bytes): | 
					
						
							|  |  |  |         if path.startswith(b"//"): | 
					
						
							|  |  |  |             if library: | 
					
						
							|  |  |  |                 start = _os.path.dirname(abspath(_getattr_bytes(library, "filepath"))) | 
					
						
							|  |  |  |             return _os.path.join(_os.path.dirname(_getattr_bytes(_bpy.data, "filepath")) | 
					
						
							|  |  |  |                                  if start is None else start, | 
					
						
							|  |  |  |                                  path[2:], | 
					
						
							|  |  |  |                                  ) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         if path.startswith("//"): | 
					
						
							|  |  |  |             if library: | 
					
						
							|  |  |  |                 start = _os.path.dirname(abspath(library.filepath)) | 
					
						
							|  |  |  |             return _os.path.join(_os.path.dirname(_bpy.data.filepath) | 
					
						
							|  |  |  |                                  if start is None else start, | 
					
						
							|  |  |  |                                  path[2:], | 
					
						
							|  |  |  |                                  ) | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def relpath(path, start=None): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Returns the path relative to the current blend file using the "//" prefix. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     :arg start: Relative to this path, | 
					
						
							|  |  |  |        when not set the current filename is used. | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |     :type start: string | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2013-04-05 00:30:32 +00:00
										 |  |  |     if isinstance(path, bytes): | 
					
						
							|  |  |  |         if not path.startswith(b"//"): | 
					
						
							|  |  |  |             if start is None: | 
					
						
							|  |  |  |                 start = _os.path.dirname(_getattr_bytes(_bpy.data, "filepath")) | 
					
						
							|  |  |  |             return b"//" + _os.path.relpath(path, start) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         if not path.startswith("//"): | 
					
						
							|  |  |  |             if start is None: | 
					
						
							|  |  |  |                 start = _os.path.dirname(_bpy.data.filepath) | 
					
						
							|  |  |  |             return "//" + _os.path.relpath(path, start) | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 05:19:40 +00:00
										 |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | def clean_name(name, replace="_"): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     Returns a name with characters replaced that | 
					
						
							|  |  |  |        may cause problems under various circumstances, | 
					
						
							|  |  |  |     such as writing to a file. | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |     All characters besides A-Z/a-z, 0-9 are replaced with "_" | 
					
						
							|  |  |  |     or the replace argument if defined. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     bad_chars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e" | 
					
						
							|  |  |  |                  "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d" | 
					
						
							|  |  |  |                  "\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c" | 
					
						
							|  |  |  |                  "\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b" | 
					
						
							|  |  |  |                  "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a" | 
					
						
							|  |  |  |                  "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99" | 
					
						
							|  |  |  |                  "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8" | 
					
						
							|  |  |  |                  "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7" | 
					
						
							|  |  |  |                  "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6" | 
					
						
							|  |  |  |                  "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5" | 
					
						
							|  |  |  |                  "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4" | 
					
						
							|  |  |  |                  "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3" | 
					
						
							|  |  |  |                  "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for ch in bad_chars: | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |         name = name.replace(ch, replace) | 
					
						
							|  |  |  |     return name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 22:29:49 +00:00
										 |  |  | def _clean_utf8(name): | 
					
						
							|  |  |  |     name = _os.path.splitext(basename(name))[0] | 
					
						
							|  |  |  |     if type(name) == bytes: | 
					
						
							|  |  |  |         return name.decode("utf8", "replace") | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return name.encode("utf8", "replace").decode("utf8") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | def display_name(name): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Creates a display string from name to be used menus and the user interface. | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     Capitalize the first letter in all lowercase names, | 
					
						
							|  |  |  |     mixed case names are kept as is. Intended for use with | 
					
						
							|  |  |  |     filenames and module names. | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     # string replacements | 
					
						
							| 
									
										
										
										
											2012-03-21 22:29:49 +00:00
										 |  |  |     name = name.replace("_colon_", ":") | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 22:29:49 +00:00
										 |  |  |     name = name.replace("_", " ") | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-21 22:29:49 +00:00
										 |  |  |     if name.islower(): | 
					
						
							|  |  |  |         name = name.lower().title() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     name = _clean_utf8(name) | 
					
						
							|  |  |  |     return name | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-03 08:28:22 +00:00
										 |  |  | def display_name_from_filepath(name): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-08-02 17:00:44 +00:00
										 |  |  |     Returns the path stripped of directory and extension, | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |     ensured to be utf8 compatible. | 
					
						
							| 
									
										
										
										
											2011-01-03 08:28:22 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2012-03-21 22:29:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     name = _clean_utf8(name) | 
					
						
							|  |  |  |     return name | 
					
						
							| 
									
										
										
										
											2011-01-03 08:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | def resolve_ncase(path): | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Resolve a case insensitive path on a case sensitive system, | 
					
						
							|  |  |  |     returning a string with the path if found else return the original path. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |     def _ncase_path_found(path): | 
					
						
							| 
									
										
										
										
											2011-11-16 16:38:37 +00:00
										 |  |  |         if not path or _os.path.exists(path): | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |             return path, True | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |         # filename may be a directory or a file | 
					
						
							| 
									
										
										
										
											2011-11-16 16:38:37 +00:00
										 |  |  |         filename = _os.path.basename(path) | 
					
						
							|  |  |  |         dirpath = _os.path.dirname(path) | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 06:27:39 +00:00
										 |  |  |         suffix = path[:0]  # "" but ensure byte/str match | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         if not filename:  # dir ends with a slash? | 
					
						
							|  |  |  |             if len(dirpath) < len(path): | 
					
						
							|  |  |  |                 suffix = path[:len(path) - len(dirpath)] | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-16 16:38:37 +00:00
										 |  |  |             filename = _os.path.basename(dirpath) | 
					
						
							|  |  |  |             dirpath = _os.path.dirname(dirpath) | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-16 16:38:37 +00:00
										 |  |  |         if not _os.path.exists(dirpath): | 
					
						
							| 
									
										
										
										
											2011-05-06 11:27:04 +00:00
										 |  |  |             if dirpath == path: | 
					
						
							|  |  |  |                 return path, False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |             dirpath, found = _ncase_path_found(dirpath) | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |             if not found: | 
					
						
							|  |  |  |                 return path, False | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         # at this point, the directory exists but not the file | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         # we are expecting 'dirpath' to be a directory, but it could be a file | 
					
						
							| 
									
										
										
										
											2011-11-16 16:38:37 +00:00
										 |  |  |         if _os.path.isdir(dirpath): | 
					
						
							|  |  |  |             files = _os.listdir(dirpath) | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             return path, False | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         filename_low = filename.lower() | 
					
						
							|  |  |  |         f_iter_nocase = None | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         for f_iter in files: | 
					
						
							|  |  |  |             if f_iter.lower() == filename_low: | 
					
						
							|  |  |  |                 f_iter_nocase = f_iter | 
					
						
							|  |  |  |                 break | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         if f_iter_nocase: | 
					
						
							| 
									
										
										
										
											2011-11-16 16:38:37 +00:00
										 |  |  |             return _os.path.join(dirpath, f_iter_nocase) + suffix, True | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             # cant find the right one, just return the path as is. | 
					
						
							|  |  |  |             return path, False | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |     ncase_path, found = _ncase_path_found(path) | 
					
						
							|  |  |  |     return ncase_path if found else path | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ensure_ext(filepath, ext, case_sensitive=False): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-08-02 17:00:44 +00:00
										 |  |  |     Return the path with the extension added if it is not already set. | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     :arg ext: The extension to check for. | 
					
						
							|  |  |  |     :type ext: string | 
					
						
							|  |  |  |     :arg case_sensitive: Check for matching case when comparing extensions. | 
					
						
							|  |  |  |     :type case_sensitive: bool | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-11-16 16:38:37 +00:00
										 |  |  |     fn_base, fn_ext = _os.path.splitext(filepath) | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |     if fn_base and fn_ext: | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |         if ((case_sensitive and ext == fn_ext) or | 
					
						
							|  |  |  |             (ext.lower() == fn_ext.lower())): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-06 01:40:54 +00:00
										 |  |  |             return filepath | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return fn_base + ext | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return filepath + ext | 
					
						
							| 
									
										
										
										
											2010-09-08 04:55:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2010-09-08 07:30:20 +00:00
										 |  |  |     :return: a list of string pairs (module_name, module_file). | 
					
						
							| 
									
										
										
										
											2010-09-08 04:55:37 +00:00
										 |  |  |     :rtype: list | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from os.path import join, isfile | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     modules = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for filename in sorted(_os.listdir(path)): | 
					
						
							| 
									
										
										
										
											2010-12-11 11:52:28 +00:00
										 |  |  |         if filename == "modules": | 
					
						
							| 
									
										
										
										
											2011-01-01 07:20:34 +00:00
										 |  |  |             pass  # XXX, hard coded exception. | 
					
						
							| 
									
										
										
										
											2010-12-11 11:52:28 +00:00
										 |  |  |         elif filename.endswith(".py") and filename != "__init__.py": | 
					
						
							| 
									
										
										
										
											2010-09-08 07:30:20 +00:00
										 |  |  |             fullpath = join(path, filename) | 
					
						
							|  |  |  |             modules.append((filename[0:-3], fullpath)) | 
					
						
							| 
									
										
										
										
											2012-08-17 18:36:20 +00:00
										 |  |  |         elif "." not in filename: | 
					
						
							| 
									
										
										
										
											2010-09-08 04:55:37 +00:00
										 |  |  |             directory = join(path, filename) | 
					
						
							| 
									
										
										
										
											2010-09-08 07:30:20 +00:00
										 |  |  |             fullpath = join(directory, "__init__.py") | 
					
						
							|  |  |  |             if isfile(fullpath): | 
					
						
							|  |  |  |                 modules.append((filename, fullpath)) | 
					
						
							| 
									
										
										
										
											2010-09-08 04:55:37 +00:00
										 |  |  |                 if recursive: | 
					
						
							| 
									
										
										
										
											2010-09-08 07:30:20 +00:00
										 |  |  |                     for mod_name, mod_path in module_names(directory, True): | 
					
						
							| 
									
										
										
										
											2011-07-31 03:15:37 +00:00
										 |  |  |                         modules.append(("%s.%s" % (filename, mod_name), | 
					
						
							| 
									
										
										
										
											2012-10-08 08:28:05 +00:00
										 |  |  |                                         mod_path, | 
					
						
							|  |  |  |                                         )) | 
					
						
							| 
									
										
										
										
											2010-09-08 04:55:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return modules | 
					
						
							| 
									
										
										
										
											2011-07-20 08:10:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def basename(path): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-10-11 04:36:27 +00:00
										 |  |  |     Equivalent to os.path.basename, but skips a "//" prefix. | 
					
						
							| 
									
										
										
										
											2011-07-20 08:10:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Use for Windows compatibility. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-07-25 04:00:11 +00:00
										 |  |  |     return _os.path.basename(path[2:] if path[:2] in {"//", b"//"} else path) |