]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/web/unlinked.py
482bd285ae5260f7b02c552662277825ac83bbed
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / web / unlinked.py
1
2 import urllib
3 from twisted.web import http
4 from twisted.internet import defer
5 from nevow import rend, url, tags as T
6 from allmydata.immutable.upload import FileHandle
7 from allmydata.mutable.publish import MutableFileHandle
8 from allmydata.web.common import getxmlfile, get_arg, boolean_of_arg, \
9      convert_children_json, WebError, parse_mutable_type_arg
10 from allmydata.web import status
11
12 def PUTUnlinkedCHK(req, client):
13     # "PUT /uri", to create an unlinked file.
14     uploadable = FileHandle(req.content, client.convergence)
15     d = client.upload(uploadable)
16     d.addCallback(lambda results: results.uri)
17     # that fires with the URI of the new file
18     return d
19
20 def PUTUnlinkedSSK(req, client, version):
21     # SDMF: files are small, and we can only upload data
22     req.content.seek(0)
23     data = MutableFileHandle(req.content)
24     d = client.create_mutable_file(data, version=version)
25     d.addCallback(lambda n: n.get_uri())
26     return d
27
28 def PUTUnlinkedCreateDirectory(req, client):
29     # "PUT /uri?t=mkdir", to create an unlinked directory.
30     arg = get_arg(req, "mutable-type", None)
31     mt = parse_mutable_type_arg(arg)
32     if mt is not None and mt is not "invalid":
33         d = client.create_dirnode(version=mt)
34     elif mt is "invalid":
35         msg = "Unknown type: %s" % arg
36         raise WebError(msg, http.BAD_REQUEST)
37     else:
38         d = client.create_dirnode()
39     d.addCallback(lambda dirnode: dirnode.get_uri())
40     # XXX add redirect_to_result
41     return d
42
43
44 def POSTUnlinkedCHK(req, client):
45     fileobj = req.fields["file"].file
46     uploadable = FileHandle(fileobj, client.convergence)
47     d = client.upload(uploadable)
48     when_done = get_arg(req, "when_done", None)
49     if when_done:
50         # if when_done= is provided, return a redirect instead of our
51         # usual upload-results page
52         def _done(upload_results, redir_to):
53             if "%(uri)s" in redir_to:
54                 redir_to = redir_to % {"uri": urllib.quote(upload_results.uri)
55                                          }
56             return url.URL.fromString(redir_to)
57         d.addCallback(_done, when_done)
58     else:
59         # return the Upload Results page, which includes the URI
60         d.addCallback(UploadResultsPage)
61     return d
62
63
64 class UploadResultsPage(status.UploadResultsRendererMixin, rend.Page):
65     """'POST /uri', to create an unlinked file."""
66     docFactory = getxmlfile("upload-results.xhtml")
67
68     def __init__(self, upload_results):
69         rend.Page.__init__(self)
70         self.results = upload_results
71
72     def upload_results(self):
73         return defer.succeed(self.results)
74
75     def data_done(self, ctx, data):
76         d = self.upload_results()
77         d.addCallback(lambda res: "done!")
78         return d
79
80     def data_uri(self, ctx, data):
81         d = self.upload_results()
82         d.addCallback(lambda res: res.uri)
83         return d
84
85     def render_download_link(self, ctx, data):
86         d = self.upload_results()
87         d.addCallback(lambda res: T.a(href="/uri/" + urllib.quote(res.uri))
88                       ["/uri/" + res.uri])
89         return d
90
91 def POSTUnlinkedSSK(req, client, version):
92     # "POST /uri", to create an unlinked file.
93     # SDMF: files are small, and we can only upload data
94     contents = req.fields["file"].file
95     data = MutableFileHandle(contents)
96     d = client.create_mutable_file(data, version=version)
97     d.addCallback(lambda n: n.get_uri())
98     return d
99
100 def POSTUnlinkedCreateDirectory(req, client):
101     # "POST /uri?t=mkdir", to create an unlinked directory.
102     ct = req.getHeader("content-type") or ""
103     if not ct.startswith("multipart/form-data"):
104         # guard against accidental attempts to call t=mkdir as if it were
105         # t=mkdir-with-children, but make sure we tolerate the usual HTML
106         # create-directory form (in which the t=mkdir and redirect_to_result=
107         # and other arguments can be passed encoded as multipath/form-data,
108         # in the request body).
109         req.content.seek(0)
110         kids_json = req.content.read()
111         if kids_json:
112             raise WebError("t=mkdir does not accept children=, "
113                            "try t=mkdir-with-children instead",
114                            http.BAD_REQUEST)
115     arg = get_arg(req, "mutable-type", None)
116     mt = parse_mutable_type_arg(arg)
117     if mt is not None and mt is not "invalid":
118         d = client.create_dirnode(version=mt)
119     elif mt is "invalid":
120         msg = "Unknown type: %s" % arg
121         raise WebError(msg, http.BAD_REQUEST)
122     else:
123         d = client.create_dirnode()
124     redirect = get_arg(req, "redirect_to_result", "false")
125     if boolean_of_arg(redirect):
126         def _then_redir(res):
127             new_url = "uri/" + urllib.quote(res.get_uri())
128             req.setResponseCode(http.SEE_OTHER) # 303
129             req.setHeader('location', new_url)
130             req.finish()
131             return ''
132         d.addCallback(_then_redir)
133     else:
134         d.addCallback(lambda dirnode: dirnode.get_uri())
135     return d
136
137 def POSTUnlinkedCreateDirectoryWithChildren(req, client):
138     # "POST /uri?t=mkdir", to create an unlinked directory.
139     req.content.seek(0)
140     kids_json = req.content.read()
141     kids = convert_children_json(client.nodemaker, kids_json)
142     d = client.create_dirnode(initial_children=kids)
143     redirect = get_arg(req, "redirect_to_result", "false")
144     if boolean_of_arg(redirect):
145         def _then_redir(res):
146             new_url = "uri/" + urllib.quote(res.get_uri())
147             req.setResponseCode(http.SEE_OTHER) # 303
148             req.setHeader('location', new_url)
149             req.finish()
150             return ''
151         d.addCallback(_then_redir)
152     else:
153         d.addCallback(lambda dirnode: dirnode.get_uri())
154     return d
155
156 def POSTUnlinkedCreateImmutableDirectory(req, client):
157     # "POST /uri?t=mkdir", to create an unlinked directory.
158     req.content.seek(0)
159     kids_json = req.content.read()
160     kids = convert_children_json(client.nodemaker, kids_json)
161     d = client.create_immutable_dirnode(kids)
162     redirect = get_arg(req, "redirect_to_result", "false")
163     if boolean_of_arg(redirect):
164         def _then_redir(res):
165             new_url = "uri/" + urllib.quote(res.get_uri())
166             req.setResponseCode(http.SEE_OTHER) # 303
167             req.setHeader('location', new_url)
168             req.finish()
169             return ''
170         d.addCallback(_then_redir)
171     else:
172         d.addCallback(lambda dirnode: dirnode.get_uri())
173     return d