53
52
# Display of times.
55
54
# date_day -- just the day
56
# date_time -- full date with time
55
# date_time -- full date with time (UTC)
58
# displaydate -- for use in sentences
59
57
# approximatedate -- for use in tables
61
# displaydate and approximatedate return an elementtree <span> Element
62
# with the full date in a tooltip.
59
# approximatedate return an elementtree <span> Element
60
# with the full date (UTC) in a tooltip.
65
63
def date_day(value):
69
67
def date_time(value):
70
68
if value is not None:
71
return value.strftime('%Y-%m-%d %H:%M:%S')
69
# Note: this assumes that the value is UTC in some fashion.
70
return value.strftime('%Y-%m-%d %H:%M:%S UTC')
76
def _displaydate(date):
77
delta = abs(datetime.datetime.now() - date)
78
if delta > datetime.timedelta(1, 0, 0):
79
# far in the past or future, display the date
80
return 'on ' + date_day(date)
81
return _approximatedate(date)
84
75
def _approximatedate(date):
85
76
delta = datetime.datetime.now() - date
86
77
if abs(delta) > datetime.timedelta(1, 0, 0):
214
201
# only do this if unicode turns out to be a problem
215
202
#_BADCHARS_RE = re.compile(ur'[\u007f-\uffff]')
204
# Can't be a dict; & needs to be done first.
208
("'", "'"), # ' is defined in XML, but not HTML.
215
"""Transform dangerous (X)HTML characters into entities.
217
Like cgi.escape, except also escaping \" and '. This makes it safe to use
218
in both attribute and element content.
220
If you want to safely fill a format string with escaped values, use
223
for char, repl in html_entity_subs:
224
s = s.replace(char, repl)
228
def html_format(template, *args):
229
"""Safely format an HTML template string, escaping the arguments.
231
The template string must not be user-controlled; it will not be escaped.
233
return template % tuple(html_escape(arg) for arg in args)
217
236
# FIXME: get rid of this method; use fixed_width() and avoid XML().
220
238
def html_clean(s):
222
240
clean up a string for html display. expand any tabs, encode any html
223
241
entities, and replace spaces with ' '. this is primarily for use
224
242
in displaying monospace text.
226
s = cgi.escape(s.expandtabs())
244
s = html_escape(s.expandtabs())
227
245
s = s.replace(' ', ' ')
269
287
except UnicodeDecodeError:
270
288
s = s.decode('iso-8859-15')
272
s = cgi.escape(s).expandtabs().replace(' ', NONBREAKING_SPACE)
290
s = html_escape(s).expandtabs().replace(' ', NONBREAKING_SPACE)
274
292
return HSC.clean(s).replace('\n', '<br/>')
454
472
for index, dir_name in enumerate(dir_parts):
455
473
inner_breadcrumbs.append({
456
474
'dir_name': dir_name,
457
'file_id': inv.path2id('/'.join(dir_parts[:index + 1])),
475
'path': '/'.join(dir_parts[:index + 1]),
458
476
'suffix': '/' + view,
460
478
return inner_breadcrumbs
525
543
# for re-ordering an existing page by different sort
527
545
t_context = threading.local()
528
_valid = ('start_revid', 'file_id', 'filter_file_id', 'q', 'remember',
529
'compare_revid', 'sort')
547
'start_revid', 'filter_file_id', 'q', 'remember', 'compare_revid', 'sort')
532
550
def set_context(map):
635
653
return new_application
656
def convert_to_json_ready(obj):
657
if isinstance(obj, Container):
658
d = obj.__dict__.copy()
661
elif isinstance(obj, datetime.datetime):
662
return tuple(obj.utctimetuple())
663
raise TypeError(repr(obj) + " is not JSON serializable")