Projet

Général

Profil

0001-templates-add-a-duration-filter-25418.patch

Frédéric Péters, 01 décembre 2021 08:29

Télécharger (5,13 ko)

Voir les différences:

Subject: [PATCH] templates: add a |duration filter (#25418)

 tests/test_templates.py           | 28 ++++++++++++++++++++++++++++
 wcs/qommon/humantime.py           | 25 +++++++++++++++++--------
 wcs/qommon/templatetags/qommon.py | 16 ++++++++++++++++
 3 files changed, 61 insertions(+), 8 deletions(-)
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
-