mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 13:33:09 +00:00
web: when a dirnode can't be read, emit a regular HTML page but with the child-table and upload-forms replaced with an apologetic message. Make sure to include the 'get info' links so the user can do a filecheck
This commit is contained in:
parent
badd79671c
commit
950200fece
@ -23,7 +23,7 @@ from allmydata.web.common import text_plain, WebError, \
|
||||
IOpHandleTable, NeedOperationHandleError, \
|
||||
boolean_of_arg, get_arg, get_root, \
|
||||
should_create_intermediate_directories, \
|
||||
getxmlfile, RenderMixin
|
||||
getxmlfile, RenderMixin, humanize_failure
|
||||
from allmydata.web.filenode import ReplaceMeMixin, \
|
||||
FileNodeHandler, PlaceHolderNodeHandler
|
||||
from allmydata.web.check_results import CheckResults, \
|
||||
@ -492,6 +492,37 @@ class DirectoryAsHTML(rend.Page):
|
||||
rend.Page.__init__(self)
|
||||
self.node = node
|
||||
|
||||
def beforeRender(self, ctx):
|
||||
# attempt to get the dirnode's children, stashing them (or the
|
||||
# failure that results) for later use
|
||||
d = self.node.list()
|
||||
def _good(children):
|
||||
# Deferreds don't optimize out tail recursion, and the way
|
||||
# Nevow's flattener handles Deferreds doesn't take this into
|
||||
# account. As a result, large lists of Deferreds that fire in the
|
||||
# same turn (i.e. the output of defer.succeed) will cause a stack
|
||||
# overflow. To work around this, we insert a turn break after
|
||||
# every 100 items, using foolscap's fireEventually(). This gives
|
||||
# the stack a chance to be popped. It would also work to put
|
||||
# every item in its own turn, but that'd be a lot more
|
||||
# inefficient. This addresses ticket #237, for which I was never
|
||||
# able to create a failing unit test.
|
||||
output = []
|
||||
for i,item in enumerate(sorted(children.items())):
|
||||
if i % 100 == 0:
|
||||
output.append(fireEventually(item))
|
||||
else:
|
||||
output.append(item)
|
||||
self.dirnode_children = output
|
||||
return ctx
|
||||
def _bad(f):
|
||||
text, code = humanize_failure(f)
|
||||
self.dirnode_children = None
|
||||
self.dirnode_children_error = text
|
||||
return ctx
|
||||
d.addCallbacks(_good, _bad)
|
||||
return d
|
||||
|
||||
def render_title(self, ctx, data):
|
||||
si_s = abbreviated_dirnode(self.node)
|
||||
header = ["Directory SI=%s" % si_s]
|
||||
@ -516,29 +547,17 @@ class DirectoryAsHTML(rend.Page):
|
||||
uri_link = "%s/uri/%s/" % (root, urllib.quote(rocap))
|
||||
return ctx.tag[T.a(href=uri_link)["Read-Only Version"]]
|
||||
|
||||
def data_children(self, ctx, data):
|
||||
d = self.node.list()
|
||||
d.addCallback(lambda dict: sorted(dict.items()))
|
||||
def _stall_some(items):
|
||||
# Deferreds don't optimize out tail recursion, and the way
|
||||
# Nevow's flattener handles Deferreds doesn't take this into
|
||||
# account. As a result, large lists of Deferreds that fire in the
|
||||
# same turn (i.e. the output of defer.succeed) will cause a stack
|
||||
# overflow. To work around this, we insert a turn break after
|
||||
# every 100 items, using foolscap's fireEventually(). This gives
|
||||
# the stack a chance to be popped. It would also work to put
|
||||
# every item in its own turn, but that'd be a lot more
|
||||
# inefficient. This addresses ticket #237, for which I was never
|
||||
# able to create a failing unit test.
|
||||
output = []
|
||||
for i,item in enumerate(items):
|
||||
if i % 100 == 0:
|
||||
output.append(fireEventually(item))
|
||||
def render_try_children(self, ctx, data):
|
||||
# if the dirnode can be retrived, render a table of children.
|
||||
# Otherwise, render an apologetic error message.
|
||||
if self.dirnode_children:
|
||||
return ctx.tag
|
||||
else:
|
||||
output.append(item)
|
||||
return output
|
||||
d.addCallback(_stall_some)
|
||||
return d
|
||||
return T.div[T.p["Error reading directory:"],
|
||||
T.p[self.dirnode_children_error]]
|
||||
|
||||
def data_children(self, ctx, data):
|
||||
return self.dirnode_children
|
||||
|
||||
def render_row(self, ctx, data):
|
||||
name, (target, metadata) = data
|
||||
@ -638,8 +657,9 @@ class DirectoryAsHTML(rend.Page):
|
||||
forms = []
|
||||
|
||||
if self.node.is_readonly():
|
||||
forms.append(T.div["No upload forms: directory is read-only"])
|
||||
return forms
|
||||
return T.div["No upload forms: directory is read-only"]
|
||||
if not self.dirnode_children:
|
||||
return T.div["No upload forms: directory is unreadable"]
|
||||
|
||||
mkdir = T.form(action=".", method="post",
|
||||
enctype="multipart/form-data")[
|
||||
|
@ -17,7 +17,7 @@
|
||||
<div><a href="?t=info">More info on this directory</a></div>
|
||||
<div n:render="show_readonly" />
|
||||
|
||||
<div>
|
||||
<div n:render="try_children">
|
||||
<table n:render="sequence" n:data="children" border="1">
|
||||
<tr n:pattern="header">
|
||||
<td>Filename</td>
|
||||
|
Loading…
Reference in New Issue
Block a user