]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/tahoe_put.py
82a9e4cc28167d8fba24559d51d0b9aa72342533
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / tahoe_put.py
1
2 from cStringIO import StringIO
3 import urllib
4 from allmydata.scripts.common_http import do_http, format_http_success, format_http_error
5 from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
6                                      UnknownAliasError
7 from allmydata.util.stringutils import quote_output, open_unicode
8
9 def put(options):
10     """
11     @param verbosity: 0, 1, or 2, meaning quiet, verbose, or very verbose
12
13     @return: a Deferred which eventually fires with the exit code
14     """
15     nodeurl = options['node-url']
16     aliases = options.aliases
17     from_file = options.from_file
18     to_file = options.to_file
19     mutable = options['mutable']
20     if options['quiet']:
21         verbosity = 0
22     else:
23         verbosity = 2
24     stdin = options.stdin
25     stdout = options.stdout
26     stderr = options.stderr
27
28     if nodeurl[-1] != "/":
29         nodeurl += "/"
30     if to_file:
31         # several possibilities for the TO_FILE argument.
32         #  <none> : unlinked upload
33         #  foo : TAHOE_ALIAS/foo
34         #  subdir/foo : TAHOE_ALIAS/subdir/foo
35         #  /oops/subdir/foo : DISALLOWED
36         #  ALIAS:foo  : aliases[ALIAS]/foo
37         #  ALIAS:subdir/foo  : aliases[ALIAS]/subdir/foo
38
39         #  ALIAS:/oops/subdir/foo : DISALLOWED
40         #  DIRCAP:./foo        : DIRCAP/foo
41         #  DIRCAP:./subdir/foo : DIRCAP/subdir/foo
42         #  MUTABLE-FILE-WRITECAP : filecap
43
44         # FIXME: this shouldn't rely on a particular prefix.
45         if to_file.startswith("URI:SSK:"):
46             url = nodeurl + "uri/%s" % urllib.quote(to_file)
47         else:
48             try:
49                 rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS)
50             except UnknownAliasError, e:
51                 e.display(stderr)
52                 return 1
53             if path.startswith("/"):
54                 suggestion = to_file.replace(u"/", u"", 1)
55                 print >>stderr, "Error: The remote filename must not start with a slash"
56                 print >>stderr, "Please try again, perhaps with %s" % quote_output(suggestion)
57                 return 1
58             url = nodeurl + "uri/%s/" % urllib.quote(rootcap)
59             if path:
60                 url += escape_path(path)
61     else:
62         # unlinked upload
63         url = nodeurl + "uri"
64     if mutable:
65         url += "?mutable=true"
66     if from_file:
67         infileobj = open_unicode(from_file, "rb")
68     else:
69         # do_http() can't use stdin directly: for one thing, we need a
70         # Content-Length field. So we currently must copy it.
71         if verbosity > 0:
72             print >>stderr, "waiting for file data on stdin.."
73         data = stdin.read()
74         infileobj = StringIO(data)
75
76     resp = do_http("PUT", url, infileobj)
77
78     if resp.status in (200, 201,):
79         print >>stderr, format_http_success(resp)
80         print >>stdout, quote_output(resp.read(), quotemarks=False)
81         return 0
82
83     print >>stderr, format_http_error("Error", resp)
84     return 1