]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/web/info.py
4a765859f23d2bbe8043b16755f4644a13632434
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / web / info.py
1
2 import os, urllib
3
4 from nevow import rend, tags as T
5 from nevow.inevow import IRequest
6
7 from allmydata.util import base32
8 from allmydata.interfaces import IDirectoryNode, IFileNode
9 from allmydata.web.common import getxmlfile
10 from allmydata.mutable.common import UnrecoverableFileError # TODO: move
11
12 class MoreInfo(rend.Page):
13     addSlash = False
14     docFactory = getxmlfile("info.xhtml")
15
16     def abbrev(self, storage_index_or_none):
17         if storage_index_or_none:
18             return base32.b2a(storage_index_or_none)[:6]
19         return "LIT file"
20
21     def get_type(self):
22         node = self.original
23         if IDirectoryNode.providedBy(node):
24             if not node.is_mutable():
25                 return "immutable directory"
26             return "directory"
27         if IFileNode.providedBy(node):
28             si = node.get_storage_index()
29             if si:
30                 if node.is_mutable():
31                     return "mutable file"
32                 return "immutable file"
33             return "immutable LIT file"
34         return "unknown"
35
36     def render_title(self, ctx, data):
37         node = self.original
38         si = node.get_storage_index()
39         t = "More Info for %s" % self.get_type()
40         if si:
41             t += " (SI=%s)" % self.abbrev(si)
42         return ctx.tag[t]
43
44     def render_header(self, ctx, data):
45         return self.render_title(ctx, data)
46
47     def render_type(self, ctx, data):
48         return ctx.tag[self.get_type()]
49
50     def render_si(self, ctx, data):
51         si = self.original.get_storage_index()
52         if not si:
53             return "None"
54         return ctx.tag[base32.b2a(si)]
55
56     def render_size(self, ctx, data):
57         node = self.original
58         d = node.get_current_size()
59         def _no_size(size):
60             if size is None:
61                 return "?"
62             return size
63         d.addCallback(_no_size)
64         def _handle_unrecoverable(f):
65             f.trap(UnrecoverableFileError)
66             return "?"
67         d.addErrback(_handle_unrecoverable)
68         d.addCallback(lambda size: ctx.tag[size])
69         return d
70
71     def render_directory_writecap(self, ctx, data):
72         node = self.original
73         if not IDirectoryNode.providedBy(node):
74             return ""
75         if node.is_readonly():
76             return ""
77         return ctx.tag[node.get_uri()]
78
79     def render_directory_readcap(self, ctx, data):
80         node = self.original
81         if not IDirectoryNode.providedBy(node):
82             return ""
83         return ctx.tag[node.get_readonly_uri()]
84
85     def render_directory_verifycap(self, ctx, data):
86         node = self.original
87         if not IDirectoryNode.providedBy(node):
88             return ""
89         verifier = node.get_verify_cap()
90         if verifier:
91             return ctx.tag[node.get_verify_cap().to_string()]
92         return ""
93
94     def render_file_writecap(self, ctx, data):
95         node = self.original
96         if IDirectoryNode.providedBy(node):
97             node = node._node
98         write_uri = node.get_write_uri()
99         if not write_uri:
100             return ""
101         return ctx.tag[write_uri]
102
103     def render_file_readcap(self, ctx, data):
104         node = self.original
105         if IDirectoryNode.providedBy(node):
106             node = node._node
107         read_uri = node.get_readonly_uri()
108         if not read_uri:
109             return ""
110         return ctx.tag[read_uri]
111
112     def render_file_verifycap(self, ctx, data):
113         node = self.original
114         if IDirectoryNode.providedBy(node):
115             node = node._node
116         verifier = node.get_verify_cap()
117         if verifier:
118             return ctx.tag[node.get_verify_cap().to_string()]
119         return ""
120
121     def get_root(self, ctx):
122         req = IRequest(ctx)
123         # the addSlash=True gives us one extra (empty) segment
124         depth = len(req.prepath) + len(req.postpath) - 1
125         link = "/".join([".."] * depth)
126         return link
127
128     def render_raw_link(self, ctx, data):
129         node = self.original
130         if IDirectoryNode.providedBy(node):
131             node = node._node
132         elif IFileNode.providedBy(node):
133             pass
134         else:
135             return ""
136         root = self.get_root(ctx)
137         quoted_uri = urllib.quote(node.get_uri())
138         text_plain_url = "%s/file/%s/@@named=/raw.txt" % (root, quoted_uri)
139         return T.li["Raw data as ", T.a(href=text_plain_url)["text/plain"]]
140
141     def render_is_checkable(self, ctx, data):
142         node = self.original
143         si = node.get_storage_index()
144         if si:
145             return ctx.tag
146         # don't show checker button for LIT files
147         return ""
148
149     def render_check_form(self, ctx, data):
150         node = self.original
151         quoted_uri = urllib.quote(node.get_uri())
152         target = self.get_root(ctx) + "/uri/" + quoted_uri
153         if IDirectoryNode.providedBy(node):
154             target += "/"
155         check = T.form(action=target, method="post",
156                        enctype="multipart/form-data")[
157             T.fieldset[
158             T.input(type="hidden", name="t", value="check"),
159             T.input(type="hidden", name="return_to", value="."),
160             T.legend(class_="freeform-form-label")["Check on this object"],
161             T.div[
162             "Verify every bit? (EXPENSIVE):",
163             T.input(type="checkbox", name="verify"),
164             ],
165             T.div["Repair any problems?: ",
166                   T.input(type="checkbox", name="repair")],
167             T.div["Add/renew lease on all shares?: ",
168                   T.input(type="checkbox", name="add-lease")],
169             T.div["Emit results in JSON format?: ",
170                   T.input(type="checkbox", name="output", value="JSON")],
171
172             T.input(type="submit", value="Check"),
173
174             ]]
175         return ctx.tag[check]
176
177     def render_is_mutable_file(self, ctx, data):
178         node = self.original
179         if IDirectoryNode.providedBy(node):
180             return ""
181         if (IFileNode.providedBy(node)
182             and node.is_mutable() and not node.is_readonly()):
183             return ctx.tag
184         return ""
185
186     def render_overwrite_form(self, ctx, data):
187         node = self.original
188         root = self.get_root(ctx)
189         action = "%s/uri/%s" % (root, urllib.quote(node.get_uri()))
190         done_url = "%s/uri/%s?t=info" % (root, urllib.quote(node.get_uri()))
191         overwrite = T.form(action=action, method="post",
192                            enctype="multipart/form-data")[
193             T.fieldset[
194             T.input(type="hidden", name="t", value="upload"),
195             T.input(type='hidden', name='when_done', value=done_url),
196             T.legend(class_="freeform-form-label")["Overwrite"],
197             "Upload new contents: ",
198             T.input(type="file", name="file"),
199             " ",
200             T.input(type="submit", value="Replace Contents")
201             ]]
202         return ctx.tag[overwrite]
203
204     def render_is_directory(self, ctx, data):
205         node = self.original
206         if IDirectoryNode.providedBy(node):
207             return ctx.tag
208         return ""
209
210     def render_deep_check_form(self, ctx, data):
211         ophandle = base32.b2a(os.urandom(16))
212         deep_check = T.form(action=".", method="post",
213                             enctype="multipart/form-data")[
214             T.fieldset[
215             T.input(type="hidden", name="t", value="start-deep-check"),
216             T.input(type="hidden", name="return_to", value="."),
217             T.legend(class_="freeform-form-label")["Run a deep-check operation (EXPENSIVE)"],
218             T.div[
219             "Verify every bit? (EVEN MORE EXPENSIVE):",
220             T.input(type="checkbox", name="verify"),
221             ],
222             T.div["Repair any problems?: ",
223                   T.input(type="checkbox", name="repair")],
224             T.div["Add/renew lease on all shares?: ",
225                   T.input(type="checkbox", name="add-lease")],
226             T.div["Emit results in JSON format?: ",
227                   T.input(type="checkbox", name="output", value="JSON")],
228
229             T.input(type="hidden", name="ophandle", value=ophandle),
230             T.input(type="submit", value="Deep-Check"),
231
232             ]]
233         return ctx.tag[deep_check]
234
235     def render_deep_size_form(self, ctx, data):
236         ophandle = base32.b2a(os.urandom(16))
237         deep_size = T.form(action=".", method="post",
238                             enctype="multipart/form-data")[
239             T.fieldset[
240             T.input(type="hidden", name="t", value="start-deep-size"),
241             T.legend(class_="freeform-form-label")["Run a deep-size operation (EXPENSIVE)"],
242             T.input(type="hidden", name="ophandle", value=ophandle),
243             T.input(type="submit", value="Deep-Size"),
244             ]]
245         return ctx.tag[deep_size]
246
247     def render_deep_stats_form(self, ctx, data):
248         ophandle = base32.b2a(os.urandom(16))
249         deep_stats = T.form(action=".", method="post",
250                             enctype="multipart/form-data")[
251             T.fieldset[
252             T.input(type="hidden", name="t", value="start-deep-stats"),
253             T.legend(class_="freeform-form-label")["Run a deep-stats operation (EXPENSIVE)"],
254             T.input(type="hidden", name="ophandle", value=ophandle),
255             T.input(type="submit", value="Deep-Stats"),
256             ]]
257         return ctx.tag[deep_stats]
258
259     def render_manifest_form(self, ctx, data):
260         ophandle = base32.b2a(os.urandom(16))
261         manifest = T.form(action=".", method="post",
262                             enctype="multipart/form-data")[
263             T.fieldset[
264             T.input(type="hidden", name="t", value="start-manifest"),
265             T.legend(class_="freeform-form-label")["Run a manifest operation (EXPENSIVE)"],
266             T.div["Output Format: ",
267                   T.select(name="output")
268                   [ T.option(value="html", selected="true")["HTML"],
269                     T.option(value="text")["text"],
270                     T.option(value="json")["JSON"],
271                     ],
272                   ],
273             T.input(type="hidden", name="ophandle", value=ophandle),
274             T.input(type="submit", value="Manifest"),
275             ]]
276         return ctx.tag[manifest]
277
278
279 # TODO: edge metadata