Source code for babelwrap

#!/usr/bin/env python3
"""
Permits setting a default language for ``_()`` and babel functions.

.. _babel.core.Locale: http://babel.pocoo.org/en/latest/api/core.html
.. _babel.dates.format_datetime: http://babel.pocoo.org/en/latest/api/dates.html#babel.dates.format_datetime
.. _babel.lists.format_list: http://babel.pocoo.org/en/latest/api/lists.html
.. _babel.numbers.format_decimal: http://babel.pocoo.org/en/latest/api/numbers.html#babel.numbers.format_decimal
.. _babel.numbers.format_percent: http://babel.pocoo.org/en/latest/api/numbers.html#babel.numbers.format_percent
.. _babel.units.format_unit: http://babel.pocoo.org/en/latest/api/units.html#babel.units.format_unit
"""

import functools
import gettext
import locale
import logging

import babel.core
import babel.dates
import babel.lists
import babel.numbers
import babel.units

logger = logging.getLogger()

# TODO: Move to toml file
_DOMAIN = "games"
_LANG_DIR = "\\Users\\Chris.santos-lang\\locales"
_SOURCE_LANGUAGE = "en"

_locale: str = ""
_folder: str = ""

    
def _install(function):
    """Used by babelwrap internally to install each babel function"""
    global _locale
    wrapper = functools.partial(function, locale=_locale)
    wrapper.__doc__ = "\n".join(
        ["    *Default locale from setlang()* Otherwise:", function.__doc__],
    )
    globals()[function.__name__] = wrapper

#TODO: Refactor to reduce complexity
[docs]def setlang(*langs: str) -> babel.core.Locale: """Gets/sets locale for language functions. E.g.:: setlang() # to get the currenty set locale setlang("zh_Hans_HK", "zh_HK") # to set a language (e.g. for testing) setlang("") # to restore the default language Args: *langs (str): locale names in order of preference. Returns: The babel.core.Locale_ that is currently set. The babel functions can then be used (defaulted to the set language) as follows:: print(format_decimal(-12345.6789)) print(format_percent(-12345.6789)) print(format_unit(-12345.6789, "second")) print(format_datetime(datetime.datetime.now())) print(format_list(["Alvin", "Simon", "Theodore"])) print(_("Hello world!")) """ global _locale if _locale and not langs: return _locale # append related languages languages = list(langs) for lang in filter(bool, langs): try: parsed = babel.core.Locale.parse(lang.replace("-", "_")) except (babel.core.UnknownLocaleError, ValueError) as e: logging.warning(f"Cannot parse language '{lang}'") languages.append(parsed.language) # append the language of the local machine language_code, encoding = locale.getdefaultlocale() languages.append(str(language_code)[0:2]) # choose the first language with qualifying .mo file folder = "" for lang in languages: path = gettext.find(_DOMAIN, _LANG_DIR, [lang]) if path: folder = path.split(_LANG_DIR + "\\")[1].split("\\")[0] break try: globals()["_"] = gettext.translation( _DOMAIN, _LANG_DIR, [folder], ).gettext except (FileNotFoundError) as e: logging.error( "No {domain}.mo found in {dir}".format( domain=_DOMAIN, dir=_LANG_DIR, ) ) globals()["_"] = lambda x: x try: new_locale = babel.core.Locale.parse(lang.replace("-", "_")) except (babel.core.UnknownLocaleError, ValueError) as e: logging.warning(f"No locale found for '{lang}'") new_locale = babel.core.Locale(_SOURCE_LANGUAGE) global _folder folderisnew = (not _folder) or (_folder != folder) if (langs and list(langs)[0]) or folderisnew: _locale, _folder = new_locale, folder logging.debug( "{locale} {path}".format( path=path, locale=repr(_locale), ) ) _install(babel.lists.format_list) _install(babel.numbers.format_decimal) _install(babel.dates.format_datetime) _install(babel.numbers.format_percent) _install(babel.units.format_unit) return _locale
setlang()