wui: use standard time format (#1077)

This commit is contained in:
Leif Ryge 2016-01-04 16:00:59 +00:00 committed by Daira Hopwood
parent 6d4a8bcd7f
commit 6226f6b497
7 changed files with 50 additions and 48 deletions

View File

@ -1006,6 +1006,21 @@ class TimeFormat(unittest.TestCase):
def test_parse_date(self):
self.failUnlessEqual(time_format.parse_date("2010-02-21"), 1266710400)
def test_format_time(self):
self.failUnlessEqual(time_format.format_time(time.gmtime(0)), '1970-01-01 00:00:00')
self.failUnlessEqual(time_format.format_time(time.gmtime(60)), '1970-01-01 00:01:00')
self.failUnlessEqual(time_format.format_time(time.gmtime(60*60)), '1970-01-01 01:00:00')
seconds_per_day = 60*60*24
leap_years_1970_to_2014_inclusive = ((2012 - 1968) // 4)
self.failUnlessEqual(time_format.format_time(time.gmtime(seconds_per_day*((2015 - 1970)*365+leap_years_1970_to_2014_inclusive))), '2015-01-01 00:00:00')
def test_format_time_y2038(self):
seconds_per_day = 60*60*24
leap_years_1970_to_2047_inclusive = ((2044 - 1968) // 4)
self.failUnlessEqual(time_format.format_time(time.gmtime(seconds_per_day*((2048 - 1970)*365+leap_years_1970_to_2047_inclusive))), '2048-01-01 00:00:00')
test_format_time_y2038.todo = "one day we'll move beyond 32-bit time"
class CacheDir(unittest.TestCase):
def test_basic(self):
basedir = "test_util/CacheDir/test_basic"

View File

@ -3,6 +3,9 @@
import calendar, datetime, re, time
def format_time(t):
return time.strftime("%Y-%m-%d %H:%M:%S", t)
def iso_utc_date(now=None, t=time.time):
if now is None:
now = t()
@ -13,11 +16,6 @@ def iso_utc(now=None, sep='_', t=time.time):
now = t()
return datetime.datetime.utcfromtimestamp(now).isoformat(sep)
def iso_local(now=None, sep='_', t=time.time):
if now is None:
now = t()
return datetime.datetime.fromtimestamp(now).isoformat(sep)
def iso_utc_time_to_seconds(isotime, _conversion_re=re.compile(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})[T_ ](?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})(?P<subsecond>\.\d+)?")):
"""
The inverse of iso_utc().

View File

@ -1,5 +1,7 @@
import time
import simplejson
from twisted.web import http, server
from twisted.python import log
from zope.interface import Interface
@ -13,11 +15,10 @@ from allmydata.interfaces import ExistingChildError, NoSuchChildError, \
MustBeReadonlyError, MustNotBeUnknownRWError, SDMF_VERSION, MDMF_VERSION
from allmydata.mutable.common import UnrecoverableFileError
from allmydata.util import abbreviate
from allmydata.util.time_format import format_time
from allmydata.util.encodingutil import to_str, quote_output
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
def get_filenode_metadata(filenode):
metadata = {'mutable': filenode.is_mutable()}
if metadata['mutable']:
@ -209,6 +210,12 @@ def text_plain(text, ctx):
req.setHeader("content-length", b"%d" % len(text))
return text
def spaces_to_nbsp(text):
return unicode(text).replace(u' ', u'\u00A0')
def render_time(t):
return spaces_to_nbsp(format_time(time.localtime(t)))
class WebError(Exception):
def __init__(self, text, code=http.BAD_REQUEST):
self.text = text

View File

@ -12,7 +12,7 @@ from nevow.inevow import IRequest
from foolscap.api import fireEventually
from allmydata.util import base32, time_format
from allmydata.util import base32
from allmydata.util.encodingutil import to_str
from allmydata.uri import from_string_dirnode
from allmydata.interfaces import IDirectoryNode, IFileNode, IFilesystemNode, \
@ -26,7 +26,7 @@ from allmydata.web.common import text_plain, WebError, \
boolean_of_arg, get_arg, get_root, parse_replace_arg, \
should_create_intermediate_directories, \
getxmlfile, RenderMixin, humanize_failure, convert_children_json, \
get_format, get_mutable_type, get_filenode_metadata
get_format, get_mutable_type, get_filenode_metadata, render_time
from allmydata.web.filenode import ReplaceMeMixin, \
FileNodeHandler, PlaceHolderNodeHandler
from allmydata.web.check_results import CheckResultsRenderer, \
@ -702,21 +702,21 @@ class DirectoryAsHTML(rend.Page):
times = []
linkcrtime = metadata.get('tahoe', {}).get("linkcrtime")
if linkcrtime is not None:
times.append("lcr: " + time_format.iso_local(linkcrtime))
times.append("lcr: " + render_time(linkcrtime))
else:
# For backwards-compatibility with links last modified by Tahoe < 1.4.0:
if "ctime" in metadata:
ctime = time_format.iso_local(metadata["ctime"])
ctime = render_time(metadata["ctime"])
times.append("c: " + ctime)
linkmotime = metadata.get('tahoe', {}).get("linkmotime")
if linkmotime is not None:
if times:
times.append(T.br())
times.append("lmo: " + time_format.iso_local(linkmotime))
times.append("lmo: " + render_time(linkmotime))
else:
# For backwards-compatibility with links last modified by Tahoe < 1.4.0:
if "mtime" in metadata:
mtime = time_format.iso_local(metadata["mtime"])
mtime = render_time(metadata["mtime"])
if times:
times.append(T.br())
times.append("m: " + mtime)

View File

@ -7,7 +7,7 @@ import allmydata
import simplejson
from allmydata import get_package_versions_string
from allmydata.util import idlib
from allmydata.web.common import getxmlfile, get_arg, TIME_FORMAT
from allmydata.web.common import getxmlfile, get_arg, render_time
class IntroducerRoot(rend.Page):
@ -53,7 +53,7 @@ class IntroducerRoot(rend.Page):
# 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())
return render_time(time.time())
def data_version(self, ctx, data):
return get_package_versions_string()
def data_import_path(self, ctx, data):
@ -92,7 +92,7 @@ class IntroducerRoot(rend.Page):
ctx.fillSlots("connection-hints",
"connection hints: " + " ".join(ad.connection_hints))
ctx.fillSlots("connected", "?")
when_s = time.strftime("%H:%M:%S %d-%b-%Y", time.localtime(ad.when))
when_s = render_time(ad.when)
ctx.fillSlots("announced", when_s)
ctx.fillSlots("version", ad.version)
ctx.fillSlots("service_name", ad.service_name)
@ -105,7 +105,7 @@ class IntroducerRoot(rend.Page):
ctx.fillSlots("nickname", s.nickname)
ctx.fillSlots("tubid", s.tubid)
ctx.fillSlots("connected", s.remote_address)
since_s = time.strftime("%H:%M:%S %d-%b-%Y", time.localtime(s.when))
since_s = render_time(s.when)
ctx.fillSlots("since", since_s)
ctx.fillSlots("version", s.version)
ctx.fillSlots("service_name", s.service_name)

View File

@ -14,7 +14,7 @@ from allmydata.interfaces import IFileNode
from allmydata.web import filenode, directory, unlinked, status, operations
from allmydata.web import storage
from allmydata.web.common import abbreviate_size, getxmlfile, WebError, \
get_arg, RenderMixin, get_format, get_mutable_type, TIME_FORMAT
get_arg, RenderMixin, get_format, get_mutable_type, render_time
class URIHandler(RenderMixin, rend.Page):
@ -171,7 +171,7 @@ class Root(rend.Page):
# 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())
return render_time(time.time())
def data_version(self, ctx, data):
return get_package_versions_string()
def data_import_path(self, ctx, data):
@ -309,10 +309,8 @@ class Root(rend.Page):
ctx.fillSlots("connected", connected)
ctx.fillSlots("connected_alt", self._connectedalts[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)))
ctx.fillSlots("since", render_time(since))
ctx.fillSlots("announced", render_time(announced))
ctx.fillSlots("version", version)
ctx.fillSlots("service_name", service_name)
ctx.fillSlots("available_space", available_space)

View File

@ -5,7 +5,7 @@ from twisted.internet import defer
from nevow import rend, inevow, tags as T
from allmydata.util import base32, idlib
from allmydata.web.common import getxmlfile, get_arg, \
abbreviate_time, abbreviate_rate, abbreviate_size, plural, compute_rate
abbreviate_time, abbreviate_rate, abbreviate_size, plural, compute_rate, render_time
from allmydata.interfaces import IUploadStatus, IDownloadStatus, \
IPublishStatus, IRetrieveStatus, IServermapUpdaterStatus
@ -162,9 +162,7 @@ class UploadStatusPage(UploadResultsRendererMixin, rend.Page):
return d
def render_started(self, ctx, data):
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(data.get_started()))
started_s = render_time(data.get_started())
return started_s
def render_si(self, ctx, data):
@ -614,9 +612,7 @@ class DownloadStatusPage(DownloadResultsRendererMixin, rend.Page):
return d
def render_started(self, ctx, data):
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(data.get_started()))
started_s = render_time(data.get_started())
return started_s + " (%s)" % data.get_started()
def render_si(self, ctx, data):
@ -647,9 +643,7 @@ class DownloadStatusTimelinePage(rend.Page):
docFactory = getxmlfile("download-status-timeline.xhtml")
def render_started(self, ctx, data):
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(data.get_started()))
started_s = render_time(data.get_started())
return started_s + " (%s)" % data.get_started()
def render_si(self, ctx, data):
@ -684,9 +678,7 @@ class RetrieveStatusPage(rend.Page, RateAndTimeMixin):
self.retrieve_status = data
def render_started(self, ctx, data):
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(data.get_started()))
started_s = render_time(data.get_started())
return started_s
def render_si(self, ctx, data):
@ -772,9 +764,7 @@ class PublishStatusPage(rend.Page, RateAndTimeMixin):
self.publish_status = data
def render_started(self, ctx, data):
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(data.get_started()))
started_s = render_time(data.get_started())
return started_s
def render_si(self, ctx, data):
@ -883,18 +873,14 @@ class MapupdateStatusPage(rend.Page, RateAndTimeMixin):
self.update_status = data
def render_started(self, ctx, data):
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(data.get_started()))
started_s = render_time(data.get_started())
return started_s
def render_finished(self, ctx, data):
when = data.get_finished()
if not when:
return "not yet"
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(data.get_finished()))
started_s = render_time(data.get_finished())
return started_s
def render_si(self, ctx, data):
@ -1110,9 +1096,7 @@ class Status(rend.Page):
def render_row(self, ctx, data):
s = data
TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
started_s = time.strftime(TIME_FORMAT,
time.localtime(s.get_started()))
started_s = render_time(s.get_started())
ctx.fillSlots("started", started_s)
si_s = base32.b2a_or_none(s.get_storage_index())