From 1e2cf7f6188630432deff5eb6b9a1cb3a2bb23a3 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Tue, 19 Oct 2021 16:29:38 +0200 Subject: [PATCH] templatetags: add as_numeral filters (#57983) --- debian/control | 3 +- debian/debian_config_common.py | 3 ++ hobo/templatetags/__init__.py | 0 hobo/templatetags/hobo.py | 46 ++++++++++++++++++++++++++++++ tests/settings.py | 2 ++ tests/test_templatetags.py | 52 ++++++++++++++++++++++++++++++++++ tox.ini | 1 + 7 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 hobo/templatetags/__init__.py create mode 100644 hobo/templatetags/hobo.py create mode 100644 tests/test_templatetags.py diff --git a/debian/control b/debian/control index 2ce27dd..8ac794f 100644 --- a/debian/control +++ b/debian/control @@ -17,7 +17,8 @@ Depends: ${misc:Depends}, python3-prometheus-client, python3-djangorestframework, python3-dnspython, - python3-systemd + python3-systemd, + python3-num2words Breaks: python-hobo (<< 1.53.post2) Replaces: python-hobo (<< 1.53.post2) Recommends: diff --git a/debian/debian_config_common.py b/debian/debian_config_common.py index 6fe009c..570ce48 100644 --- a/debian/debian_config_common.py +++ b/debian/debian_config_common.py @@ -375,6 +375,9 @@ if PROJECT_NAME != 'wcs': if 'authentic2' not in INSTALLED_APPS: MELLON_ADAPTER = ('hobo.multitenant.mellon.MellonAdapter',) +if PROJECT_NAME in ('wcs', 'combo'): + TEMPLATES[0]['OPTIONS'].setdefault('builtins', []).append('hobo.templatetags.hobo') + if 'authentic2' not in INSTALLED_APPS: MELLON_DEFAULT_ASSERTION_CONSUMER_BINDING = 'artifact' diff --git a/hobo/templatetags/__init__.py b/hobo/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hobo/templatetags/hobo.py b/hobo/templatetags/hobo.py new file mode 100644 index 0000000..86b19a7 --- /dev/null +++ b/hobo/templatetags/hobo.py @@ -0,0 +1,46 @@ +# hobo - portal to configure and deploy applications +# Copyright (C) 2015-2021 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import decimal + +from django import template +from django.template.defaultfilters import stringfilter +from django.utils.translation import get_language +from num2words import num2words + +register = template.Library() + + +def unlazy(x): + return x.get_value() if hasattr(x, 'get_value') else x + + +@register.filter +@stringfilter +def as_numeral(number): + try: + return num2words(unlazy(number), lang=get_language()) + except (TypeError, ValueError, decimal.InvalidOperation, OverflowError): + return '' + + +@register.filter +@stringfilter +def as_numeral_currency(number): + try: + return num2words(unlazy(number), lang=get_language(), to='currency') + except (TypeError, ValueError, decimal.InvalidOperation, OverflowError): + return '' diff --git a/tests/settings.py b/tests/settings.py index 5068ca0..952c142 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -24,3 +24,5 @@ DATABASES = { }, } } + +TEMPLATES[0]['OPTIONS'].setdefault('builtins', []).append('hobo.templatetags.hobo') diff --git a/tests/test_templatetags.py b/tests/test_templatetags.py new file mode 100644 index 0000000..64ba5dd --- /dev/null +++ b/tests/test_templatetags.py @@ -0,0 +1,52 @@ +# hobo - portal to configure and deploy applications +# Copyright (C) 2015-2021 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from django.template import Context, Template + + +def test_as_numeral(settings): + t = Template('{{ number|as_numeral }}') + assert t.render(Context({'number': 42})) == 'forty-two' + assert t.render(Context({'number': '42'})) == 'forty-two' + assert t.render(Context({'number': 42.15})) == 'forty-two point one five' + assert t.render(Context({'number': -42})) == 'minus forty-two' + assert t.render(Context({'number': None})) == '' + assert t.render(Context({'number': 'foo'})) == '' + assert t.render(Context({'number': ['foo', 'bar']})) == '' + assert t.render(Context({'number': {'foo': 'bar'}})) == '' + assert t.render(Context({'number': 10 ** 500})) == '' + + settings.LANGUAGE_CODE = 'fr' + assert t.render(Context({'number': 42})) == 'quarante-deux' + assert t.render(Context({'number': 42.15})) == 'quarante-deux virgule un cinq' + + +def test_as_numeral_currency(settings): + t = Template('{{ number|as_numeral_currency }}') + assert t.render(Context({'number': 42})) == 'forty-two euro, zero cents' + assert t.render(Context({'number': '42'})) == 'forty-two euro, zero cents' + assert t.render(Context({'number': 42.15})) == 'forty-two euro, fifteen cents' + assert t.render(Context({'number': -42})) == 'minus forty-two euro, zero cents' + assert t.render(Context({'number': None})) == '' + assert t.render(Context({'number': 'foo'})) == '' + assert t.render(Context({'number': ['foo', 'bar']})) == '' + assert t.render(Context({'number': {'foo': 'bar'}})) == '' + assert t.render(Context({'number': 10 ** 500})) == '' + + settings.LANGUAGE_CODE = 'fr' + assert t.render(Context({'number': 42})) == 'quarante-deux euros et zéro centimes' + assert t.render(Context({'number': 42.15})) == 'quarante-deux euros et quinze centimes' + assert t.render(Context({'number': '1'})) == 'un euro et zéro centimes' diff --git a/tox.ini b/tox.ini index 832cee8..a1b5096 100644 --- a/tox.ini +++ b/tox.ini @@ -55,6 +55,7 @@ deps: xmlschema<1.1 enum34<=1.1.6 psycopg2-binary<2.9 + num2words black: pre-commit commands = ./getlasso3.sh -- 2.30.2