Source code for pyra.locales

"""
..
   locales.py

Functions related to localization.

Localization (also referred to as l10n) is the process of adapting a product or service to a specific locale.
Translation is only one of several elements in the localization process. In addition to translation, the localization
process may also include:
- Adapting design and layout to properly display translated text in the language of the locale
- Adapting sorting functions to the alphabetical order of a specific locale
- Changing formats for date and time, addresses, numbers, currencies, etc. for specific target locales
- Adapting graphics to suit the expectations and tastes of a target locale
- Modifying content to suit the tastes and consumption habits of a target locale

The aim of localization is to give a product or service the look and feel of having been created specifically for a
target market, no matter their language, cultural preferences, or location.
"""
# standard imports
import gettext
import os
import subprocess
import sys

# lib imports
import babel
from babel import localedata

# local imports
from pyra import config
from pyra.definitions import Paths
from pyra import logger

default_domain = 'retroarcher'
default_locale = 'en'
default_timezone = 'UTC'
supported_locales = ['en', 'es']

log = logger.get_logger(__name__)


[docs] def get_all_locales() -> dict: """ Get a dictionary of all possible locales for use with babel. Dictionary keys will be `locale_id` and value with be `locale_display_name`. This is a shortened example of the returned value. .. code-block:: python { 'de': 'Deutsch', 'en': 'English', 'en_GB': 'English (United Kingdom)', 'en_US': 'English (United States)', 'es': 'español', 'fr': 'français', 'it': 'italiano', 'ru': 'русский' } Returns ------- dict Dictionary of all possible locales. Examples -------- >>> get_all_locales() {... 'en': 'English', ... 'en_GB': 'English (United Kingdom)', ... 'es': 'español', ... 'fr': 'français', ...} """ log.debug(msg='Getting locale dictionary.') locale_ids = localedata.locale_identifiers() locales = {} for locale_id in locale_ids: locale = babel.Locale.parse(identifier=locale_id) locales[locale_id] = locale.get_display_name() return locales
[docs] def get_locale() -> str: """ Verify the locale. Verify the locale from the config against supported locales and returns appropriate locale. Returns ------- str The locale set in the config if it is valid, otherwise the default locale (en). Examples -------- >>> get_locale() 'en' """ try: config_locale = config.CONFIG['General']['LOCALE'] except TypeError: config_locale = None if config_locale in supported_locales: return config_locale else: return default_locale
[docs] def get_text() -> gettext.gettext: """ Install the language defined in the conifg. This function installs the language defined in the config and allows translations in python code. Returns ------- gettext.gettext The `gettext.gettext` method. Examples -------- >>> get_text() <bound method GNUTranslations.gettext of <gettext.GNUTranslations object at 0x...>> """ translation_fallback = False if not os.path.isfile(os.path.join(Paths.LOCALE_DIR, get_locale(), 'LC_MESSAGES', f'{default_domain}.mo')): log.warning(msg='No locale mo translation file found.') locale_script = os.path.join(Paths.ROOT_DIR, 'scripts', '_locale.py') if os.path.isfile(locale_script): log.info(msg='Running locale compile script.') # run python script in a subprocess subprocess.run( args=[sys.executable, locale_script, '--compile'], cwd=Paths.ROOT_DIR, ) else: log.warning(msg='Locale compile script not found. Defaulting to English.') translation_fallback = True language = gettext.translation( domain=default_domain, localedir=Paths.LOCALE_DIR, languages=[get_locale()], fallback=translation_fallback, ) language.install() return language.gettext