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