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