templates: add a |duration filter (#25418)
This commit is contained in:
parent
c20803ba48
commit
6040c018f2
|
@ -4,6 +4,7 @@ import string
|
|||
|
||||
import pytest
|
||||
from django.test import override_settings
|
||||
from django.utils import translation
|
||||
from django.utils.timezone import now
|
||||
|
||||
try:
|
||||
|
@ -1293,3 +1294,30 @@ def test_newline(pub):
|
|||
context = pub.substitutions.get_context_variables()
|
||||
assert Template('a{% newline %}b').render(context) == 'a\nb'
|
||||
assert Template('a{% newline windows=True %}b').render(context) == 'a\r\nb'
|
||||
|
||||
|
||||
def test_duration(pub):
|
||||
pub.ngettext = translation.ngettext
|
||||
|
||||
context = {'value': 80}
|
||||
assert Template('{{ value|duration }}').render(context) == '1h20'
|
||||
assert Template('{{ value|duration:"long" }}').render(context) == '1 hour and 20 minutes'
|
||||
|
||||
context = {'value': 40}
|
||||
assert Template('{{ value|duration }}').render(context) == '40min'
|
||||
assert Template('{{ value|duration:"long" }}').render(context) == '40 minutes'
|
||||
|
||||
context = {'value': 120}
|
||||
assert Template('{{ value|duration }}').render(context) == '2h'
|
||||
assert Template('{{ value|duration:"long" }}').render(context) == '2 hours'
|
||||
|
||||
context = {'value': 1510}
|
||||
assert Template('{{ value|duration }}').render(context) == '1 day and 1h10'
|
||||
assert Template('{{ value|duration:"long" }}').render(context) == '1 day, 1 hour and 10 minutes'
|
||||
|
||||
context = {'value': 61}
|
||||
assert Template('{{ value|duration }}').render(context) == '1h01'
|
||||
|
||||
context = {'value': 'xx'}
|
||||
assert Template('{{ value|duration }}').render(context) == ''
|
||||
assert Template('{{ value|duration:"long" }}').render(context) == ''
|
||||
|
|
|
@ -65,7 +65,7 @@ def humanduration2seconds(humanduration):
|
|||
return seconds
|
||||
|
||||
|
||||
def seconds2humanduration(seconds):
|
||||
def seconds2humanduration(seconds, short=False):
|
||||
"""Convert a time range in seconds to a human string representation"""
|
||||
if not isinstance(seconds, int):
|
||||
return ""
|
||||
|
@ -79,10 +79,19 @@ def seconds2humanduration(seconds):
|
|||
human = []
|
||||
if days:
|
||||
human.append(ngettext('%(total)s day', '%(total)s days', days) % {'total': days})
|
||||
if hours:
|
||||
human.append(ngettext('%(total)s hour', '%(total)s hours', hours) % {'total': hours})
|
||||
if minutes:
|
||||
human.append(ngettext('%(total)s minute', '%(total)s minutes', minutes) % {'total': minutes})
|
||||
if seconds:
|
||||
human.append(ngettext('%(total)s second', '%(total)s seconds', seconds) % {'total': seconds})
|
||||
return list2human(human)
|
||||
if short:
|
||||
if hours and minutes:
|
||||
human.append(_('%(hours)sh%(minutes)02d') % {'hours': hours, 'minutes': minutes})
|
||||
elif hours:
|
||||
human.append(_('%(hours)sh') % {'hours': hours})
|
||||
elif minutes:
|
||||
human.append(_('%(minutes)smin') % {'minutes': minutes})
|
||||
return list2human(human)
|
||||
else:
|
||||
if hours:
|
||||
human.append(ngettext('%(total)s hour', '%(total)s hours', hours) % {'total': hours})
|
||||
if minutes:
|
||||
human.append(ngettext('%(total)s minute', '%(total)s minutes', minutes) % {'total': minutes})
|
||||
if seconds:
|
||||
human.append(ngettext('%(total)s second', '%(total)s seconds', seconds) % {'total': seconds})
|
||||
return list2human(human)
|
||||
|
|
|
@ -52,6 +52,7 @@ from django.utils.timezone import is_naive, make_aware
|
|||
|
||||
from wcs.qommon import calendar, evalutils, tokens, upload_storage
|
||||
from wcs.qommon.admin.texts import TextsDirectory
|
||||
from wcs.qommon.humantime import seconds2humanduration
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
@ -256,6 +257,21 @@ def decimal(value, arg=None):
|
|||
return defaultfilters.floatformat(value, arg=arg)
|
||||
|
||||
|
||||
@register.filter(is_safe=False)
|
||||
def duration(value, arg='short'):
|
||||
if arg not in ('short', 'long'):
|
||||
return ''
|
||||
# value is expected to be a timedelta or a number of seconds
|
||||
value = unlazy(value)
|
||||
arg = unlazy(arg)
|
||||
if not isinstance(value, datetime.timedelta):
|
||||
try:
|
||||
value = datetime.timedelta(seconds=int(value) * 60)
|
||||
except (TypeError, ValueError):
|
||||
return ''
|
||||
return seconds2humanduration(int(value.total_seconds()), short=bool(arg != 'long'))
|
||||
|
||||
|
||||
@register.filter(expects_localtime=True, is_safe=False)
|
||||
def add_days(value, arg):
|
||||
if hasattr(value, 'timetuple'):
|
||||
|
|
Loading…
Reference in New Issue