Port info.xhtml to twt.

This commit is contained in:
hab 2019-08-14 12:53:53 +01:00
parent 85980038de
commit a01c375327
2 changed files with 158 additions and 122 deletions

View File

@ -1,17 +1,33 @@
import os, urllib import os, urllib
from nevow import rend, tags as T from twisted.python.filepath import FilePath
from nevow.inevow import IRequest from twisted.web.template import tags as T, Element, renderElement, XMLFile, renderer
from allmydata.util import base32 from allmydata.util import base32
from allmydata.interfaces import IDirectoryNode, IFileNode, MDMF_VERSION from allmydata.interfaces import IDirectoryNode, IFileNode, MDMF_VERSION
from allmydata.web.common import getxmlfile from allmydata.web.common import MultiFormatResource
from allmydata.mutable.common import UnrecoverableFileError # TODO: move from allmydata.mutable.common import UnrecoverableFileError # TODO: move
class MoreInfo(rend.Page):
addSlash = False class MoreInfo(MultiFormatResource):
docFactory = getxmlfile("info.xhtml") def __init__(self, node):
super(MoreInfo, self).__init__()
self.node = node
def render_HTML(self, req):
return renderElement(req, MoreInfoElement(self.node))
render_INFO = render_HTML
class MoreInfoElement(Element):
loader = XMLFile(FilePath(__file__).sibling("info.xhtml"))
def __init__(self, node):
super(MoreInfoElement, self).__init__()
self.original = node
def abbrev(self, storage_index_or_none): def abbrev(self, storage_index_or_none):
if storage_index_or_none: if storage_index_or_none:
@ -38,27 +54,32 @@ class MoreInfo(rend.Page):
return "immutable LIT file" return "immutable LIT file"
return "unknown" return "unknown"
def render_title(self, ctx, data): @renderer
def title(self, req, tag):
node = self.original node = self.original
si = node.get_storage_index() si = node.get_storage_index()
t = "More Info for %s" % self.get_type() t = "More Info for %s" % self.get_type()
if si: if si:
t += " (SI=%s)" % self.abbrev(si) t += " (SI=%s)" % self.abbrev(si)
return ctx.tag[t] return tag(t)
def render_header(self, ctx, data): @renderer
return self.render_title(ctx, data) def header(self, req, tag):
return self.title(req, tag)
def render_type(self, ctx, data): @renderer
return ctx.tag[self.get_type()] def type(self, req, tag):
return tag(self.get_type())
def render_si(self, ctx, data): @renderer
def si(self, req, tag):
si = self.original.get_storage_index() si = self.original.get_storage_index()
if not si: if not si:
return "None" return "None"
return ctx.tag[base32.b2a(si)] return tag(base32.b2a(si))
def render_size(self, ctx, data): @renderer
def size(self, req, tag):
node = self.original node = self.original
d = node.get_current_size() d = node.get_current_size()
def _no_size(size): def _no_size(size):
@ -70,67 +91,73 @@ class MoreInfo(rend.Page):
f.trap(UnrecoverableFileError) f.trap(UnrecoverableFileError)
return "?" return "?"
d.addErrback(_handle_unrecoverable) d.addErrback(_handle_unrecoverable)
d.addCallback(lambda size: ctx.tag[size]) d.addCallback(lambda size: tag(str(size)))
return d return d
def render_directory_writecap(self, ctx, data): @renderer
def directory_writecap(self, req, tag):
node = self.original node = self.original
if not IDirectoryNode.providedBy(node): if not IDirectoryNode.providedBy(node):
return "" return ""
if node.is_readonly(): if node.is_readonly():
return "" return ""
return ctx.tag[node.get_uri()] return tag(node.get_uri())
def render_directory_readcap(self, ctx, data): @renderer
def directory_readcap(self, req, tag):
node = self.original node = self.original
if not IDirectoryNode.providedBy(node): if not IDirectoryNode.providedBy(node):
return "" return ""
return ctx.tag[node.get_readonly_uri()] return tag(node.get_readonly_uri())
def render_directory_verifycap(self, ctx, data): @renderer
def directory_verifycap(self, req, tag):
node = self.original node = self.original
if not IDirectoryNode.providedBy(node): if not IDirectoryNode.providedBy(node):
return "" return ""
verifier = node.get_verify_cap() verifier = node.get_verify_cap()
if verifier: if verifier:
return ctx.tag[node.get_verify_cap().to_string()] return tag(node.get_verify_cap().to_string())
return "" return ""
def render_file_writecap(self, ctx, data): @renderer
def file_writecap(self, req, tag):
node = self.original node = self.original
if IDirectoryNode.providedBy(node): if IDirectoryNode.providedBy(node):
node = node._node node = node._node
write_uri = node.get_write_uri() write_uri = node.get_write_uri()
if not write_uri: if not write_uri:
return "" return ""
return ctx.tag[write_uri] return tag(write_uri)
def render_file_readcap(self, ctx, data): @renderer
def file_readcap(self, req, tag):
node = self.original node = self.original
if IDirectoryNode.providedBy(node): if IDirectoryNode.providedBy(node):
node = node._node node = node._node
read_uri = node.get_readonly_uri() read_uri = node.get_readonly_uri()
if not read_uri: if not read_uri:
return "" return ""
return ctx.tag[read_uri] return tag(read_uri)
def render_file_verifycap(self, ctx, data): @renderer
def file_verifycap(self, req, tag):
node = self.original node = self.original
if IDirectoryNode.providedBy(node): if IDirectoryNode.providedBy(node):
node = node._node node = node._node
verifier = node.get_verify_cap() verifier = node.get_verify_cap()
if verifier: if verifier:
return ctx.tag[node.get_verify_cap().to_string()] return tag(node.get_verify_cap().to_string())
return "" return ""
def get_root(self, ctx): def get_root(self, req):
req = IRequest(ctx)
# the addSlash=True gives us one extra (empty) segment # the addSlash=True gives us one extra (empty) segment
depth = len(req.prepath) + len(req.postpath) - 1 depth = len(req.prepath) + len(req.postpath) - 1
link = "/".join([".."] * depth) link = "/".join([".."] * depth)
return link return link
def render_raw_link(self, ctx, data): @renderer
def raw_link(self, req, tag):
node = self.original node = self.original
if IDirectoryNode.providedBy(node): if IDirectoryNode.providedBy(node):
node = node._node node = node._node
@ -138,147 +165,156 @@ class MoreInfo(rend.Page):
pass pass
else: else:
return "" return ""
root = self.get_root(ctx) root = self.get_root(req)
quoted_uri = urllib.quote(node.get_uri()) quoted_uri = urllib.quote(node.get_uri())
text_plain_url = "%s/file/%s/@@named=/raw.txt" % (root, quoted_uri) text_plain_url = "%s/file/%s/@@named=/raw.txt" % (root, quoted_uri)
return T.li["Raw data as ", T.a(href=text_plain_url)["text/plain"]] return T.li("Raw data as ", T.a("text/plain", href=text_plain_url))
def render_is_checkable(self, ctx, data): @renderer
def is_checkable(self, req, tag):
node = self.original node = self.original
si = node.get_storage_index() si = node.get_storage_index()
if si: if si:
return ctx.tag return tag
# don't show checker button for LIT files # don't show checker button for LIT files
return "" return ""
def render_check_form(self, ctx, data): @renderer
def check_form(self, req, tag):
node = self.original node = self.original
quoted_uri = urllib.quote(node.get_uri()) quoted_uri = urllib.quote(node.get_uri())
target = self.get_root(ctx) + "/uri/" + quoted_uri target = self.get_root(req) + "/uri/" + quoted_uri
if IDirectoryNode.providedBy(node): if IDirectoryNode.providedBy(node):
target += "/" target += "/"
check = T.form(action=target, method="post", check = T.form(action=target, method="post",
enctype="multipart/form-data")[ enctype="multipart/form-data")(
T.fieldset[ T.fieldset(
T.input(type="hidden", name="t", value="check"), T.input(type="hidden", name="t", value="check"),
T.input(type="hidden", name="return_to", value="."), T.input(type="hidden", name="return_to", value="."),
T.legend(class_="freeform-form-label")["Check on this object"], T.legend("Check on this object", class_="freeform-form-label"),
T.div[ T.div(
"Verify every bit? (EXPENSIVE):", "Verify every bit? (EXPENSIVE):",
T.input(type="checkbox", name="verify"), T.input(type="checkbox", name="verify"),
], ),
T.div["Repair any problems?: ", T.div("Repair any problems?: ",
T.input(type="checkbox", name="repair")], T.input(type="checkbox", name="repair")),
T.div["Add/renew lease on all shares?: ", T.div("Add/renew lease on all shares?: ",
T.input(type="checkbox", name="add-lease")], T.input(type="checkbox", name="add-lease")),
T.div["Emit results in JSON format?: ", T.div("Emit results in JSON format?: ",
T.input(type="checkbox", name="output", value="JSON")], T.input(type="checkbox", name="output", value="JSON")),
T.input(type="submit", value="Check"), T.input(type="submit", value="Check"),
]] ))
return ctx.tag[check] return tag(check)
def render_is_mutable_file(self, ctx, data): @renderer
def is_mutable_file(self, req, tag):
node = self.original node = self.original
if IDirectoryNode.providedBy(node): if IDirectoryNode.providedBy(node):
return "" return ""
if (IFileNode.providedBy(node) if (IFileNode.providedBy(node)
and node.is_mutable() and not node.is_readonly()): and node.is_mutable() and not node.is_readonly()):
return ctx.tag return tag
return "" return ""
def render_overwrite_form(self, ctx, data): @renderer
def overwrite_form(self, req, tag):
node = self.original node = self.original
root = self.get_root(ctx) root = self.get_root(req)
action = "%s/uri/%s" % (root, urllib.quote(node.get_uri())) action = "%s/uri/%s" % (root, urllib.quote(node.get_uri()))
done_url = "%s/uri/%s?t=info" % (root, urllib.quote(node.get_uri())) done_url = "%s/uri/%s?t=info" % (root, urllib.quote(node.get_uri()))
overwrite = T.form(action=action, method="post", overwrite = T.form(action=action, method="post",
enctype="multipart/form-data")[ enctype="multipart/form-data")(
T.fieldset[ T.fieldset(
T.input(type="hidden", name="t", value="upload"), T.input(type="hidden", name="t", value="upload"),
T.input(type='hidden', name='when_done', value=done_url), T.input(type='hidden', name='when_done', value=done_url),
T.legend(class_="freeform-form-label")["Overwrite"], T.legend("Overwrite", class_="freeform-form-label"),
"Upload new contents: ", "Upload new contents: ",
T.input(type="file", name="file"), T.input(type="file", name="file"),
" ", " ",
T.input(type="submit", value="Replace Contents") T.input(type="submit", value="Replace Contents")
]] ))
return ctx.tag[overwrite] return tag(overwrite)
def render_is_directory(self, ctx, data): @renderer
def is_directory(self, req, tag):
node = self.original node = self.original
if IDirectoryNode.providedBy(node): if IDirectoryNode.providedBy(node):
return ctx.tag return tag
return "" return ""
def render_deep_check_form(self, ctx, data): @renderer
def deep_check_form(self, req, tag):
ophandle = base32.b2a(os.urandom(16)) ophandle = base32.b2a(os.urandom(16))
deep_check = T.form(action=".", method="post", deep_check = T.form(action=".", method="post",
enctype="multipart/form-data")[ enctype="multipart/form-data")(
T.fieldset[ T.fieldset(
T.input(type="hidden", name="t", value="start-deep-check"), T.input(type="hidden", name="t", value="start-deep-check"),
T.input(type="hidden", name="return_to", value="."), T.input(type="hidden", name="return_to", value="."),
T.legend(class_="freeform-form-label")["Run a deep-check operation (EXPENSIVE)"], T.legend("Run a deep-check operation (EXPENSIVE)", class_="freeform-form-label"),
T.div[ T.div(
"Verify every bit? (EVEN MORE EXPENSIVE):", "Verify every bit? (EVEN MORE EXPENSIVE):",
T.input(type="checkbox", name="verify"), T.input(type="checkbox", name="verify"),
], ),
T.div["Repair any problems?: ", T.div("Repair any problems?: ",
T.input(type="checkbox", name="repair")], T.input(type="checkbox", name="repair")),
T.div["Add/renew lease on all shares?: ", T.div("Add/renew lease on all shares?: ",
T.input(type="checkbox", name="add-lease")], T.input(type="checkbox", name="add-lease")),
T.div["Emit results in JSON format?: ", T.div("Emit results in JSON format?: ",
T.input(type="checkbox", name="output", value="JSON")], T.input(type="checkbox", name="output", value="JSON")),
T.input(type="hidden", name="ophandle", value=ophandle), T.input(type="hidden", name="ophandle", value=ophandle),
T.input(type="submit", value="Deep-Check"), T.input(type="submit", value="Deep-Check"),
]] ))
return ctx.tag[deep_check] return tag(deep_check)
def render_deep_size_form(self, ctx, data): @renderer
def deep_size_form(self, req, tag):
ophandle = base32.b2a(os.urandom(16)) ophandle = base32.b2a(os.urandom(16))
deep_size = T.form(action=".", method="post", deep_size = T.form(action=".", method="post",
enctype="multipart/form-data")[ enctype="multipart/form-data")(
T.fieldset[ T.fieldset(
T.input(type="hidden", name="t", value="start-deep-size"), T.input(type="hidden", name="t", value="start-deep-size"),
T.legend(class_="freeform-form-label")["Run a deep-size operation (EXPENSIVE)"], T.legend("Run a deep-size operation (EXPENSIVE)", class_="freeform-form-label"),
T.input(type="hidden", name="ophandle", value=ophandle), T.input(type="hidden", name="ophandle", value=ophandle),
T.input(type="submit", value="Deep-Size"), T.input(type="submit", value="Deep-Size"),
]] ))
return ctx.tag[deep_size] return tag(deep_size)
def render_deep_stats_form(self, ctx, data): @renderer
def deep_stats_form(self, req, tag):
ophandle = base32.b2a(os.urandom(16)) ophandle = base32.b2a(os.urandom(16))
deep_stats = T.form(action=".", method="post", deep_stats = T.form(action=".", method="post",
enctype="multipart/form-data")[ enctype="multipart/form-data")(
T.fieldset[ T.fieldset(
T.input(type="hidden", name="t", value="start-deep-stats"), T.input(type="hidden", name="t", value="start-deep-stats"),
T.legend(class_="freeform-form-label")["Run a deep-stats operation (EXPENSIVE)"], T.legend("Run a deep-stats operation (EXPENSIVE)", class_="freeform-form-label"),
T.input(type="hidden", name="ophandle", value=ophandle), T.input(type="hidden", name="ophandle", value=ophandle),
T.input(type="submit", value="Deep-Stats"), T.input(type="submit", value="Deep-Stats"),
]] ))
return ctx.tag[deep_stats] return tag(deep_stats)
def render_manifest_form(self, ctx, data): @renderer
def manifest_form(self, req, tag):
ophandle = base32.b2a(os.urandom(16)) ophandle = base32.b2a(os.urandom(16))
manifest = T.form(action=".", method="post", manifest = T.form(action=".", method="post",
enctype="multipart/form-data")[ enctype="multipart/form-data")(
T.fieldset[ T.fieldset(
T.input(type="hidden", name="t", value="start-manifest"), T.input(type="hidden", name="t", value="start-manifest"),
T.legend(class_="freeform-form-label")["Run a manifest operation (EXPENSIVE)"], T.legend("Run a manifest operation (EXPENSIVE)", class_="freeform-form-label"),
T.div["Output Format: ", T.div("Output Format: ",
T.select(name="output") T.select(name="output")
[ T.option(value="html", selected="true")["HTML"], ( T.option("HTML", value="html", selected="true"),
T.option(value="text")["text"], T.option("text", value="text"),
T.option(value="json")["JSON"], T.option("JSON", value="json"),
], ),
], ),
T.input(type="hidden", name="ophandle", value=ophandle), T.input(type="hidden", name="ophandle", value=ophandle),
T.input(type="submit", value="Manifest"), T.input(type="submit", value="Manifest"),
]] ))
return ctx.tag[manifest] return tag(manifest)
# TODO: edge metadata # TODO: edge metadata

View File

@ -1,67 +1,67 @@
<html xmlns:n="http://nevow.com/ns/nevow/0.1"><head> <html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"><head>
<title n:render="title"></title> <title t:render="title" />
<link href="/tahoe.css" rel="stylesheet" type="text/css"/> <link href="/tahoe.css" rel="stylesheet" type="text/css"/>
<link href="/icon.png" rel="shortcut icon" /> <link href="/icon.png" rel="shortcut icon" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head><body> </head><body>
<h1 n:render="header"></h1> <h1 t:render="header"></h1>
<ul> <ul>
<li>Object Type: <span n:render="type" /></li> <li>Object Type: <span t:render="type" /></li>
<li>Storage Index: <tt n:render="si" /></li> <li>Storage Index: <tt t:render="si" /></li>
<li>Object Size: <span n:render="size" /></li> <li>Object Size: <span t:render="size" /></li>
<li>Access Caps (Tahoe-URIs): <li>Access Caps (Tahoe-URIs):
<table class="table-headings-left"> <table class="table-headings-left">
<span n:render="is_directory"> <span t:render="is_directory">
<tr> <tr>
<th>Directory writecap</th> <th>Directory writecap</th>
<td><tt class="data-chars" n:render="directory_writecap" /></td> <td><tt class="data-chars" t:render="directory_writecap" /></td>
</tr> </tr>
<tr> <tr>
<th>Directory readcap</th> <th>Directory readcap</th>
<td><tt class="data-chars" n:render="directory_readcap" /></td> <td><tt class="data-chars" t:render="directory_readcap" /></td>
</tr> </tr>
<tr> <tr>
<th>Directory verifycap</th> <th>Directory verifycap</th>
<td><tt class="data-chars" n:render="directory_verifycap" /></td> <td><tt class="data-chars" t:render="directory_verifycap" /></td>
</tr> </tr>
</span> </span>
<tr> <tr>
<th>File writecap</th> <th>File writecap</th>
<td><tt class="data-chars" n:render="file_writecap" /></td> <td><tt class="data-chars" t:render="file_writecap" /></td>
</tr> </tr>
<tr> <tr>
<th>File readcap</th> <th>File readcap</th>
<td><tt class="data-chars" n:render="file_readcap" /></td> <td><tt class="data-chars" t:render="file_readcap" /></td>
</tr> </tr>
<tr> <tr>
<th>File verifycap</th> <th>File verifycap</th>
<td><tt class="data-chars" n:render="file_verifycap" /></td> <td><tt class="data-chars" t:render="file_verifycap" /></td>
</tr> </tr>
</table></li> </table></li>
<li><a href="?t=json">JSON</a></li> <li><a href="?t=json">JSON</a></li>
<li n:render="raw_link" /> <li t:render="raw_link" />
</ul> </ul>
<div n:render="is_checkable"> <div t:render="is_checkable">
<h2>Checker Operations</h2> <h2>Checker Operations</h2>
<div n:render="check_form" /> <div t:render="check_form" />
</div> </div>
<div n:render="is_mutable_file"> <div t:render="is_mutable_file">
<h2>Mutable File Operations</h2> <h2>Mutable File Operations</h2>
<div n:render="overwrite_form" /> <div t:render="overwrite_form" />
</div> </div>
<div n:render="is_directory"> <div t:render="is_directory">
<h2>Directory Operations</h2> <h2>Directory Operations</h2>
<div n:render="deep_check_form" /> <div t:render="deep_check_form" />
<div n:render="deep_size_form" /> <div t:render="deep_size_form" />
<div n:render="deep_stats_form" /> <div t:render="deep_stats_form" />
<div n:render="manifest_form" /> <div t:render="manifest_form" />
</div> </div>
</body></html> </body></html>