File: gfal2_recursive_ls.py

package info (click to toggle)
gfal2-bindings 1.13.0-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 688 kB
  • sloc: cpp: 2,574; python: 1,050; sh: 109; makefile: 92
file content (104 lines) | stat: -rwxr-xr-x 3,154 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python
import gfal2
import optparse
import stat
import sys
from datetime import datetime


class Crawler:

    def __init__(self, long=False, recursive=False,
                 max_levels=2, context=gfal2.creat_context()):
        self.context = context
        self.long = long
        self.recursive = recursive
        self.max_levels = max_levels

    def _short_format(self, fname):
        return fname

    def _mode2str(self, mode):
        s = ['-'] * 10
        if stat.S_ISDIR(mode):
            s[0] = 'd'
        elif stat.S_ISLNK(mode):
            s[0] = 'l'
        elif not stat.S_ISREG(mode):
            s[0] = '?'

        for i in range(3):
            if mode & stat.S_IRUSR:
                s[1 + i * 3] = 'r'
            if mode & stat.S_IWUSR:
                s[2 + i * 3] = 'w'
            if mode & stat.S_IXUSR:
                s[3 + i * 3] = 'x'
            mode = mode << 3
        return ''.join(s)

    def _long_format(self, fname, fstat):
        return "%s %3d %5d %5d %10d %s %s" % \
            (self._mode2str(fstat.st_mode),
             fstat.st_nlink, fstat.st_uid, fstat.st_gid,
             fstat.st_size,
             datetime.fromtimestamp(fstat.st_mtime).strftime('%b %d %H:%M'),
             fname)

    def _crawl(self, url, out, level=0):
        if level > self.max_levels:
            return

        tabbing = '  ' * level
        try:
            entries = [f for f in self.context.listdir(url)
                       if f != '.' and f != '..']
        except gfal2.GError:
            out.write(tabbing, '!')
            return

        for f in entries:
            full = url + '/' + f
            # Do the stat only if we need to
            if self.recursive or self.long:
                try:
                    fstat = self.context.stat(full)
                except gfal2.GError:
                    fstat = self.context.st_stat()

            # Print entry
            if self.long:
                out.write(tabbing, self._long_format(f, fstat))
            else:
                out.write(tabbing, self._short_format(f))

            # Descend
            if self.recursive and stat.S_ISDIR(fstat.st_mode):
                self._crawl(full, out, level + 1)

    def crawl(self, url, out=sys.stdout):
        self._crawl(url, out)


if __name__ == '__main__':
    # Get the options
    parser = optparse.OptionParser()
    parser.add_option('-l', '--long', dest='long',
                      default=False, action='store_true',
                      help='Long format')
    parser.add_option('-r', '--recursive', dest='recursive',
                      default=False, action='store_true',
                      help='Recursive')
    parser.add_option('-m', '--max', dest='max_recursive',
                      default=1, type='int',
                      help='Maximum recursive level')

    (options, args) = parser.parse_args()
    if  len(args) != 1:
        parser.error('Incorrect number of arguments. Need a path')

    url = args[0]

    # List recursively
    crawler = Crawler(options.long, options.recursive, options.max_recursive)
    crawler.crawl(url, sys.stdout)