root/livinglogic.python.xist/src/ll/scripts/uls.py @ 3745:18a330745351

Revision 3745:18a330745351, 5.0 KB (checked in by Walter Doerwald <walter@…>, 11 years ago)

Activate oracle URLs for uls. Use absolute URLs for testing the type.

Line 
1#!/usr/local/bin/python
2# -*- coding: utf-8 -*-
3
4
5## Copyright 2009 by LivingLogic AG, Bayreuth/Germany.
6## Copyright 2009 by Walter Dörwald
7##
8## All Rights Reserved
9##
10## See ll/__init__.py for the license
11
12
13from __future__ import with_statement
14
15import sys, optparse, contextlib, datetime, pwd, grp, stat, curses
16
17from ll import url
18
19try:
20    import astyle
21except ImportError:
22    from ll import astyle
23
24try:
25    from ll import orasql # Activate oracle URLs
26except ImportError:
27    pass
28
29
30style_pad = astyle.Style.fromstr("black:black:bold")
31style_sizeunit = astyle.Style.fromstr("yellow:black")
32
33
34def rpad(s, l):
35    meas = str(s)
36    if not isinstance(s, (basestring, astyle.Text)):
37        s = str(s)
38    if len(meas) < l:
39        return astyle.style_default(s, style_pad("."*(l-len(meas))))
40    return s
41
42
43def lpad(s, l):
44    meas = str(s)
45    if not isinstance(s, (basestring, astyle.Text)):
46        s = str(s)
47    if len(meas) < l:
48        return astyle.style_default(style_pad("."*(l-len(meas))), s)
49    return s
50
51
52def findcolcount(urls, width, spacing):
53    def width4cols(numcols, spacing):
54        cols = [0]*numcols
55        rows = (len(urls)+numcols-1)//numcols
56        for (i, (u, su)) in enumerate(urls):
57            cols[i//rows] = max(cols[i//rows], len(su))
58        return (sum(cols) + (numcols-1)*spacing, rows, cols)
59
60    numcols = len(urls)
61    while True:
62        (s, rows, cols) = width4cols(numcols, spacing)
63        if s <= width or numcols == 1:
64            return (rows, cols)
65        numcols -=1
66
67
68def main(args=None):
69    uids = {}
70    gids = {}
71    modedata = (
72        (stat.S_IRUSR, "-r"),
73        (stat.S_IWUSR, "-w"),
74        (stat.S_IXUSR, "-x"),
75        (stat.S_IRGRP, "-r"),
76        (stat.S_IWGRP, "-w"),
77        (stat.S_IXGRP, "-x"),
78        (stat.S_IROTH, "-r"),
79        (stat.S_IWOTH, "-w"),
80        (stat.S_IXOTH, "-x"),
81    )
82    sep = style_pad("|")
83    curses.setupterm()
84    width = curses.tigetnum('cols')
85    def printone(url, long, human):
86        if long:
87            stat = url.stat()
88            if stat.st_uid not in uids:
89                user = uids[stat.st_uid] = pwd.getpwuid(stat.st_uid)[0]
90            else:
91                user = uids[stat.st_uid]
92            if stat.st_gid not in gids:
93                group = gids[stat.st_gid] = grp.getgrgid(stat.st_gid)[0]
94            else:
95                group = gids[stat.st_gid]
96            mtime = datetime.datetime.fromtimestamp(stat.st_mtime).strftime("%Y-%m-%d %H:%M:%S")
97            mode = "".join([text[bool(stat.st_mode&bit)] for (bit, text) in modedata])
98            size = stat.st_size
99            if human:
100                s = "BKMGTP"
101                for c in s:
102                    if size < 2048:
103                        if c == "B":
104                            size = str(int(size))
105                        else:
106                            size = astyle.style_default(str(int(size)), style_sizeunit(c))
107                        break
108                    size /= 1024.
109            stdout.write(mode, sep, rpad(user, 8), sep, rpad(group, 8), sep, lpad(size, 5 if human else 12), sep, lpad(stat.st_nlink, 3), sep, mtime, sep)
110        if url.isdir():
111            stdout.writeln(astyle.style_dir(str(url)))
112        else:
113            stdout.writeln(astyle.style_file(str(url)))
114
115    def printblock(urls, width, spacing):
116        (rows, cols) = findcolcount(urls, width, spacing)
117        for i in xrange(rows):
118            for (j, w) in enumerate(cols):
119                index = i+j*rows
120                try:
121                    (u, su) = urls[index]
122                except IndexError:
123                    pass
124                else:
125                    if u.isdir():
126                        su = astyle.style_dir(su)
127                    else:
128                        su = astyle.style_file(su)
129                    if index + rows < len(urls):
130                        su = rpad(su, w+spacing)
131                    stdout.write(su)
132            stdout.writeln()
133
134    def printall(base, url, one, long, recursive, human, spacing):
135        if url.isdir():
136            if url.path.segments[-1][0]:
137                url.path.segments.append(("",))
138            if not long and not one:
139                urls = []
140                for child in url.listdir():
141                    u = url/child
142                    urls.append((u, str(u.relative(base))))
143                if urls:
144                    printblock(urls, width, spacing)
145                    if recursive:
146                        for child in url.dirs():
147                            printall(base, url/child, one, long, recursive, human, spacing)
148            else:
149                for child in url.listdir():
150                    printone(url/child, long, human)
151                    if recursive:
152                        printall(base, url/child, one, long, recursive, human, spacing)
153        else:
154            printone(url, long, human)
155
156    colors = ("yes", "no", "auto")
157    p = optparse.OptionParser(usage="usage: %prog [options] [url] [url] ...")
158    p.add_option("-c", "--color", dest="color", help="Color output (%s)" % ", ".join(colors), default="auto", choices=colors)
159    p.add_option("-1", "--one", dest="one", help="One entry per line?", action="store_true")
160    p.add_option("-l", "--long", dest="long", help="Long format?", action="store_true")
161    p.add_option("-s", "--human-readable-sizes", dest="human", help="Output human readable sizes?", action="store_true")
162    p.add_option("-r", "--recursive", dest="recursive", help="Recursive listing?", action="store_true")
163    p.add_option("-w", "--spacing", dest="spacing", help="Spacing between columns", type="int", default=3)
164   
165    (options, args) = p.parse_args(args)
166
167    if options.color == "yes":
168        color = True
169    elif options.color == "no":
170        color = False
171    else:
172        color = None
173    stdout = astyle.Stream(sys.stdout, color)
174    stderr = astyle.Stream(sys.stderr, color)
175
176    if not args:
177        args = ["."]
178
179    with url.Context():
180        for u in args:
181            u = url.URL(u)
182            printall(u, u, options.one, options.long, options.recursive, options.human, options.spacing)
183
184
185if __name__ == "__main__":
186    sys.exit(main())
Note: See TracBrowser for help on using the browser.