Package shelljob :: Module fs
[hide private]
[frames] | no frames]

Source Code for Module shelljob.fs

  1  """ 
  2          A collection of filesystem related commands. 
  3  """ 
  4  import os, re, tempfile 
  5   
6 -def find( path, 7 include_dirs = True, include_files = True, 8 name_regex = None, not_name_regex = None, 9 whole_name_regex = None, not_whole_name_regex = None, 10 exclude_root = False, relative = False, 11 limit_depth = None ):
12 """ 13 Creates an iterator of files matching a variety of conditions. 14 15 @param path: which path to iterate 16 @param include_dirs: include directories in output 17 @param include_files: include files in output 18 @param name_regex: optional regex string compared against basename of file 19 @param not_name_regex: if specificed only produces names not matching this regex 20 @param whole_name_regex: like name_regex but applies to whole path, not just basename 21 @param not_whole_name_regex: like not_name_regex but applies to whole path 22 @param exclude_root: do not include the intput 'path' itself in the output 23 @param limit_depth: do not list items deeper than this level from root 24 @param relative: filenames are relative to "path" as opposed to appended to path 25 @return: a generator for the matched files 26 """ 27 def maybe_regex(arg): 28 return re.compile(arg) if arg != None else None
29 c_name_regex = maybe_regex(name_regex) 30 c_not_name_regex = maybe_regex(not_name_regex) 31 c_whole_name_regex = maybe_regex(whole_name_regex) 32 c_not_whole_name_regex = maybe_regex(not_whole_name_regex) 33 34 def check_name(name, whole_name): 35 if c_name_regex != None and not c_name_regex.match( name ): 36 return False 37 if c_not_name_regex != None and c_not_name_regex.match( name ): 38 return False 39 if c_whole_name_regex != None and not c_whole_name_regex.match( whole_name ): 40 return False 41 if c_not_whole_name_regex != None and c_not_whole_name_regex.match( whole_name ): 42 return False 43 return True 44 45 def result( whole, rel ): 46 if relative: 47 return rel 48 else: 49 return whole 50 51 def filter_func(): 52 # A list of paths still to be processed (depth, whole_path, relative_path) 53 queue = [ ( 0, path, '' ) ] 54 55 while len(queue) != 0: 56 depth, root, rel_path = queue[0] 57 queue = queue[1:] 58 59 if root == path and exclude_root: 60 pass 61 elif include_dirs and check_name( os.path.basename(root), root ): 62 yield result( root, rel_path ) 63 64 if limit_depth != None and depth > limit_depth: 65 continue 66 67 for item in os.listdir(root): 68 whole = os.path.join( root, item ) 69 rel = os.path.join( rel_path, item ) 70 71 if os.path.isdir(whole): 72 queue.append( ( depth + 1, whole, rel ) ) 73 elif include_files and check_name( item, whole ): 74 yield result( whole, rel ) 75 76 return filter_func() 77
78 -class NamedTempFile:
79 """ 80 Creates a temporary file for a 'with' block. The file is deleted when the block exits. 81 This creates the file to ensure it exists/block a race, but does not write anything to 82 it, nor does it keep it open. It is intended for times when you need a named file 83 for subprocesses. 84 85 Example:: 86 87 with fs.NamedTempFile() as nm: 88 proc.call( "curl http://mortoray.com/ -o {}".format( nm ) ) 89 html = open(nm).read() 90 print( len(html) ) 91 92 """ 93
94 - def __init__(self, suffix = None, prefix = None, dir = None ):
95 """ 96 @param suffix: optional suffix for generated filename (a dot '.' is not automatically added, 97 specifiy it if desired) 98 @param prefix: optional prefix for generated filename 99 @param dir: in which directory, if None then use a system default 100 """ 101 self.args = { 102 'text': False, 103 } 104 if suffix != None: 105 self.args['suffix'] = suffix 106 if prefix != None: 107 self.args['prefix'] = prefix 108 if dir != None: 109 self.args['dir'] = dir
110
111 - def __enter__(self):
112 (handle, name) = tempfile.mkstemp( **self.args ) 113 os.close(handle) 114 self.name = name 115 return name
116
117 - def __exit__(self, type, value, traceback):
118 os.remove(self.name)
119