]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/web/info.py
webapi changes for MDMF
[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, MDMF_VERSION
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                     ret = "mutable file"
32                     if node.get_version() == MDMF_VERSION:
33                         ret += " (mdmf)"
34                     else:
35                         ret += " (sdmf)"
36                     return ret
37                 return "immutable file"
38             return "immutable LIT file"
39         return "unknown"
40
41     def render_title(self, ctx, data):
42         node = self.original
43         si = node.get_storage_index()
44         t = "More Info for %s" % self.get_type()
45         if si:
46             t += " (SI=%s)" % self.abbrev(si)
47         return ctx.tag[t]
48
49     def render_header(self, ctx, data):
50         return self.render_title(ctx, data)
51
52     def render_type(self, ctx, data):
53         return ctx.tag[self.get_type()]
54
55     def render_si(self, ctx, data):
56         si = self.original.get_storage_index()
57         if not si:
58             return "None"
59         return ctx.tag[base32.b2a(si)]
60
61     def render_size(self, ctx, data):
62         node = self.original
63         d = node.get_current_size()
64         def _no_size(size):
65             if size is None:
66                 return "?"
67             return size
68         d.addCallback(_no_size)
69         def _handle_unrecoverable(f):
70             f.trap(UnrecoverableFileError)
71             return "?"
72         d.addErrback(_handle_unrecoverable)
73         d.addCallback(lambda size: ctx.tag[size])
74         return d
75
76     def render_directory_writecap(self, ctx, data):
77         node = self.original
78         if not IDirectoryNode.providedBy(node):
79             return ""
80         if node.is_readonly():
81             return ""
82         return ctx.tag[node.get_uri()]
83
84     def render_directory_readcap(self, ctx, data):
85         node = self.original
86         if not IDirectoryNode.providedBy(node):
87             return ""
88         return ctx.tag[node.get_readonly_uri()]
89
90     def render_directory_verifycap(self, ctx, data):
91         node = self.original
92         if not IDirectoryNode.providedBy(node):
93             return ""
94         verifier = node.get_verify_cap()
95         if verifier:
96             return ctx.tag[node.get_verify_cap().to_string()]
97         return ""
98
99     def render_file_writecap(self, ctx, data):
100         node = self.original
101         if IDirectoryNode.providedBy(node):
102             node = node._node
103         write_uri = node.get_write_uri()
104         if not write_uri:
105             return ""
106         return ctx.tag[write_uri]
107
108     def render_file_readcap(self, ctx, data):
109         node = self.original
110         if IDirectoryNode.providedBy(node):
111             node = node._node
112         read_uri = node.get_readonly_uri()
113         if not read_uri:
114             return ""
115         return ctx.tag[read_uri]
116
117     def render_file_verifycap(self, ctx, data):
118         node = self.original
119         if IDirectoryNode.providedBy(node):
120             node = node._node
121         verifier = node.get_verify_cap()
122         if verifier:
123             return ctx.tag[node.get_verify_cap().to_string()]
124         return ""
125
126     def get_root(self, ctx):
127         req = IRequest(ctx)
128         # the addSlash=True gives us one extra (empty) segment
129         depth = len(req.prepath) + len(req.postpath) - 1
130         link = "/".join([".."] * depth)
131         return link
132
133     def render_raw_link(self, ctx, data):
134         node = self.original
135         if IDirectoryNode.providedBy(node):
136             node = node._node
137         elif IFileNode.providedBy(node):
138             pass
139         else:
140             return ""
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"]]
145
146     def render_is_checkable(self, ctx, data):
147         node = self.original
148         si = node.get_storage_index()
149         if si:
150             return ctx.tag
151         # don't show checker button for LIT files
152         return ""
153
154     def render_check_form(self, ctx, data):
155         node = self.original
156         quoted_uri = urllib.quote(node.get_uri())
157         target = self.get_root(ctx) + "/uri/" + quoted_uri
158         if IDirectoryNode.providedBy(node):
159             target += "/"
160         check = T.form(action=target, method="post",
161                        enctype="multipart/form-data")[
162             T.fieldset[
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"],
166             T.div[
167             "Verify every bit? (EXPENSIVE):",
168             T.input(type="checkbox", name="verify"),
169             ],
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")],
176
177             T.input(type="submit", value="Check"),
178
179             ]]
180         return ctx.tag[check]
181
182     def render_is_mutable_file(self, ctx, data):
183         node = self.original
184         if IDirectoryNode.providedBy(node):
185             return ""
186         if (IFileNode.providedBy(node)
187             and node.is_mutable() and not node.is_readonly()):
188             return ctx.tag
189         return ""
190
191     def render_overwrite_form(self, ctx, data):
192         node = self.original
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")[
198             T.fieldset[
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"),
204             " ",
205             T.input(type="submit", value="Replace Contents")
206             ]]
207         return ctx.tag[overwrite]
208
209     def render_is_directory(self, ctx, data):
210         node = self.original
211         if IDirectoryNode.providedBy(node):
212             return ctx.tag
213         return ""
214
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")[
219             T.fieldset[
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)"],
223             T.div[
224             "Verify every bit? (EVEN MORE EXPENSIVE):",
225             T.input(type="checkbox", name="verify"),
226             ],
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")],
233
234             T.input(type="hidden", name="ophandle", value=ophandle),
235             T.input(type="submit", value="Deep-Check"),
236
237             ]]
238         return ctx.tag[deep_check]
239
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")[
244             T.fieldset[
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"),
249             ]]
250         return ctx.tag[deep_size]
251
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")[
256             T.fieldset[
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"),
261             ]]
262         return ctx.tag[deep_stats]
263
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")[
268             T.fieldset[
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"],
276                     ],
277                   ],
278             T.input(type="hidden", name="ophandle", value=ophandle),
279             T.input(type="submit", value="Manifest"),
280             ]]
281         return ctx.tag[manifest]
282
283
284 # TODO: edge metadata