source: trunk/python2/inspect.py @ 224

Last change on this file since 224 was 196, checked in by tim, 15 years ago

experimental python bindings generator as provided by Michael Cohen

File size: 8.1 KB
Line 
1#!/usr/bin/python
2""" Module to inspect the contents of an AFF4 volume """
3import sys, pdb, os
4import re, cmd, readline
5import optparse
6import pyaff4
7import shlex
8import fnmatch, time
9import subprocess
10import readline
11
12time.sleep(1)
13
14## Set more sane completer delimiters
15readline.set_completer_delims(' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?')
16
17## Configure colors
18colors = {}
19colors['cyan']   = '\033[96m'
20colors['purple'] = '\033[95m'
21colors['blue']   = '\033[94m'
22colors['green']  = '\033[92m'
23colors['yellow'] = '\033[93m'
24colors['red']    = '\033[91m'
25colors['end']    = '\033[0m'
26
27#If the output is not a terminal, remove the colors
28if not sys.stdout.isatty():
29   for key, value in colors.iteritems():
30      colors[key] = ''
31
32parser = optparse.OptionParser()
33(options, args) = parser.parse_args()
34
35## Load the specified args as volumes
36oracle = pyaff4.Resolver()
37VOLUMES = []
38STREAMS = {}
39
40for arg in args:
41    volume = pyaff4.RDFURN()
42    volume.set(arg)
43    if oracle.load(volume):
44        VOLUMES.append(volume)
45        urn = pyaff4.RDFURN()
46        iter = oracle.get_iter(volume, pyaff4.AFF4_CONTAINS)
47        while oracle.iter_next(iter, urn):
48           print urn.value
49           if not urn: break
50
51           ## We store is as a simplified path
52           path = "/%s%s" % (urn.parser.netloc, urn.parser.query)
53           STREAMS[path] = urn
54
55class Inspector(cmd.Cmd):
56    prompt = "/:>"
57    intro = "Inspecting the volumes %s. Type 'help' for help." % args
58    CWD = "/"
59
60    def cmdloop(self, *args):
61        while 1:
62            try:
63                if not cmd.Cmd.cmdloop(self, *args):
64                    break
65            except KeyboardInterrupt,e:
66                print "Type %sexit%s to exit, %shelp%s for help" % (
67                    colors['yellow'],
68                    colors['end'],
69                    colors['cyan'],
70                    colors['end'])
71
72    def do_EOF(self, args):
73        """ Exit this program """
74        print "%sGoodbye%s" % (colors['yellow'],
75                               colors['end'])
76        return True
77
78    def do_cd(self, line):
79        """ Change directory """
80        args = shlex.split(line)
81        if not args[0].startswith("/"):
82            args[0] = self.CWD + args[0]
83
84        try:
85            potential_cd = os.path.normpath(args[0])
86            if not potential_cd.endswith('/'):
87                potential_cd += "/"
88
89            for s in STREAMS:
90                if s.startswith(potential_cd):
91                    self.CWD = potential_cd
92                    self.prompt = "%s:>" % self.CWD
93                    return
94
95            raise IOError("No such directory %s" % potential_cd)
96        except IndexError:
97            print "CWD: %s" % self.CWD
98
99    def complete_cd(self, *args):
100        return self.complete_stream(*args)
101
102    def do_help(self, line):
103        """ Provide help for commands """
104        args = shlex.split(line)
105        if not args:
106            ## List all commands
107            for k in dir(self):
108                if k.startswith("do_"):
109                    method = getattr(self, k)
110                    print "%s%s%s: %s" % (colors['red'],
111                                          k[3:],
112                                          colors['end'],
113                                          method.__doc__)
114            return
115
116        for arg in args:
117            try:
118                method = getattr(self, "do_%s" % arg)
119            except AttributeError:
120                print "%sError:%s Command %s%s%s not found" % (colors['red'],
121                                                               colors['end'],
122                                                               colors['yellow'],
123                                                               arg,
124                                                               colors['end'])
125
126            print "%s: %s" % (arg, method.__doc__)
127
128    def do_ls(self, line):
129        """ List streams matching a glob expression """
130        globs = shlex.split(line)
131        if not globs: globs=[self.CWD]
132
133        result = []
134
135        for s in STREAMS:
136            for g in globs:
137                if fnmatch.fnmatch(s, g + "*"):
138                    if s.startswith(self.CWD):
139                        s = s[len(self.CWD):]
140
141                    path = s.split("/")[0]
142                    if path == s:
143                        decoration = colors['blue']
144                    else:
145                        decoration = colors['end']
146
147                    if path not in result:
148                        print "%s%s%s" % (decoration, path, colors['end'])
149                        result.append(path)
150
151    def do_less(self, line):
152        """ Read the streams specified and pipe them through the pager """
153        globs = shlex.split(line)
154        for s in STREAMS:
155            for g in globs:
156                if not g.startswith("/"):
157                    g = self.CWD + g
158
159                g = os.path.normpath(g)
160                if fnmatch.fnmatch(s, g):
161                    ## Try to open the stream
162                    try:
163                        fd = oracle.open(STREAMS[s], 'r')
164                    except IOError, e:
165                        raise
166
167                    pager = os.environ.get("PAGER","less")
168                    pipe=os.popen(pager,"w")
169
170                    while 1:
171                        data = fd.read(1024 * 1024)
172                        if not data: break
173
174                        pipe.write(data)
175
176                    pipe.close()
177
178    def do_cp(self, line):
179        """ Copy a stream from a source to a destination. """
180        globs = shlex.split(line)
181        src = globs[0]
182        dest = globs[1]
183        if(len(globs) > 2):
184           print "usage: cp src dest"
185           return
186
187        if not src.startswith("/"):
188           src = self.CWD + src
189
190        src = os.path.normpath(src)
191        src_urn = pyaff4.RDFURN()
192        src_urn.set("aff4:/" + src)
193        ## Try to open the stream
194        try:
195           fd = oracle.open(src_urn, 'r')
196        except IOError, e:
197           raise
198
199        dest_fd = open(dest, "w")
200        while 1:
201           data = fd.read(1024 * 1024)
202           if not data: break
203
204           dest_fd.write(data)
205
206        dest_fd.close()
207
208    def complete_cp(self, *args):
209       return self.complete_stream(*args)
210
211    def complete_less(self, *args):
212        return self.complete_stream(*args)
213
214    def _display_attribute(self, iter):
215       while 1:
216          obj = oracle.alloc_from_iter(iter)
217          if not obj: break
218
219          print "    -> type (%s) " % (obj.dataType)
220          print "    -> data (%s) " % (obj.serialise(iter.urn))
221
222
223    def do_resolve(self, line):
224       globs = shlex.split(line)
225       attribute = pyaff4.XSDString()
226       subject = pyaff4.RDFURN()
227       iter = pyaff4.RESOLVER_ITER()
228
229       subject.set(globs[0])
230       try:
231          attribute.set(globs[1])
232          print attribute.value
233          self._display_attribute(iter)
234
235       except IndexError:
236          ## Just display all the attributes
237          while oracle.attributes_iter(subject, attribute, iter):
238             print attribute.value
239             self._display_attribute(iter)
240
241    def complete_stream(self, text, line, begidx, endidx):
242        if not text.startswith("/"):
243            text = self.CWD + text
244
245        if not text:
246            completions = STREAMS.keys()
247
248        completions = [ text + f[len(text):].split("/")[0]
249                        for f in STREAMS.keys()
250                        if f.startswith(text)
251                        ]
252
253        return completions
254
255    def do_pwd(self, line):
256        print "CWD: %s" % self.CWD
257
258    def do_exit(self, *args):
259        """ Exits the program """
260        return self.do_EOF(*args)
261
262    def emptyline(self):
263        return
264
265    def onecmd(self, line):
266        try:
267            return cmd.Cmd.onecmd(self, line)
268        except Exception,e:
269            print "%sError:%s %s%s%s %s" % (colors['red'],
270                                            colors['end'],
271                                            colors['yellow'],
272                                            e.__class__.__name__,
273                                            colors['end'],
274                                            e)
275
276        return None
277
278Inspector().cmdloop()
Note: See TracBrowser for help on using the repository browser.