mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-19 03:06:33 +00:00
port manifest to twisted.web.template
This commit is contained in:
parent
4a73f8055c
commit
7ccfe44be6
@ -965,8 +965,121 @@ class RenameForm(rend.Page):
|
|||||||
ctx.tag.attributes['value'] = name
|
ctx.tag.attributes['value'] = name
|
||||||
return ctx.tag
|
return ctx.tag
|
||||||
|
|
||||||
class ManifestResults(MultiFormatPage, ReloadMixin):
|
|
||||||
docFactory = getxmlfile("manifest.xhtml")
|
class ReloadableMonitorElement(Element, object):
|
||||||
|
"""
|
||||||
|
Like 'ReloadMixin', but for twisted.web.template style. This
|
||||||
|
provides renderers for "reload" and "refesh" and a self.monitor
|
||||||
|
attribute
|
||||||
|
"""
|
||||||
|
refresh_time = 60 # 1 minute
|
||||||
|
|
||||||
|
def __init__(self, monitor):
|
||||||
|
self.monitor = monitor
|
||||||
|
super(ReloadableMonitorElement, self).__init__()
|
||||||
|
|
||||||
|
@renderer
|
||||||
|
def refresh(self, req, tag):
|
||||||
|
if self.monitor.is_finished():
|
||||||
|
return ""
|
||||||
|
tag.attributes["http-equiv"] = "refresh"
|
||||||
|
tag.attributes["content"] = str(self.refresh_time)
|
||||||
|
return tag
|
||||||
|
|
||||||
|
@renderer
|
||||||
|
def reload(self, req, tag):
|
||||||
|
if self.monitor.is_finished():
|
||||||
|
return ""
|
||||||
|
# url.gethere would break a proxy, so the correct thing to do is
|
||||||
|
# req.path[-1] + queryargs
|
||||||
|
ophandle = req.prepath[-1]
|
||||||
|
reload_target = ophandle + "?output=html"
|
||||||
|
cancel_target = ophandle + "?t=cancel"
|
||||||
|
cancel_button = tags.form(
|
||||||
|
[
|
||||||
|
tags.input(type="submit", value="Cancel"),
|
||||||
|
],
|
||||||
|
action=cancel_target,
|
||||||
|
method="POST",
|
||||||
|
enctype="multipart/form-data",
|
||||||
|
)
|
||||||
|
|
||||||
|
return tag([
|
||||||
|
"Operation still running: ",
|
||||||
|
tags.a("Reload", href=reload_target),
|
||||||
|
cancel_button,
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def _slashify_path(path):
|
||||||
|
"""
|
||||||
|
Converts a tuple from a 'manifest' path into a string with slashes
|
||||||
|
in it
|
||||||
|
"""
|
||||||
|
if not path:
|
||||||
|
return ""
|
||||||
|
return "/".join([p.encode("utf-8") for p in path])
|
||||||
|
|
||||||
|
|
||||||
|
def _cap_to_link(root, path, cap):
|
||||||
|
"""
|
||||||
|
Turns a capability-string into a WebAPI link tag
|
||||||
|
|
||||||
|
:param root: the root piece of the URI
|
||||||
|
|
||||||
|
:param cap: the capability-string
|
||||||
|
|
||||||
|
:returns: tags.a instance
|
||||||
|
"""
|
||||||
|
# TODO: we need a clean consistent way to get the type of a cap string
|
||||||
|
if cap:
|
||||||
|
if cap.startswith("URI:CHK") or cap.startswith("URI:SSK"):
|
||||||
|
nameurl = urllib.quote(path[-1].encode("utf-8"))
|
||||||
|
uri_link = "%s/file/%s/@@named=/%s" % (root, urllib.quote(cap),
|
||||||
|
nameurl)
|
||||||
|
else:
|
||||||
|
uri_link = "%s/uri/%s" % (root, urllib.quote(cap, safe=""))
|
||||||
|
return tags.a(cap, href=uri_link)
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class ManifestElement(ReloadableMonitorElement):
|
||||||
|
loader = XMLFile(FilePath(__file__).sibling("manifest.xhtml"))
|
||||||
|
|
||||||
|
def _si_abbrev(self):
|
||||||
|
si = self.monitor.origin_si
|
||||||
|
if not si:
|
||||||
|
return "<LIT>"
|
||||||
|
return base32.b2a(si)[:6]
|
||||||
|
|
||||||
|
@renderer
|
||||||
|
def title(self, req, tag):
|
||||||
|
return tag(
|
||||||
|
"Manifest of SI={}".format(self._si_abbrev())
|
||||||
|
)
|
||||||
|
|
||||||
|
@renderer
|
||||||
|
def header(self, req, tag):
|
||||||
|
return tag(
|
||||||
|
"Manifest of SI={}".format(self._si_abbrev())
|
||||||
|
)
|
||||||
|
|
||||||
|
@renderer
|
||||||
|
def items(self, req, tag):
|
||||||
|
manifest = self.monitor.get_status()["manifest"]
|
||||||
|
root = get_root(req)
|
||||||
|
rows = [
|
||||||
|
{
|
||||||
|
"path": _slashify_path(path),
|
||||||
|
"cap": _cap_to_link(root, path, cap),
|
||||||
|
}
|
||||||
|
for path, cap in manifest
|
||||||
|
]
|
||||||
|
return SlotsSequenceElement(tag, rows)
|
||||||
|
|
||||||
|
|
||||||
|
class ManifestResults(MultiFormatResource, ReloadMixin):
|
||||||
|
|
||||||
# Control MultiFormatPage
|
# Control MultiFormatPage
|
||||||
formatArgument = "output"
|
formatArgument = "output"
|
||||||
@ -979,18 +1092,19 @@ class ManifestResults(MultiFormatPage, ReloadMixin):
|
|||||||
# The default format is HTML but the HTML renderer is just renderHTTP.
|
# The default format is HTML but the HTML renderer is just renderHTTP.
|
||||||
render_HTML = None
|
render_HTML = None
|
||||||
|
|
||||||
def slashify_path(self, path):
|
def render_HTML(self, req):
|
||||||
if not path:
|
return renderElement(
|
||||||
return ""
|
req,
|
||||||
return "/".join([p.encode("utf-8") for p in path])
|
ManifestElement(self.monitor)
|
||||||
|
)
|
||||||
|
|
||||||
def render_TEXT(self, req):
|
def render_TEXT(self, req):
|
||||||
req.setHeader("content-type", "text/plain")
|
req.setHeader("content-type", "text/plain")
|
||||||
lines = []
|
lines = []
|
||||||
is_finished = self.monitor.is_finished()
|
is_finished = self.monitor.is_finished()
|
||||||
lines.append("finished: " + {True: "yes", False: "no"}[is_finished])
|
lines.append("finished: " + {True: "yes", False: "no"}[is_finished])
|
||||||
for (path, cap) in self.monitor.get_status()["manifest"]:
|
for path, cap in self.monitor.get_status()["manifest"]:
|
||||||
lines.append(self.slashify_path(path) + " " + cap)
|
lines.append(_slashify_path(path) + " " + cap)
|
||||||
return "\n".join(lines) + "\n"
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
def render_JSON(self, req):
|
def render_JSON(self, req):
|
||||||
@ -1024,37 +1138,6 @@ class ManifestResults(MultiFormatPage, ReloadMixin):
|
|||||||
# CPU.
|
# CPU.
|
||||||
return json.dumps(status, indent=1)
|
return json.dumps(status, indent=1)
|
||||||
|
|
||||||
def _si_abbrev(self):
|
|
||||||
si = self.monitor.origin_si
|
|
||||||
if not si:
|
|
||||||
return "<LIT>"
|
|
||||||
return base32.b2a(si)[:6]
|
|
||||||
|
|
||||||
def render_title(self, ctx):
|
|
||||||
return T.title["Manifest of SI=%s" % self._si_abbrev()]
|
|
||||||
|
|
||||||
def render_header(self, ctx):
|
|
||||||
return T.p["Manifest of SI=%s" % self._si_abbrev()]
|
|
||||||
|
|
||||||
def data_items(self, ctx, data):
|
|
||||||
return self.monitor.get_status()["manifest"]
|
|
||||||
|
|
||||||
def render_row(self, ctx, path_cap):
|
|
||||||
path, cap = path_cap
|
|
||||||
ctx.fillSlots("path", self.slashify_path(path))
|
|
||||||
root = get_root(ctx)
|
|
||||||
# TODO: we need a clean consistent way to get the type of a cap string
|
|
||||||
if cap:
|
|
||||||
if cap.startswith("URI:CHK") or cap.startswith("URI:SSK"):
|
|
||||||
nameurl = urllib.quote(path[-1].encode("utf-8"))
|
|
||||||
uri_link = "%s/file/%s/@@named=/%s" % (root, urllib.quote(cap),
|
|
||||||
nameurl)
|
|
||||||
else:
|
|
||||||
uri_link = "%s/uri/%s" % (root, urllib.quote(cap, safe=""))
|
|
||||||
ctx.fillSlots("cap", T.a(href=uri_link)[cap])
|
|
||||||
else:
|
|
||||||
ctx.fillSlots("cap", "")
|
|
||||||
return ctx.tag
|
|
||||||
|
|
||||||
class DeepSizeResults(MultiFormatPage):
|
class DeepSizeResults(MultiFormatPage):
|
||||||
# Control MultiFormatPage
|
# Control MultiFormatPage
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
<html xmlns:n="http://nevow.com/ns/nevow/0.1">
|
<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">
|
||||||
<head>
|
<head>
|
||||||
<title n:render="title"></title>
|
<title t:render="title"></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" />
|
||||||
<meta n:render="refresh" />
|
<meta t:render="refresh" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<h1><p n:render="header"></p></h1>
|
<h1><p t:render="header"></p></h1>
|
||||||
|
|
||||||
<h2 n:render="reload" />
|
<h2 t:render="reload" />
|
||||||
|
|
||||||
<table n:render="sequence" n:data="items">
|
<table t:render="items">
|
||||||
<tr n:pattern="header">
|
<tr t:pattern="header">
|
||||||
<td>Path</td>
|
<td>Path</td>
|
||||||
<td>cap</td>
|
<td>cap</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr n:pattern="item" n:render="row">
|
<tr t:render="item">
|
||||||
<td><n:slot name="path"/></td>
|
<td><t:slot name="path"/></td>
|
||||||
<td><n:slot name="cap"/></td>
|
<td><t:slot name="cap"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr n:pattern="empty"><td>no items in the manifest!</td></tr>
|
<tr t:render="empty"><td>no items in the manifest!</td></tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user