from twisted.internet import address
from twisted.web import http
-from nevow import rend, url, loaders, tags as T
+from nevow import rend, url, tags as T
from nevow.inevow import IRequest
from nevow.static import File as nevow_File # TODO: merge with static.File?
from nevow.util import resource_filename
-from formless import webform
import allmydata # to display import path
from allmydata import get_package_versions_string
-from allmydata import provisioning
-from allmydata.util import idlib, log
+from allmydata.util import log
from allmydata.interfaces import IFileNode
from allmydata.web import filenode, directory, unlinked, status, operations
-from allmydata.web import reliability, storage
+from allmydata.web import storage
from allmydata.web.common import abbreviate_size, getxmlfile, WebError, \
- get_arg, RenderMixin, get_format, get_mutable_type
+ get_arg, RenderMixin, get_format, get_mutable_type, TIME_FORMAT
+from allmydata.util.time_format import format_delta
class URIHandler(RenderMixin, rend.Page):
details=get_arg(req, "details", ""),
level=log.WEIRD, umid="LkD9Pw")
req.setHeader("content-type", "text/plain")
- return "Thank you for your report!"
-
-class NoReliability(rend.Page):
- docFactory = loaders.xmlstr('''\
-<html xmlns:n="http://nevow.com/ns/nevow/0.1">
- <head>
- <title>AllMyData - Tahoe</title>
- <link href="/webform_css" rel="stylesheet" type="text/css"/>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- </head>
- <body>
- <h2>"Reliability" page not available</h2>
- <p>Please install the python "NumPy" module to enable this page.</p>
- </body>
-</html>
-''')
+ return "An incident report has been saved to logs/incidents/ in the node directory."
SPACE = u"\u00A0"*2
addSlash = True
docFactory = getxmlfile("welcome.xhtml")
- def __init__(self, client, clock=None):
+ def __init__(self, client, clock=None, now=None):
rend.Page.__init__(self, client)
self.client = client
# If set, clock is a twisted.internet.task.Clock that the tests
# use to test ophandle expiration.
self.child_operations = operations.OphandleTable(clock)
+ self.now = now
+ if self.now is None:
+ self.now = time.time
try:
s = client.getServiceNamed("storage")
except KeyError:
s = None
- self.child_storage = storage.StorageStatus(s)
+ self.child_storage = storage.StorageStatus(s, self.client.nickname)
self.child_uri = URIHandler(client)
self.child_cap = URIHandler(client)
# needs to created on each request
return status.HelperStatus(self.client.helper)
- child_provisioning = provisioning.ProvisioningTool()
- if reliability.is_available():
- child_reliability = reliability.ReliabilityTool()
- else:
- child_reliability = NoReliability()
-
child_report_incident = IncidentReporter()
#child_server # let's reserve this for storage-server-over-HTTP
# FIXME: This code is duplicated in root.py and introweb.py.
+ def data_rendered_at(self, ctx, data):
+ return time.strftime(TIME_FORMAT, time.localtime())
def data_version(self, ctx, data):
return get_package_versions_string()
def data_import_path(self, ctx, data):
return str(allmydata)
- def data_my_nodeid(self, ctx, data):
- return idlib.nodeid_b2a(self.client.nodeid)
+ def render_my_nodeid(self, ctx, data):
+ tubid_s = "TubID: "+self.client.get_long_tubid()
+ return T.td(title=tubid_s)[self.client.get_long_nodeid()]
def data_my_nickname(self, ctx, data):
return self.client.nickname
return ctx.tag[ul]
- def data_introducer_furl(self, ctx, data):
- return self.client.introducer_furl
+ def data_introducer_furl_prefix(self, ctx, data):
+ ifurl = self.client.introducer_furl
+ # trim off the secret swissnum
+ (prefix, _, swissnum) = ifurl.rpartition("/")
+ if not ifurl:
+ return None
+ if swissnum == "introducer":
+ return ifurl
+ else:
+ return "%s/[censored]" % (prefix,)
+
+ def data_introducer_description(self, ctx, data):
+ if self.data_connected_to_introducer(ctx, data) == "no":
+ return "Introducer not connected"
+ return "Introducer"
+
def data_connected_to_introducer(self, ctx, data):
if self.client.connected_to_introducer():
return "yes"
return "no"
- def data_helper_furl(self, ctx, data):
+ def data_helper_furl_prefix(self, ctx, data):
try:
uploader = self.client.getServiceNamed("uploader")
except KeyError:
return None
furl, connected = uploader.get_helper_info()
- return furl
+ if not furl:
+ return None
+ # trim off the secret swissnum
+ (prefix, _, swissnum) = furl.rpartition("/")
+ return "%s/[censored]" % (prefix,)
+
+ def data_helper_description(self, ctx, data):
+ if self.data_connected_to_helper(ctx, data) == "no":
+ return "Helper not connected"
+ return "Helper"
+
def data_connected_to_helper(self, ctx, data):
try:
uploader = self.client.getServiceNamed("uploader")
except KeyError:
return "no" # we don't even have an Uploader
furl, connected = uploader.get_helper_info()
+
+ if furl is None:
+ return "not-configured"
if connected:
return "yes"
return "no"
ctx.fillSlots("peerid", server.get_longname())
ctx.fillSlots("nickname", server.get_nickname())
rhost = server.get_remote_host()
- if rhost:
+ if server.is_connected():
if nodeid == self.client.nodeid:
rhost_s = "(loopback)"
elif isinstance(rhost, address.IPv4Address):
rhost_s = "%s:%d" % (rhost.host, rhost.port)
else:
rhost_s = str(rhost)
- connected = "Yes: to " + rhost_s
- since = server.get_last_connect_time()
+ addr = rhost_s
+ service_connection_status = "Connected"
+ service_connection_status_abs_time, service_connection_status_rel_time = format_delta(server.get_last_connect_time(), self.now())
else:
- connected = "No"
- since = server.get_last_loss_time()
- announced = server.get_announcement_time()
+ addr = "N/A"
+ service_connection_status = "Disconnected"
+ service_connection_status_abs_time, service_connection_status_rel_time = format_delta(server.get_last_loss_time(), self.now())
+
+ last_received_data_abs_time, last_received_data_rel_time = format_delta(server.get_last_received_data_time(), self.now())
+
announcement = server.get_announcement()
version = announcement["my-version"]
- service_name = announcement["service-name"]
-
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- ctx.fillSlots("connected", connected)
- ctx.fillSlots("connected-bool", bool(rhost))
- ctx.fillSlots("since", time.strftime(TIME_FORMAT,
- time.localtime(since)))
- ctx.fillSlots("announced", time.strftime(TIME_FORMAT,
- time.localtime(announced)))
+ available_space = server.get_available_space()
+ if available_space is None:
+ available_space = "N/A"
+ else:
+ available_space = abbreviate_size(available_space)
+ ctx.fillSlots("address", addr)
+ ctx.fillSlots("service_connection_status", service_connection_status)
+ ctx.fillSlots("service_connection_status_abs_time", service_connection_status_abs_time)
+ ctx.fillSlots("service_connection_status_rel_time", service_connection_status_rel_time)
+ ctx.fillSlots("last_received_data_abs_time", last_received_data_abs_time)
+ ctx.fillSlots("last_received_data_rel_time", last_received_data_rel_time)
ctx.fillSlots("version", version)
- ctx.fillSlots("service_name", service_name)
+ ctx.fillSlots("available_space", available_space)
return ctx.tag
form = T.form(action="report_incident", method="post",
enctype="multipart/form-data")[
T.fieldset[
- T.legend(class_="freeform-form-label")["Report an Incident"],
T.input(type="hidden", name="t", value="report-incident"),
- "What went wrong?:"+SPACE,
+ "What went wrong?"+SPACE,
T.input(type="text", name="details"), SPACE,
- T.input(type="submit", value="Report!"),
+ T.input(type="submit", value=u"Save \u00BB"),
]]
return T.div[form]