Mercurial > hg > config
annotate python/tree2.py @ 387:0aee0da6b06b
even more success
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Fri, 26 Jul 2013 16:20:22 -0700 |
parents | bea5f2fe4ea4 |
children | 3678770e8c52 |
rev | line source |
---|---|
382 | 1 #!/usr/bin/env python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 tree in python | |
6 """ | |
7 | |
8 import optparse | |
9 import os | |
10 import sys | |
11 | |
387 | 12 # ASCII delimeters |
13 VERTICAL_LINE = '|' | |
385 | 14 ITEM = '+' |
15 END = '\\' | |
387 | 16 |
17 # unicode delimiters | |
18 VERTICAL_LINE = '│' | |
385 | 19 ITEM = '├' |
20 END = '└' | |
382 | 21 |
22 def depth(directory): | |
387 | 23 """returns the integer depth of a directory or path relative to '/' """ |
24 | |
382 | 25 directory = os.path.abspath(directory) |
26 level = 0 | |
27 while True: | |
28 directory, remainder = os.path.split(directory) | |
29 level += 1 | |
30 if not remainder: | |
31 break | |
32 return level | |
33 | |
386 | 34 def tree(directory, sort_key=lambda x: x.lower()): |
383
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
35 |
385 | 36 retval = [] |
383
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
37 indent = [] |
384 | 38 last = {} |
386 | 39 top = depth(directory) |
40 | |
382 | 41 for dirpath, dirnames, filenames in os.walk(directory, topdown=True): |
383
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
42 |
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
43 abspath = os.path.abspath(dirpath) |
384 | 44 basename = os.path.basename(abspath) |
45 parent = os.path.dirname(abspath) | |
383
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
46 level = depth(abspath) - top |
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
47 |
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
48 # sort articles of interest |
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
49 for resource in (dirnames, filenames): |
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
50 resource[:] = sorted(resource, key=sort_key) |
382 | 51 |
385 | 52 files_end = ITEM |
53 dirpath_marker = ITEM | |
54 | |
55 if level > len(indent): | |
387 | 56 indent.append(VERTICAL_LINE) |
385 | 57 indent = indent[:level] |
58 | |
383
8d1ad56761b0
this still, somehow, eludes my tired brain
Jeff Hammel <jhammel@mozilla.com>
parents:
382
diff
changeset
|
59 if dirnames: |
385 | 60 files_end = ITEM |
61 last[abspath] = dirnames[-1] | |
62 else: | |
63 files_end = END | |
384 | 64 |
385 | 65 if last.get(parent) == os.path.basename(abspath): |
66 # last directory of parent | |
67 dirpath_mark = END | |
68 indent[-1] = ' ' | |
69 elif not indent: | |
70 dirpath_mark = '' | |
71 else: | |
72 dirpath_mark = ITEM | |
73 | |
74 retval.append('%s%s%s'% (''.join(indent[:-1]), dirpath_mark, basename)) | |
75 if filenames: | |
76 last_file = filenames[-1] | |
387 | 77 retval.extend([('%s%s%s' % (''.join(indent), |
385 | 78 files_end if filename == last_file else ITEM, |
79 filename)) | |
80 for index, filename in enumerate(filenames)]) | |
81 | |
382 | 82 return '\n'.join(retval) |
83 | |
84 def main(args=sys.argv[1:]): | |
85 | |
86 usage = '%prog [options]' | |
87 parser = optparse.OptionParser(usage=usage, description=__doc__) | |
88 options, args = parser.parse_args(args) | |
89 if not args: | |
90 args = ['.'] | |
91 | |
92 not_directory = [arg for arg in args | |
93 if not os.path.isdir(arg)] | |
94 if not_directory: | |
95 parser.error("Not a directory: %s" % (', '.join(not_directory))) | |
96 | |
97 for arg in args: | |
98 print (tree(arg)) | |
99 | |
100 if __name__ == '__main__': | |
101 main() |