]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/tahoe_manifest.py
8428cfcefbfa8722ab8c34dc8e30c72d8965abf8
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / tahoe_manifest.py
1
2 import os, time
3 from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
4 from allmydata.scripts.common_http import do_http
5 from allmydata.util import base32
6 from allmydata import uri
7 import urllib
8 import simplejson
9
10 class ManifestGrabber:
11     def run(self, options):
12         stderr = options.stderr
13         self.options = options
14         self.ophandle = ophandle = base32.b2a(os.urandom(16))
15         nodeurl = options['node-url']
16         if not nodeurl.endswith("/"):
17             nodeurl += "/"
18         self.nodeurl = nodeurl
19         where = options.where
20         rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
21         if path == '/':
22             path = ''
23         url = nodeurl + "uri/%s" % urllib.quote(rootcap)
24         if path:
25             url += "/" + escape_path(path)
26         # todo: should it end with a slash?
27         url += "?t=start-manifest&ophandle=" + ophandle
28         resp = do_http("POST", url)
29         if resp.status not in (200, 302):
30             print >>stderr, "ERROR", resp.status, resp.reason, resp.read()
31             return 1
32         # now we poll for results. We nominally poll at t=1, 5, 10, 30, 60,
33         # 90, k*120 seconds, but if the poll takes non-zero time, that will
34         # be slightly longer. I'm not worried about trying to make up for
35         # that time.
36
37         return self.wait_for_results()
38
39     def poll_times(self):
40         for i in (1,5,10,30,60,90):
41             yield i
42         i = 120
43         while True:
44             yield i
45             i += 120
46
47     def wait_for_results(self):
48         last = 0
49         for next in self.poll_times():
50             delay = next - last
51             time.sleep(delay)
52             last = next
53             if self.poll():
54                 return 0
55
56     def poll(self):
57         url = self.nodeurl + "operations/" + self.ophandle
58         url += "?t=status&output=JSON&release-after-complete=true"
59         stdout = self.options.stdout
60         stderr = self.options.stderr
61         resp = do_http("GET", url)
62         if resp.status != 200:
63             print >>stderr, "ERROR", resp.status, resp.reason, resp.read()
64             return True
65         data = simplejson.loads(resp.read())
66         if not data["finished"]:
67             return False
68         self.write_results(data)
69         return True
70
71     def write_results(self, data):
72         stdout = self.options.stdout
73         stderr = self.options.stderr
74         if self.options["storage-index"]:
75             for (path, cap) in data["manifest"]:
76                 u = uri.from_string(str(cap))
77                 si = u.get_storage_index()
78                 if si is not None:
79                     print >>stdout, base32.b2a(si)
80         else:
81             for (path, cap) in data["manifest"]:
82                 try:
83                     print >>stdout, cap, "/".join(path)
84                 except UnicodeEncodeError:
85                     print >>stdout, cap, "/".join([p.encode("utf-8")
86                                                    for p in path])
87
88
89
90 def manifest(options):
91     return ManifestGrabber().run(options)