4 from nevow import rend, tags as T
5 from nevow.inevow import IRequest
7 from allmydata.util import base32
8 from allmydata.interfaces import IDirectoryNode, IFileNode, MDMF_VERSION
9 from allmydata.web.common import getxmlfile
10 from allmydata.mutable.common import UnrecoverableFileError # TODO: move
12 class MoreInfo(rend.Page):
14 docFactory = getxmlfile("info.xhtml")
16 def abbrev(self, storage_index_or_none):
17 if storage_index_or_none:
18 return base32.b2a(storage_index_or_none)[:6]
23 if IDirectoryNode.providedBy(node):
24 if not node.is_mutable():
25 return "immutable directory"
27 if IFileNode.providedBy(node):
28 si = node.get_storage_index()
32 if node.get_version() == MDMF_VERSION:
37 return "immutable file"
38 return "immutable LIT file"
41 def render_title(self, ctx, data):
43 si = node.get_storage_index()
44 t = "More Info for %s" % self.get_type()
46 t += " (SI=%s)" % self.abbrev(si)
49 def render_header(self, ctx, data):
50 return self.render_title(ctx, data)
52 def render_type(self, ctx, data):
53 return ctx.tag[self.get_type()]
55 def render_si(self, ctx, data):
56 si = self.original.get_storage_index()
59 return ctx.tag[base32.b2a(si)]
61 def render_size(self, ctx, data):
63 d = node.get_current_size()
68 d.addCallback(_no_size)
69 def _handle_unrecoverable(f):
70 f.trap(UnrecoverableFileError)
72 d.addErrback(_handle_unrecoverable)
73 d.addCallback(lambda size: ctx.tag[size])
76 def render_directory_writecap(self, ctx, data):
78 if not IDirectoryNode.providedBy(node):
80 if node.is_readonly():
82 return ctx.tag[node.get_uri()]
84 def render_directory_readcap(self, ctx, data):
86 if not IDirectoryNode.providedBy(node):
88 return ctx.tag[node.get_readonly_uri()]
90 def render_directory_verifycap(self, ctx, data):
92 if not IDirectoryNode.providedBy(node):
94 verifier = node.get_verify_cap()
96 return ctx.tag[node.get_verify_cap().to_string()]
99 def render_file_writecap(self, ctx, data):
101 if IDirectoryNode.providedBy(node):
103 write_uri = node.get_write_uri()
106 return ctx.tag[write_uri]
108 def render_file_readcap(self, ctx, data):
110 if IDirectoryNode.providedBy(node):
112 read_uri = node.get_readonly_uri()
115 return ctx.tag[read_uri]
117 def render_file_verifycap(self, ctx, data):
119 if IDirectoryNode.providedBy(node):
121 verifier = node.get_verify_cap()
123 return ctx.tag[node.get_verify_cap().to_string()]
126 def get_root(self, ctx):
128 # the addSlash=True gives us one extra (empty) segment
129 depth = len(req.prepath) + len(req.postpath) - 1
130 link = "/".join([".."] * depth)
133 def render_raw_link(self, ctx, data):
135 if IDirectoryNode.providedBy(node):
137 elif IFileNode.providedBy(node):
141 root = self.get_root(ctx)
142 quoted_uri = urllib.quote(node.get_uri())
143 text_plain_url = "%s/file/%s/@@named=/raw.txt" % (root, quoted_uri)
144 return T.li["Raw data as ", T.a(href=text_plain_url)["text/plain"]]
146 def render_is_checkable(self, ctx, data):
148 si = node.get_storage_index()
151 # don't show checker button for LIT files
154 def render_check_form(self, ctx, data):
156 quoted_uri = urllib.quote(node.get_uri())
157 target = self.get_root(ctx) + "/uri/" + quoted_uri
158 if IDirectoryNode.providedBy(node):
160 check = T.form(action=target, method="post",
161 enctype="multipart/form-data")[
163 T.input(type="hidden", name="t", value="check"),
164 T.input(type="hidden", name="return_to", value="."),
165 T.legend(class_="freeform-form-label")["Check on this object"],
167 "Verify every bit? (EXPENSIVE):",
168 T.input(type="checkbox", name="verify"),
170 T.div["Repair any problems?: ",
171 T.input(type="checkbox", name="repair")],
172 T.div["Add/renew lease on all shares?: ",
173 T.input(type="checkbox", name="add-lease")],
174 T.div["Emit results in JSON format?: ",
175 T.input(type="checkbox", name="output", value="JSON")],
177 T.input(type="submit", value="Check"),
180 return ctx.tag[check]
182 def render_is_mutable_file(self, ctx, data):
184 if IDirectoryNode.providedBy(node):
186 if (IFileNode.providedBy(node)
187 and node.is_mutable() and not node.is_readonly()):
191 def render_overwrite_form(self, ctx, data):
193 root = self.get_root(ctx)
194 action = "%s/uri/%s" % (root, urllib.quote(node.get_uri()))
195 done_url = "%s/uri/%s?t=info" % (root, urllib.quote(node.get_uri()))
196 overwrite = T.form(action=action, method="post",
197 enctype="multipart/form-data")[
199 T.input(type="hidden", name="t", value="upload"),
200 T.input(type='hidden', name='when_done', value=done_url),
201 T.legend(class_="freeform-form-label")["Overwrite"],
202 "Upload new contents: ",
203 T.input(type="file", name="file"),
205 T.input(type="submit", value="Replace Contents")
207 return ctx.tag[overwrite]
209 def render_is_directory(self, ctx, data):
211 if IDirectoryNode.providedBy(node):
215 def render_deep_check_form(self, ctx, data):
216 ophandle = base32.b2a(os.urandom(16))
217 deep_check = T.form(action=".", method="post",
218 enctype="multipart/form-data")[
220 T.input(type="hidden", name="t", value="start-deep-check"),
221 T.input(type="hidden", name="return_to", value="."),
222 T.legend(class_="freeform-form-label")["Run a deep-check operation (EXPENSIVE)"],
224 "Verify every bit? (EVEN MORE EXPENSIVE):",
225 T.input(type="checkbox", name="verify"),
227 T.div["Repair any problems?: ",
228 T.input(type="checkbox", name="repair")],
229 T.div["Add/renew lease on all shares?: ",
230 T.input(type="checkbox", name="add-lease")],
231 T.div["Emit results in JSON format?: ",
232 T.input(type="checkbox", name="output", value="JSON")],
234 T.input(type="hidden", name="ophandle", value=ophandle),
235 T.input(type="submit", value="Deep-Check"),
238 return ctx.tag[deep_check]
240 def render_deep_size_form(self, ctx, data):
241 ophandle = base32.b2a(os.urandom(16))
242 deep_size = T.form(action=".", method="post",
243 enctype="multipart/form-data")[
245 T.input(type="hidden", name="t", value="start-deep-size"),
246 T.legend(class_="freeform-form-label")["Run a deep-size operation (EXPENSIVE)"],
247 T.input(type="hidden", name="ophandle", value=ophandle),
248 T.input(type="submit", value="Deep-Size"),
250 return ctx.tag[deep_size]
252 def render_deep_stats_form(self, ctx, data):
253 ophandle = base32.b2a(os.urandom(16))
254 deep_stats = T.form(action=".", method="post",
255 enctype="multipart/form-data")[
257 T.input(type="hidden", name="t", value="start-deep-stats"),
258 T.legend(class_="freeform-form-label")["Run a deep-stats operation (EXPENSIVE)"],
259 T.input(type="hidden", name="ophandle", value=ophandle),
260 T.input(type="submit", value="Deep-Stats"),
262 return ctx.tag[deep_stats]
264 def render_manifest_form(self, ctx, data):
265 ophandle = base32.b2a(os.urandom(16))
266 manifest = T.form(action=".", method="post",
267 enctype="multipart/form-data")[
269 T.input(type="hidden", name="t", value="start-manifest"),
270 T.legend(class_="freeform-form-label")["Run a manifest operation (EXPENSIVE)"],
271 T.div["Output Format: ",
272 T.select(name="output")
273 [ T.option(value="html", selected="true")["HTML"],
274 T.option(value="text")["text"],
275 T.option(value="json")["JSON"],
278 T.input(type="hidden", name="ophandle", value=ophandle),
279 T.input(type="submit", value="Manifest"),
281 return ctx.tag[manifest]
284 # TODO: edge metadata