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, get_format, get_mutable_type
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.get_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 file_format = get_format(req, None)
31 if file_format == "CHK":
32 raise WebError("format=CHK not accepted for PUT /uri?t=mkdir",
36 mt = get_mutable_type(file_format)
37 d = client.create_dirnode(version=mt)
38 d.addCallback(lambda dirnode: dirnode.get_uri())
39 # XXX add redirect_to_result
43 def POSTUnlinkedCHK(req, client):
44 fileobj = req.fields["file"].file
45 uploadable = FileHandle(fileobj, client.convergence)
46 d = client.upload(uploadable)
47 when_done = get_arg(req, "when_done", None)
49 # if when_done= is provided, return a redirect instead of our
50 # usual upload-results page
51 def _done(upload_results, redir_to):
52 if "%(uri)s" in redir_to:
53 redir_to = redir_to.replace("%(uri)s", urllib.quote(upload_results.get_uri()))
54 return url.URL.fromString(redir_to)
55 d.addCallback(_done, when_done)
57 # return the Upload Results page, which includes the URI
58 d.addCallback(UploadResultsPage)
62 class UploadResultsPage(status.UploadResultsRendererMixin, rend.Page):
63 """'POST /uri', to create an unlinked file."""
64 docFactory = getxmlfile("upload-results.xhtml")
66 def __init__(self, upload_results):
67 rend.Page.__init__(self)
68 self.results = upload_results
70 def upload_results(self):
71 return defer.succeed(self.results)
73 def data_done(self, ctx, data):
74 d = self.upload_results()
75 d.addCallback(lambda res: "done!")
78 def data_uri(self, ctx, data):
79 d = self.upload_results()
80 d.addCallback(lambda res: res.get_uri())
83 def render_download_link(self, ctx, data):
84 d = self.upload_results()
85 d.addCallback(lambda res:
86 T.a(href="/uri/" + urllib.quote(res.get_uri()))
87 ["/uri/" + res.get_uri()])
90 def POSTUnlinkedSSK(req, client, version):
91 # "POST /uri", to create an unlinked file.
92 # SDMF: files are small, and we can only upload data
93 contents = req.fields["file"].file
94 data = MutableFileHandle(contents)
95 d = client.create_mutable_file(data, version=version)
96 d.addCallback(lambda n: n.get_uri())
99 def POSTUnlinkedCreateDirectory(req, client):
100 # "POST /uri?t=mkdir", to create an unlinked directory.
101 ct = req.getHeader("content-type") or ""
102 if not ct.startswith("multipart/form-data"):
103 # guard against accidental attempts to call t=mkdir as if it were
104 # t=mkdir-with-children, but make sure we tolerate the usual HTML
105 # create-directory form (in which the t=mkdir and redirect_to_result=
106 # and other arguments can be passed encoded as multipath/form-data,
107 # in the request body).
109 kids_json = req.content.read()
111 raise WebError("t=mkdir does not accept children=, "
112 "try t=mkdir-with-children instead",
114 file_format = get_format(req, None)
115 if file_format == "CHK":
116 raise WebError("format=CHK not currently accepted for POST /uri?t=mkdir",
120 mt = get_mutable_type(file_format)
121 d = client.create_dirnode(version=mt)
122 redirect = get_arg(req, "redirect_to_result", "false")
123 if boolean_of_arg(redirect):
124 def _then_redir(res):
125 new_url = "uri/" + urllib.quote(res.get_uri())
126 req.setResponseCode(http.SEE_OTHER) # 303
127 req.setHeader('location', new_url)
130 d.addCallback(_then_redir)
132 d.addCallback(lambda dirnode: dirnode.get_uri())
135 def POSTUnlinkedCreateDirectoryWithChildren(req, client):
136 # "POST /uri?t=mkdir", to create an unlinked directory.
138 kids_json = req.content.read()
139 kids = convert_children_json(client.nodemaker, kids_json)
140 d = client.create_dirnode(initial_children=kids)
141 redirect = get_arg(req, "redirect_to_result", "false")
142 if boolean_of_arg(redirect):
143 def _then_redir(res):
144 new_url = "uri/" + urllib.quote(res.get_uri())
145 req.setResponseCode(http.SEE_OTHER) # 303
146 req.setHeader('location', new_url)
149 d.addCallback(_then_redir)
151 d.addCallback(lambda dirnode: dirnode.get_uri())
154 def POSTUnlinkedCreateImmutableDirectory(req, client):
155 # "POST /uri?t=mkdir", to create an unlinked directory.
157 kids_json = req.content.read()
158 kids = convert_children_json(client.nodemaker, kids_json)
159 d = client.create_immutable_dirnode(kids)
160 redirect = get_arg(req, "redirect_to_result", "false")
161 if boolean_of_arg(redirect):
162 def _then_redir(res):
163 new_url = "uri/" + urllib.quote(res.get_uri())
164 req.setResponseCode(http.SEE_OTHER) # 303
165 req.setHeader('location', new_url)
168 d.addCallback(_then_redir)
170 d.addCallback(lambda dirnode: dirnode.get_uri())