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 % {"uri": urllib.quote(upload_results.get_uri())
55 return url.URL.fromString(redir_to)
56 d.addCallback(_done, when_done)
58 # return the Upload Results page, which includes the URI
59 d.addCallback(UploadResultsPage)
63 class UploadResultsPage(status.UploadResultsRendererMixin, rend.Page):
64 """'POST /uri', to create an unlinked file."""
65 docFactory = getxmlfile("upload-results.xhtml")
67 def __init__(self, upload_results):
68 rend.Page.__init__(self)
69 self.results = upload_results
71 def upload_results(self):
72 return defer.succeed(self.results)
74 def data_done(self, ctx, data):
75 d = self.upload_results()
76 d.addCallback(lambda res: "done!")
79 def data_uri(self, ctx, data):
80 d = self.upload_results()
81 d.addCallback(lambda res: res.get_uri())
84 def render_download_link(self, ctx, data):
85 d = self.upload_results()
86 d.addCallback(lambda res:
87 T.a(href="/uri/" + urllib.quote(res.get_uri()))
88 ["/uri/" + res.get_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 file_format = get_format(req, None)
116 if file_format == "CHK":
117 raise WebError("format=CHK not currently accepted for POST /uri?t=mkdir",
121 mt = get_mutable_type(file_format)
122 d = client.create_dirnode(version=mt)
123 redirect = get_arg(req, "redirect_to_result", "false")
124 if boolean_of_arg(redirect):
125 def _then_redir(res):
126 new_url = "uri/" + urllib.quote(res.get_uri())
127 req.setResponseCode(http.SEE_OTHER) # 303
128 req.setHeader('location', new_url)
131 d.addCallback(_then_redir)
133 d.addCallback(lambda dirnode: dirnode.get_uri())
136 def POSTUnlinkedCreateDirectoryWithChildren(req, client):
137 # "POST /uri?t=mkdir", to create an unlinked directory.
139 kids_json = req.content.read()
140 kids = convert_children_json(client.nodemaker, kids_json)
141 d = client.create_dirnode(initial_children=kids)
142 redirect = get_arg(req, "redirect_to_result", "false")
143 if boolean_of_arg(redirect):
144 def _then_redir(res):
145 new_url = "uri/" + urllib.quote(res.get_uri())
146 req.setResponseCode(http.SEE_OTHER) # 303
147 req.setHeader('location', new_url)
150 d.addCallback(_then_redir)
152 d.addCallback(lambda dirnode: dirnode.get_uri())
155 def POSTUnlinkedCreateImmutableDirectory(req, client):
156 # "POST /uri?t=mkdir", to create an unlinked directory.
158 kids_json = req.content.read()
159 kids = convert_children_json(client.nodemaker, kids_json)
160 d = client.create_immutable_dirnode(kids)
161 redirect = get_arg(req, "redirect_to_result", "false")
162 if boolean_of_arg(redirect):
163 def _then_redir(res):
164 new_url = "uri/" + urllib.quote(res.get_uri())
165 req.setResponseCode(http.SEE_OTHER) # 303
166 req.setHeader('location', new_url)
169 d.addCallback(_then_redir)
171 d.addCallback(lambda dirnode: dirnode.get_uri())