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
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
20 def PUTUnlinkedSSK(req, client, version):
21 # SDMF: files are small, and we can only upload data
23 data = MutableFileHandle(req.content)
24 d = client.create_mutable_file(data, version=version)
25 d.addCallback(lambda n: n.get_uri())
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)
35 msg = "Unknown type: %s" % arg
36 raise WebError(msg, http.BAD_REQUEST)
38 d = client.create_dirnode()
39 d.addCallback(lambda dirnode: dirnode.get_uri())
40 # XXX add redirect_to_result
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)
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)
56 return url.URL.fromString(redir_to)
57 d.addCallback(_done, when_done)
59 # return the Upload Results page, which includes the URI
60 d.addCallback(UploadResultsPage)
64 class UploadResultsPage(status.UploadResultsRendererMixin, rend.Page):
65 """'POST /uri', to create an unlinked file."""
66 docFactory = getxmlfile("upload-results.xhtml")
68 def __init__(self, upload_results):
69 rend.Page.__init__(self)
70 self.results = upload_results
72 def upload_results(self):
73 return defer.succeed(self.results)
75 def data_done(self, ctx, data):
76 d = self.upload_results()
77 d.addCallback(lambda res: "done!")
80 def data_uri(self, ctx, data):
81 d = self.upload_results()
82 d.addCallback(lambda res: res.uri)
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))
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())
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).
110 kids_json = req.content.read()
112 raise WebError("t=mkdir does not accept children=, "
113 "try t=mkdir-with-children instead",
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)
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)
132 d.addCallback(_then_redir)
134 d.addCallback(lambda dirnode: dirnode.get_uri())
137 def POSTUnlinkedCreateDirectoryWithChildren(req, client):
138 # "POST /uri?t=mkdir", to create an unlinked directory.
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)
151 d.addCallback(_then_redir)
153 d.addCallback(lambda dirnode: dirnode.get_uri())
156 def POSTUnlinkedCreateImmutableDirectory(req, client):
157 # "POST /uri?t=mkdir", to create an unlinked directory.
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)
170 d.addCallback(_then_redir)
172 d.addCallback(lambda dirnode: dirnode.get_uri())