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
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
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
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):
119