Package grizzled :: Package file
[hide private]
[frames] | no frames]

Source Code for Package grizzled.file

  1  """ 
  2  This module contains file- and path-related methods, classes, and modules. 
  3  """ 
  4   
  5  from __future__ import with_statement, absolute_import 
  6   
  7  __docformat__ = "restructuredtext en" 
  8   
  9  # --------------------------------------------------------------------------- 
 10  # Imports 
 11  # --------------------------------------------------------------------------- 
 12   
 13  import os as _os 
 14  import sys 
 15  import shutil 
 16   
 17  # --------------------------------------------------------------------------- 
 18  # Exports 
 19  # --------------------------------------------------------------------------- 
 20   
 21  __all__ = ['unlink_quietly', 'recursively_remove', 'copy_recursively', 
 22             'copy', 'touch', 'pathsplit', 'eglob', 'universal_path', 
 23             'native_path'] 
 24   
 25  # --------------------------------------------------------------------------- 
 26  # Functions 
 27  # --------------------------------------------------------------------------- 
 28   
 47   
 48      for path in looper(*paths): 
 49          try: 
 50              _os.unlink(path) 
 51          except: 
 52              pass 
 53   
54 -def recursively_remove(dir):
55 """ 56 Recursively remove all files and directories below and including a 57 specified directory. 58 59 :Parameters: 60 dir : str 61 path to directory to remove 62 """ 63 if not _os.path.exists(dir): 64 return 65 66 shutil.rmtree(dir)
67
68 -def list_recursively(dir):
69 """ 70 Recursively list the contents of a directory. Yields the contents of 71 the directory and all subdirectories. This method returns a generator, 72 so it evaluates its recursive walk lazily. 73 74 :Parameters: 75 dir : str 76 Path to directory to list 77 78 :raise ValueError: If ``dir`` does not exist, or if ``dir`` exists 79 but is not a directory. 80 """ 81 if not _os.path.isdir(dir): 82 raise ValueError, "%s is not a directory." % dir 83 84 for f in _os.listdir(dir): 85 if _os.path.isdir(f): 86 list_recursively(f) 87 else: 88 yield f
89
90 -def copy_recursively(source_dir, target_dir):
91 """ 92 Recursively copy a source directory (and all its contents) to a target 93 directory. 94 95 :Parameters: 96 source_dir : str 97 Source directory to copy recursively. This path must 98 exist and must specify a directory; otherwise, this 99 function throws a ``ValueError`` 100 101 target_dir : str 102 Directory to which to copy the contents of ``source_dir``. 103 This directory must not already exist. 104 105 :raise ValueError: If: ``source_dir`` does not exist; ``source_dir`` exists 106 but is not a directory; or ``target_dir`` exists but is 107 not a directory. 108 """ 109 shutil.copytree(source_dir, target_dir)
110
111 -def copy(files, target_dir, create_target=False):
112 """ 113 Copy one or more files to a target directory. 114 115 :Parameters: 116 files : str or list 117 single file path or a list of file paths to be copied 118 119 target_dir : str 120 path to target directory 121 122 create_target : bool 123 If ``True``, ``copy()`` will attempt to create the target directory 124 if it does not exist. If ``False``, ``copy()`` will throw an 125 exception if the target directory does not exist. 126 127 :raise OSError: ``target_dir`` does not exist, and ``create_target`` is 128 ``False`` 129 """ 130 if type(files) == str: 131 files = [files] 132 133 if not _os.path.exists(target_dir): 134 if create_target: 135 _os.mkdir(target_dir) 136 137 if _os.path.exists(target_dir) and (not _os.path.isdir(target_dir)): 138 raise OSError, 'Cannot copy files to non-directory "%s"' % target_dir 139 140 for f in files: 141 targetFile = _os.path.join(target_dir, _os.path.basename(f)) 142 open(targetFile, 'wb').write(open(f, 'rb').read())
143
144 -def touch(files, times=None):
145 """ 146 Similar to the Unix *touch* command, this function: 147 148 - updates the access and modification times for any existing files 149 in a list of files 150 - creates any non-existent files in the list of files 151 152 If any file in the list is a directory, this function will throw an 153 exception. 154 155 :Parameters: 156 files : list or str 157 pathname or list of pathnames of files to be created or updated 158 159 times : tuple 160 tuple of the form (*atime*, *mtime*), identical to 161 what is passed to the standard ``os.utime()`` function. 162 If this tuple is ``None``, then the current time is used. 163 """ 164 if type(files) == str: 165 files = [files] 166 167 for f in files: 168 if _os.path.exists(f): 169 if not _os.path.isfile(f): 170 raise OSError, "Can't touch non-file \"%s\"" % f 171 _os.utime(f, times) 172 173 else: 174 # Doesn't exist. Create it. 175 open(f, 'wb').close()
176 177
178 -def pathsplit(path):
179 """ 180 Split a path into an array of path components, using the file separator 181 ('/' on POSIX systems, '\' on Windows) that's appropriate for the 182 underlying operating system. Does not take drive letters into account. 183 If there's a Windows drive letter in the path, it'll end up with the 184 first component. 185 186 :Parameters: 187 path : str 188 path to split. Can be relative or absolute 189 190 :rtype: list 191 :return: a list of path components 192 """ 193 result = [] 194 (head, tail) = _os.path.split(path) 195 196 if (not head) or (head == path): 197 # No file separator. Done. 198 pass 199 200 else: 201 result = pathsplit(head) 202 203 if tail: 204 result += [tail] 205 206 return result
207
208 -def __find_matches(pattern_pieces, directory):
209 """ 210 Used by eglob. 211 """ 212 import glob 213 214 result = [] 215 if not _os.path.isdir(directory): 216 return [] 217 218 piece = pattern_pieces[0] 219 last = len(pattern_pieces) == 1 220 if piece == '**': 221 if not last: 222 remaining_pieces = pattern_pieces[1:] 223 224 for root, dirs, files in _os.walk(directory): 225 if last: 226 # At the end of a pattern, "**" just recursively matches 227 # directories. 228 result += [root] 229 else: 230 # Recurse downward, trying to match the rest of the 231 # pattern. 232 sub_result = __find_matches(remaining_pieces, root) 233 for partial_path in sub_result: 234 result += [partial_path] 235 236 else: 237 # Regular glob pattern. 238 239 matches = glob.glob(_os.path.join(directory, piece)) 240 if len(matches) > 0: 241 if last: 242 for match in matches: 243 result += [match] 244 else: 245 remaining_pieces = pattern_pieces[1:] 246 for match in matches: 247 sub_result = __find_matches(remaining_pieces, match) 248 for partial_path in sub_result: 249 result += [partial_path] 250 251 # Normalize the paths. 252 253 for i in range(len(result)): 254 result[i] = _os.path.normpath(result[i]) 255 256 return result
257
258 -def eglob(pattern, directory='.'):
259 """ 260 Extended glob function that supports the all the wildcards supported 261 by the Python standard ``glob`` routine, as well as a special "**" 262 wildcard that recursively matches any directory. Examples: 263 264 +--------------+--------------------------------------------------------+ 265 | \*\*/\*.py | all files ending in '.py' under the current directory | 266 +--------------+--------------------------------------------------------+ 267 | foo/\*\*/bar | all files name 'bar' anywhere under subdirectory 'foo' | 268 +--------------+--------------------------------------------------------+ 269 270 :Parameters: 271 pattern : str 272 The wildcard pattern. Must be a simple pattern with no directories. 273 274 directory : str 275 The directory in which to do the globbing. 276 277 :rtype: list 278 :return: A list of matched files, or an empty list for no match 279 """ 280 pieces = pathsplit(pattern) 281 return __find_matches(pieces, directory)
282
283 -def universal_path(path):
284 """ 285 Converts a path name from its operating system-specific format to a 286 universal path notation. Universal path notation always uses a Unix-style 287 "/" to separate path elements. A universal path can be converted to a 288 native (operating system-specific) path via the ``native_path()`` 289 function. Note that on POSIX-compliant systems, this function simply 290 returns the ``path`` parameter unmodified. 291 292 :Parameters: 293 path : str 294 the path to convert to universal path notation 295 296 :rtype: str 297 :return: the universal path. 298 """ 299 if _os.name != 'posix': 300 path = path.replace(_os.path.sep, '/') 301 302 return path
303
304 -def native_path(path):
305 """ 306 Converts a path name from universal path notation to the operating 307 system-specific format. Universal path notation always uses a Unix-style 308 "/" to separate path elements. A native path can be converted to a 309 universal path via the ``universal_path()`` function. Note that on 310 POSIX-compliant systems, this function simply returns the ``path`` 311 parameter unmodified. 312 313 :Parameters: 314 path : str 315 the path to convert to native path notation 316 317 :rtype: str 318 :return: the native path. 319 """ 320 if _os.name != 'posix': 321 path = path.replace('/', _os.path.sep) 322 323 return path
324