1 """
2 A collection of filesystem related commands.
3 """
4 import os, re
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,
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 @return: a generator for the matched files
25 """
26 def maybe_regex(arg):
27 return re.compile(arg) if arg != None else None
28 c_name_regex = maybe_regex(name_regex)
29 c_not_name_regex = maybe_regex(not_name_regex)
30 c_whole_name_regex = maybe_regex(whole_name_regex)
31 c_not_whole_name_regex = maybe_regex(not_whole_name_regex)
32
33 def check_name(name, whole_name):
34 if c_name_regex != None and not c_name_regex.match( name ):
35 return False
36 if c_not_name_regex != None and c_not_name_regex.match( name ):
37 return False
38 if c_whole_name_regex != None and not c_whole_name_regex.match( whole_name ):
39 return False
40 if c_not_whole_name_regex != None and c_not_whole_name_regex.match( whole_name ):
41 return False
42 return True
43
44 def filter_func():
45
46 queue = [ ( 0, path ) ]
47
48 while len(queue) != 0:
49 depth, root = queue[0]
50 queue = queue[1:]
51
52 if root == path and exclude_root:
53 pass
54 elif include_dirs and check_name( os.path.basename(root), root ):
55 yield root
56
57 if limit_depth != None and depth > limit_depth:
58 continue
59
60 for item in os.listdir(root):
61 whole = os.path.join( root, item )
62
63 if os.path.isdir(whole):
64 queue.append( ( depth + 1, whole ) )
65 elif include_files and check_name( item, whole ):
66 yield whole
67
68 return filter_func()
69