From 65cd0e8ecd22f4227f30019fb9e7d11e2f7eeee7 Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 11 May 2020 10:38:15 -0400 Subject: [PATCH 01/10] Reformat publish status template page --- src/allmydata/web/publish-status.xhtml | 79 ++++++++++++++------------ 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/allmydata/web/publish-status.xhtml b/src/allmydata/web/publish-status.xhtml index 4204de8e2..2c676493f 100644 --- a/src/allmydata/web/publish-status.xhtml +++ b/src/allmydata/web/publish-status.xhtml @@ -1,51 +1,56 @@ + Tahoe-LAFS - Mutable File Publish Status + -

Mutable File Publish Status

+

Mutable File Publish Status

- - -

Publish Results

- -
Return to the Welcome Page
+

Publish Results

- + + +
Return to the Welcome Page
+ + + + From 89c42100907956c3c6189c3905a133274db84cd3 Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 11 May 2020 10:40:48 -0400 Subject: [PATCH 02/10] Use twisted tags in publish status template page --- src/allmydata/web/publish-status.xhtml | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/allmydata/web/publish-status.xhtml b/src/allmydata/web/publish-status.xhtml index 2c676493f..49f5bb08c 100644 --- a/src/allmydata/web/publish-status.xhtml +++ b/src/allmydata/web/publish-status.xhtml @@ -1,4 +1,4 @@ - + Tahoe-LAFS - Mutable File Publish Status @@ -12,40 +12,40 @@

Mutable File Publish Status

Publish Results

From fdf6449ba8bcff3d1da1283fcd4d12ccf57f4aff Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 11 May 2020 11:24:56 -0400 Subject: [PATCH 03/10] Use MultiFormatResource to implement PublishStatusPage --- src/allmydata/web/status.py | 190 ++++++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 72 deletions(-) diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py index bc0d69d77..225f30193 100644 --- a/src/allmydata/web/status.py +++ b/src/allmydata/web/status.py @@ -759,114 +759,160 @@ class RetrieveStatusPage(rend.Page, RateAndTimeMixin): return T.li["Per-Server Fetch Response Times: ", l] -class PublishStatusPage(rend.Page, RateAndTimeMixin): +class PublishStatusPage(MultiFormatResource): + docFactory = getxmlfile("publish-status.xhtml") - def __init__(self, data): - rend.Page.__init__(self, data) - self.publish_status = data + def __init__(self, publish_status): + super(PublishStatusPage, self).__init__() + self._publish_status = publish_status - def render_started(self, ctx, data): - started_s = render_time(data.get_started()) - return started_s + def render_HTML(self, req): + elem = PublishStatusElement(self._publish_status); + return renderElement(req, elem) - def render_si(self, ctx, data): - si_s = base32.b2a_or_none(data.get_storage_index()) + +class PublishStatusElement(Element, RateAndTimeMixin): + + loader = XMLFile(FilePath(__file__).sibling("publish-status.xhtml")) + + def __init__(self, publish_status): + super(PublishStatusElement, self).__init__() + self._publish_status = publish_status + + @renderer + def started(self, req, tag): + started_s = render_time(self._publish_status.get_started()) + return tag(started_s) + + @renderer + def si(self, req, tag): + si_s = base32.b2a_or_none(self._publish_status.get_storage_index()) if si_s is None: si_s = "(None)" - return si_s + return tag(str(si_s)) - def render_helper(self, ctx, data): - return {True: "Yes", - False: "No"}[data.using_helper()] + @renderer + def helper(self, req, tag): + return tag({True: "Yes", + False: "No"}[self._publish_status.using_helper()]) - def render_current_size(self, ctx, data): - size = data.get_size() + @renderer + def current_size(self, req, tag): + size = self._publish_status.get_size() if size is None: size = "(unknown)" - return size + return tag(str(size)) - def render_progress(self, ctx, data): - progress = data.get_progress() + @renderer + def progress(self, req, tag): + progress = self._publish_status.get_progress() # TODO: make an ascii-art bar - return "%.1f%%" % (100.0 * progress) + return tag("%.1f%%" % (100.0 * progress)) - def render_status(self, ctx, data): - return data.get_status() + @renderer + def status(self, req, tag): + return tag(self._publish_status.get_status()) - def render_encoding(self, ctx, data): - k, n = data.get_encoding() - return ctx.tag["Encoding: %s of %s" % (k, n)] + @renderer + def encoding(self, req, tag): + k, n = self._publish_status.get_encoding() + return tag("Encoding: %s of %s" % (k, n)) - def render_sharemap(self, ctx, data): - servermap = data.get_servermap() + @renderer + def sharemap(self, req, tag): + servermap = self._publish_status.get_servermap() if servermap is None: - return ctx.tag["None"] - l = T.ul() + return tag("None") + l = tags.ul() sharemap = servermap.make_sharemap() for shnum in sorted(sharemap.keys()): - l[T.li["%d -> Placed on " % shnum, - ", ".join(["[%s]" % server.get_name() - for server in sharemap[shnum]])]] - return ctx.tag["Sharemap:", l] + l(tags.li("%d -> Placed on " % shnum, + ", ".join(["[%s]" % server.get_name() + for server in sharemap[shnum]]))) + return tag("Sharemap:", l) - def render_problems(self, ctx, data): - problems = data.get_problems() + @renderer + def problems(self, req, tag): + problems = self._publish_status.get_problems() if not problems: - return "" - l = T.ul() + return tag() + l = tags.ul() # XXX: is this exercised? I don't think PublishStatus.problems is # ever populated for peerid in sorted(problems.keys()): peerid_s = idlib.shortnodeid_b2a(peerid) - l[T.li["[%s]: %s" % (peerid_s, problems[peerid])]] - return ctx.tag["Server Problems:", l] + l(tags.li("[%s]: %s" % (peerid_s, problems[peerid]))) + return tag("Server Problems:", l) - def _get_rate(self, data, name): - file_size = self.publish_status.get_size() - duration = self.publish_status.timings.get(name) - return compute_rate(file_size, duration) + def _get_rate(self, name): + file_size = self._publish_status.get_size() + duration = self._publish_status.timings.get(name) + return str(compute_rate(file_size, duration)) - def data_time_total(self, ctx, data): - return self.publish_status.timings.get("total") - def data_rate_total(self, ctx, data): - return self._get_rate(data, "total") + def _get_time(self, name): + return str(self._publish_status.timings.get(name)) - def data_time_setup(self, ctx, data): - return self.publish_status.timings.get("setup") + @renderer + def time_total(self, req, tag): + return tag(self._get_time("total")) - def data_time_encrypt(self, ctx, data): - return self.publish_status.timings.get("encrypt") - def data_rate_encrypt(self, ctx, data): - return self._get_rate(data, "encrypt") + @renderer + def rate_total(self, req, tag): + return tag(self._get_rate("total")) - def data_time_encode(self, ctx, data): - return self.publish_status.timings.get("encode") - def data_rate_encode(self, ctx, data): - return self._get_rate(data, "encode") + @renderer + def time_setup(self, req, tag): + return tag(self._get_time("setup")) - def data_time_pack(self, ctx, data): - return self.publish_status.timings.get("pack") - def data_rate_pack(self, ctx, data): - return self._get_rate(data, "pack") - def data_time_sign(self, ctx, data): - return self.publish_status.timings.get("sign") + @renderer + def time_encrypt(self, req, tag): + return tag(self._get_time("encrypt")) - def data_time_push(self, ctx, data): - return self.publish_status.timings.get("push") - def data_rate_push(self, ctx, data): - return self._get_rate(data, "push") + @renderer + def rate_encrypt(self, req, tag): + return tag(self._get_rate("encrypt")) - def render_server_timings(self, ctx, data): - per_server = self.publish_status.timings.get("send_per_server") + @renderer + def time_encode(self, req, tag): + return tag(self._get_time("encode")) + + @renderer + def rate_encode(self, req, tag): + return tag(self._get_rate("encode")) + + @renderer + def time_pack(self, req, tag): + return tag(self._get_time("pack")) + + @renderer + def rate_pack(self, req, tag): + return tag(self._get_rate("pack")) + + @renderer + def time_sign(self, req, tag): + return tag(self._get_time("sign")) + + @renderer + def time_push(self, req, tag): + return tag(self._get_time("push")) + + @renderer + def rate_push(self, req, tag): + return self._get_rate("push") + + @renderer + def server_timings(self, req, tag): + per_server = self._publish_status.timings.get("send_per_server") if not per_server: - return "" - l = T.ul() + return tag() + l = tags.ul() for server in sorted(per_server.keys(), key=lambda s: s.get_name()): times_s = ", ".join([self.render_time(None, t) for t in per_server[server]]) - l[T.li["[%s]: %s" % (server.get_name(), times_s)]] - return T.li["Per-Server Response Times: ", l] + l(tags.li("[%s]: %s" % (server.get_name(), times_s))) + return tags.li("Per-Server Response Times: ", l) + class MapupdateStatusPage(rend.Page, RateAndTimeMixin): docFactory = getxmlfile("map-update-status.xhtml") From 0fba615afb192c04e23e47e821abc3e58b57d665 Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 11 May 2020 11:28:01 -0400 Subject: [PATCH 04/10] Remove RateAndTimeMixin from PublishStatusPage --- src/allmydata/web/status.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py index 225f30193..07585435a 100644 --- a/src/allmydata/web/status.py +++ b/src/allmydata/web/status.py @@ -772,7 +772,7 @@ class PublishStatusPage(MultiFormatResource): return renderElement(req, elem) -class PublishStatusElement(Element, RateAndTimeMixin): +class PublishStatusElement(Element): loader = XMLFile(FilePath(__file__).sibling("publish-status.xhtml")) @@ -908,7 +908,7 @@ class PublishStatusElement(Element, RateAndTimeMixin): return tag() l = tags.ul() for server in sorted(per_server.keys(), key=lambda s: s.get_name()): - times_s = ", ".join([self.render_time(None, t) + times_s = ", ".join([abbreviate_time(t) for t in per_server[server]]) l(tags.li("[%s]: %s" % (server.get_name(), times_s))) return tags.li("Per-Server Response Times: ", l) From 9e200fc0141615de83f33b681b8644fbe59f7a9d Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 11 May 2020 11:34:57 -0400 Subject: [PATCH 05/10] Render publish problems only when there are problems --- src/allmydata/web/publish-status.xhtml | 2 +- src/allmydata/web/status.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/allmydata/web/publish-status.xhtml b/src/allmydata/web/publish-status.xhtml index 49f5bb08c..1949230c2 100644 --- a/src/allmydata/web/publish-status.xhtml +++ b/src/allmydata/web/publish-status.xhtml @@ -24,7 +24,7 @@
  • -
  • +
  • Timings:
    • diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py index 07585435a..70edbc4c9 100644 --- a/src/allmydata/web/status.py +++ b/src/allmydata/web/status.py @@ -843,7 +843,7 @@ class PublishStatusElement(Element): for peerid in sorted(problems.keys()): peerid_s = idlib.shortnodeid_b2a(peerid) l(tags.li("[%s]: %s" % (peerid_s, problems[peerid]))) - return tag("Server Problems:", l) + return tag(tags.li("Server Problems:", l)) def _get_rate(self, name): file_size = self._publish_status.get_size() From a4bc31a13798c66f0ef082355f14d8eefdffcf6d Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 11 May 2020 11:42:30 -0400 Subject: [PATCH 06/10] Add newsfragment --- newsfragments/3289.minor | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 newsfragments/3289.minor diff --git a/newsfragments/3289.minor b/newsfragments/3289.minor new file mode 100644 index 000000000..e69de29bb From 0ae045ea166651c122f92e7c169e501f339845a4 Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 11 May 2020 12:47:48 -0400 Subject: [PATCH 07/10] Add comments to PublishStatusPage --- src/allmydata/web/status.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py index 70edbc4c9..7e05a2677 100644 --- a/src/allmydata/web/status.py +++ b/src/allmydata/web/status.py @@ -759,11 +759,13 @@ class RetrieveStatusPage(rend.Page, RateAndTimeMixin): return T.li["Per-Server Fetch Response Times: ", l] +# Renders "status/publish-%n" class PublishStatusPage(MultiFormatResource): - docFactory = getxmlfile("publish-status.xhtml") - def __init__(self, publish_status): + """ + :publish_status mutable.publish.PublishStatus: publish stats provider. + """ super(PublishStatusPage, self).__init__() self._publish_status = publish_status From 2e0e210c14fd533bf5fa477e3a385b5876a53c5a Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Wed, 13 May 2020 17:43:55 -0400 Subject: [PATCH 08/10] Make PublishStatusPage comment a docstring --- src/allmydata/web/status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py index 7e05a2677..203b73fd6 100644 --- a/src/allmydata/web/status.py +++ b/src/allmydata/web/status.py @@ -759,8 +759,8 @@ class RetrieveStatusPage(rend.Page, RateAndTimeMixin): return T.li["Per-Server Fetch Response Times: ", l] -# Renders "status/publish-%n" class PublishStatusPage(MultiFormatResource): + """Renders status/publish-%d.""" def __init__(self, publish_status): """ From ebe80221d59208620c4c2ddcf397a89069ed2a3f Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Wed, 13 May 2020 17:44:50 -0400 Subject: [PATCH 09/10] Add missing "param:" to init method docstring --- src/allmydata/web/status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py index 203b73fd6..68c5d5341 100644 --- a/src/allmydata/web/status.py +++ b/src/allmydata/web/status.py @@ -764,7 +764,7 @@ class PublishStatusPage(MultiFormatResource): def __init__(self, publish_status): """ - :publish_status mutable.publish.PublishStatus: publish stats provider. + :param publish_status mutable.publish.PublishStatus: stats provider. """ super(PublishStatusPage, self).__init__() self._publish_status = publish_status From 79a44eac33ded8088ec58840fb8e87a54dfc7c5f Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Wed, 13 May 2020 19:29:41 -0400 Subject: [PATCH 10/10] Correct docstring to ":param " format --- src/allmydata/web/status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py index 68c5d5341..0217978d3 100644 --- a/src/allmydata/web/status.py +++ b/src/allmydata/web/status.py @@ -764,7 +764,7 @@ class PublishStatusPage(MultiFormatResource): def __init__(self, publish_status): """ - :param publish_status mutable.publish.PublishStatus: stats provider. + :param mutable.publish.PublishStatus publish_status: stats provider. """ super(PublishStatusPage, self).__init__() self._publish_status = publish_status