diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2022-07-08 02:42:44 +0200 | 
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2022-07-08 02:42:44 +0200 | 
| commit | bb6714e9d7468465f23bf0e163d06517de397dbe (patch) | |
| tree | aaabb03f1e7f8f41259815e5f03fcca14ef124f2 | |
| parent | 210650683ccbfa35da293cd1b43057a780349d91 (diff) | |
| download | fietsboek-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.in | 2 | ||||
| -rw-r--r-- | fietsboek/util.py | 39 | ||||
| -rw-r--r-- | setup.py | 1 | 
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}" @@ -20,6 +20,7 @@ requires = [      'SQLAlchemy',      'transaction',      'zope.sqlalchemy', +    'importlib_resources',      'Babel',      'cryptography',      'gpxpy',  | 
