diff options
Diffstat (limited to 'ishtar_common/jinja_filters.py')
-rw-r--r-- | ishtar_common/jinja_filters.py | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/ishtar_common/jinja_filters.py b/ishtar_common/jinja_filters.py new file mode 100644 index 000000000..0bc81c47f --- /dev/null +++ b/ishtar_common/jinja_filters.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright (C) 2025 Étienne Loks <etienne.loks at iggdrasil dot net> +# 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 <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + + +from datetime import datetime +from jinja2.filters import environmentfilter +import locale +from num2words import num2words +import re + +from django.conf import settings + + +def set_locale(): + language_code = settings.LANGUAGE_CODE.split("-") + language_code = language_code[0] + "_" + language_code[1].upper() + for language_suffix in (".utf8", ""): + try: + locale.setlocale(locale.LC_TIME, language_code + language_suffix) + break + except locale.Error: + pass + + +@environmentfilter +def float_format(*args): + """ + 10350.5 -> 10 350,5 + 5 -> 5 + 5.449999 -> 5,45 + """ + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + if value is None or value == "": + return "" + try: + value = float(value) + except ValueError: + return "" + locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8") + if int(value) != value: + value = float(f"{value:.2f}") + return f"{value:n}" + + +@environmentfilter +def euro_format(*args): + """ + 15000 -> 15 000,00 € + 5 -> 5,00 € + """ + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + value = float_format(value) + if not value: + return "" + parts = value.split(",") + if len(parts) < 2: + return value + ",00 €" + elif len(parts[1]) == 1: + return value + "0 €" + return value + " €" + + +@environmentfilter +def number_to_words(*args): + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + if value is None or value == "": + return "" + try: + value = float(value) + except ValueError: + return "" + return num2words(value, lang=settings.LANGUAGE_CODE.split("-")[0]) + + +@environmentfilter +def replace_line_breaks(*args): + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + return (value or "").replace("\r\n", "\n") + + +@environmentfilter +def capfirst_filter(*args): + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + return value[0].upper() + value[1:] if value else value + + +@environmentfilter +def lowerfirst_filter(*args): + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + return value[0].lower() + value[1:] if value else value + + +RE_CAP = re.compile(r"[^-' ]+") +SEP = ("un", "une", "le", "la", "les", "lez", "d", "l", "de", "des", "du", "sur", + "sous", "en") + + +@environmentfilter +def capitalize_filter(*args): + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + if not value: + return "" + value = value.lower() + res = "" + for m in RE_CAP.finditer(value): + start = m.start() + if start: + res += value[start - 1] + v = m.group() + if v not in SEP: + v = v[0].upper() + v[1:] + res += v + return res + + +@environmentfilter +def human_date_filter(*args): + value = args[0] if len(args) == 1 else args[1] # jinja simple filter + try: + value = datetime.strptime(value, "%Y-%m-%d") + except (ValueError, TypeError) as __: + return "" + set_locale() + return value.strftime(settings.DATE_FORMAT) |