0001-templates-add-a-duration-filter-25418.patch
tests/test_templates.py | ||
---|---|---|
4 | 4 | |
5 | 5 |
import pytest |
6 | 6 |
from django.test import override_settings |
7 |
from django.utils import translation |
|
7 | 8 |
from django.utils.timezone import now |
8 | 9 | |
9 | 10 |
try: |
... | ... | |
1293 | 1294 |
context = pub.substitutions.get_context_variables() |
1294 | 1295 |
assert Template('a{% newline %}b').render(context) == 'a\nb' |
1295 | 1296 |
assert Template('a{% newline windows=True %}b').render(context) == 'a\r\nb' |
1297 | ||
1298 | ||
1299 |
def test_duration(pub): |
|
1300 |
pub.ngettext = translation.ngettext |
|
1301 | ||
1302 |
context = {'value': 4800} |
|
1303 |
assert Template('{{ value|duration }}').render(context) == '1h20' |
|
1304 |
assert Template('{{ value|duration:"long" }}').render(context) == '1 hour and 20 minutes' |
|
1305 | ||
1306 |
context = {'value': 2400} |
|
1307 |
assert Template('{{ value|duration }}').render(context) == '40min' |
|
1308 |
assert Template('{{ value|duration:"long" }}').render(context) == '40 minutes' |
|
1309 | ||
1310 |
context = {'value': 7200} |
|
1311 |
assert Template('{{ value|duration }}').render(context) == '2h' |
|
1312 |
assert Template('{{ value|duration:"long" }}').render(context) == '2 hours' |
|
1313 | ||
1314 |
context = {'value': 90600} |
|
1315 |
assert Template('{{ value|duration }}').render(context) == '1 day and 1h10' |
|
1316 |
assert Template('{{ value|duration:"long" }}').render(context) == '1 day, 1 hour and 10 minutes' |
|
1317 | ||
1318 |
context = {'value': 3660} |
|
1319 |
assert Template('{{ value|duration }}').render(context) == '1h01' |
|
1320 | ||
1321 |
context = {'value': 'xx'} |
|
1322 |
assert Template('{{ value|duration }}').render(context) == '' |
|
1323 |
assert Template('{{ value|duration:"long" }}').render(context) == '' |
wcs/qommon/humantime.py | ||
---|---|---|
65 | 65 |
return seconds |
66 | 66 | |
67 | 67 | |
68 |
def seconds2humanduration(seconds): |
|
68 |
def seconds2humanduration(seconds, short=False):
|
|
69 | 69 |
"""Convert a time range in seconds to a human string representation""" |
70 | 70 |
if not isinstance(seconds, int): |
71 | 71 |
return "" |
... | ... | |
79 | 79 |
human = [] |
80 | 80 |
if days: |
81 | 81 |
human.append(ngettext('%(total)s day', '%(total)s days', days) % {'total': days}) |
82 |
if hours: |
|
83 |
human.append(ngettext('%(total)s hour', '%(total)s hours', hours) % {'total': hours}) |
|
84 |
if minutes: |
|
85 |
human.append(ngettext('%(total)s minute', '%(total)s minutes', minutes) % {'total': minutes}) |
|
86 |
if seconds: |
|
87 |
human.append(ngettext('%(total)s second', '%(total)s seconds', seconds) % {'total': seconds}) |
|
88 |
return list2human(human) |
|
82 |
if short: |
|
83 |
if hours and minutes: |
|
84 |
human.append(_('%(hours)sh%(minutes)02d') % {'hours': hours, 'minutes': minutes}) |
|
85 |
elif hours: |
|
86 |
human.append(_('%(hours)sh') % {'hours': hours}) |
|
87 |
elif minutes: |
|
88 |
human.append(_('%(minutes)smin') % {'minutes': minutes}) |
|
89 |
return list2human(human) |
|
90 |
else: |
|
91 |
if hours: |
|
92 |
human.append(ngettext('%(total)s hour', '%(total)s hours', hours) % {'total': hours}) |
|
93 |
if minutes: |
|
94 |
human.append(ngettext('%(total)s minute', '%(total)s minutes', minutes) % {'total': minutes}) |
|
95 |
if seconds: |
|
96 |
human.append(ngettext('%(total)s second', '%(total)s seconds', seconds) % {'total': seconds}) |
|
97 |
return list2human(human) |
wcs/qommon/templatetags/qommon.py | ||
---|---|---|
52 | 52 | |
53 | 53 |
from wcs.qommon import calendar, evalutils, tokens, upload_storage |
54 | 54 |
from wcs.qommon.admin.texts import TextsDirectory |
55 |
from wcs.qommon.humantime import seconds2humanduration |
|
55 | 56 | |
56 | 57 |
register = template.Library() |
57 | 58 | |
... | ... | |
256 | 257 |
return defaultfilters.floatformat(value, arg=arg) |
257 | 258 | |
258 | 259 | |
260 |
@register.filter(is_safe=False) |
|
261 |
def duration(value, arg='short'): |
|
262 |
if arg not in ('short', 'long'): |
|
263 |
return '' |
|
264 |
# value is expected to be a timedelta or a number of seconds |
|
265 |
value = unlazy(value) |
|
266 |
arg = unlazy(arg) |
|
267 |
if not isinstance(value, datetime.timedelta): |
|
268 |
try: |
|
269 |
value = datetime.timedelta(seconds=int(value)) |
|
270 |
except (TypeError, ValueError): |
|
271 |
return '' |
|
272 |
return seconds2humanduration(int(value.total_seconds()), short=bool(arg != 'long')) |
|
273 | ||
274 | ||
259 | 275 |
@register.filter(expects_localtime=True, is_safe=False) |
260 | 276 |
def add_days(value, arg): |
261 | 277 |
if hasattr(value, 'timetuple'): |
262 |
- |