aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2022-07-08 02:42:44 +0200
committerDaniel Schadt <kingdread@gmx.de>2022-07-08 02:42:44 +0200
commitbb6714e9d7468465f23bf0e163d06517de397dbe (patch)
treeaaabb03f1e7f8f41259815e5f03fcca14ef124f2
parent210650683ccbfa35da293cd1b43057a780349d91 (diff)
downloadfietsboek-bb6714e9d7468465f23bf0e163d06517de397dbe.tar.gz
fietsboek-bb6714e9d7468465f23bf0e163d06517de397dbe.tar.bz2
fietsboek-bb6714e9d7468465f23bf0e163d06517de397dbe.zip
better loading in util.read_localized_resource
The other code kinda assumed that we can turn the resource path into a package by replacing the slashes (path separators) with dots. That turned out to not really work in the end, especially if the resource subfolders don't have a __init__.py in there. This uses the .files() API (available in Python 3.9 and backported in importlib_resources) to better handle folders in the resources.
-rw-r--r--MANIFEST.in2
-rw-r--r--fietsboek/util.py39
-rw-r--r--setup.py1
3 files changed, 26 insertions, 16 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index 0d8bb87..38898e6 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,7 +1,7 @@
include *.txt *.ini *.cfg *.rst
recursive-include fietsboek *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
recursive-include fietsboek/static *
-recursive-include fietsboek/locale *.pot *.po *.mo
+recursive-include fietsboek/locale *.pot *.po *.mo *.html
recursive-include tests *
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
diff --git a/fietsboek/util.py b/fietsboek/util.py
index e24f96a..7ca0d62 100644
--- a/fietsboek/util.py
+++ b/fietsboek/util.py
@@ -2,8 +2,9 @@
import random
import string
import datetime
-import importlib.resources
+# Compat for Python < 3.9
+import importlib_resources
import babel
import markdown
import bleach
@@ -263,29 +264,37 @@ def check_password_constraints(password, repeat_password=None):
raise ValueError(_("password_constraint.length"))
-def read_localized_resource(locale_name, path):
+def read_localized_resource(locale_name, path, raise_on_error=False):
"""Reads a localized resource.
Localized resources are located in the ``fietsboek/locale/**`` directory.
- Note that ``path`` may contain slashes, which are automatically replaced
- with the right separators.
+ Note that ``path`` may contain slashes.
If the resource could not be found, a placeholder string is returned instead.
:param locale_name: Name of the locale.
:type locale_name: str
+ :param raise_on_error: Raise an error instead of returning a placeholder.
+ :type raise_on_error: bool
+ :raises FileNotFoundError: If the path could not be found and
+ ``raise_on_error`` is ``True``.
:return: The text content of the resource.
:rtype: str
"""
- parts = path.split("/")
- package = ".".join(parts[:-1])
- package = f"fietsboek.locale.{locale_name}.{package}"
- try:
- return importlib.resources.read_text(package, parts[-1])
- except (FileNotFoundError, ModuleNotFoundError, NotADirectoryError):
- # Second chance: If the locale is a specific form of a more general
- # locale, try the general locale as well.
- if "_" in locale_name:
- main_locale = locale_name.split("_", 1)[0]
- return read_localized_resource(main_locale, path)
+ locales = [locale_name]
+ # Second chance: If the locale is a specific form of a more general
+ # locale, try the general locale as well.
+ if "_" in locale_name:
+ locales.append(locale_name.split("_", 1)[0])
+
+ for locale in locales:
+ locale_dir = importlib_resources.files('fietsboek') / 'locale' / locale
+ resource_path = locale_dir / path
+ try:
+ return resource_path.read_text()
+ except (FileNotFoundError, ModuleNotFoundError, NotADirectoryError):
+ pass
+ if raise_on_error:
+ raise FileNotFoundError(f"Resource {path!r} not found")
+ else:
return f"{locale_name}:{path}"
diff --git a/setup.py b/setup.py
index d6267a6..bcb2ab1 100644
--- a/setup.py
+++ b/setup.py
@@ -20,6 +20,7 @@ requires = [
'SQLAlchemy',
'transaction',
'zope.sqlalchemy',
+ 'importlib_resources',
'Babel',
'cryptography',
'gpxpy',