|
| 1 | +import gettext |
| 2 | +import os |
| 3 | +from pathlib import Path |
| 4 | +from typing import Any, Generator |
| 5 | + |
| 6 | +from app import config |
| 7 | +from app.dependencies import templates |
| 8 | + |
| 9 | +LANGUAGE_DIR = "app/locales" |
| 10 | +LANGUAGE_DIR_TEST = "../app/locales" |
| 11 | +TRANSLATION_FILE = "base" |
| 12 | + |
| 13 | + |
| 14 | +def set_ui_language(language: str = None) -> None: |
| 15 | + """Set the gettext translations to a given language. |
| 16 | + If the language requested is not supported, the translations default |
| 17 | + to the value of config.WEBSITE_LANGUAGE. |
| 18 | +
|
| 19 | + Args: |
| 20 | + language (str, optional): a valid language code that follows RFC 1766. |
| 21 | + Defaults to None. |
| 22 | + See also the Language Code Identifier (LCID) Reference for a list of |
| 23 | + valid language codes. |
| 24 | +
|
| 25 | + .. _RFC 1766: |
| 26 | + https://tools.ietf.org/html/rfc1766.html |
| 27 | +
|
| 28 | + .. _Language Code Identifier (LCID) Reference: |
| 29 | + https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c # noqa: E501 |
| 30 | + """ |
| 31 | + |
| 32 | + # TODO: Connect when user registration is completed. |
| 33 | + # if not language: |
| 34 | + # language = _get_display_language(user_id: int) |
| 35 | + |
| 36 | + language_dir = _get_language_directory() |
| 37 | + |
| 38 | + if language not in _get_supported_languages(language_dir): |
| 39 | + language = config.WEBSITE_LANGUAGE |
| 40 | + |
| 41 | + translations = gettext.translation(TRANSLATION_FILE, |
| 42 | + localedir=language_dir, |
| 43 | + languages=[language]) |
| 44 | + translations.install() |
| 45 | + templates.env.install_gettext_translations(translations, newstyle=True) |
| 46 | + |
| 47 | + |
| 48 | +# TODO: Waiting for user registration. Add doc. |
| 49 | +# def _get_display_language(user_id: int) -> str: |
| 50 | +# # TODO: handle user language setting: |
| 51 | +# # If user is logged in, get language setting. |
| 52 | +# # If user is not logged in, get default site setting. |
| 53 | +# |
| 54 | +# if db_user: |
| 55 | +# return db_user.language |
| 56 | +# return config.WEBSITE_LANGUAGE |
| 57 | + |
| 58 | + |
| 59 | +def _get_language_directory() -> str: |
| 60 | + """Get and return the language directory relative path. |
| 61 | +
|
| 62 | + Returns: |
| 63 | + str: the language directory relative path. |
| 64 | + """ |
| 65 | + language_dir = LANGUAGE_DIR |
| 66 | + if Path(LANGUAGE_DIR_TEST).is_dir(): |
| 67 | + # If running from test, change dir path. |
| 68 | + language_dir = LANGUAGE_DIR_TEST |
| 69 | + return language_dir |
| 70 | + |
| 71 | + |
| 72 | +def _get_supported_languages(language_dir: str = None) -> \ |
| 73 | + Generator[str, Any, None]: |
| 74 | + """Get and return a generator of supported translation languages codes. |
| 75 | +
|
| 76 | + Args: |
| 77 | + language_dir (str, optional): the path of the language directory. |
| 78 | + Defaults to None. |
| 79 | +
|
| 80 | + Returns: |
| 81 | + Generator[str, Any, None]: a generator expression of supported |
| 82 | + translation languages codes. |
| 83 | + """ |
| 84 | + |
| 85 | + if not language_dir: |
| 86 | + language_dir = _get_language_directory() |
| 87 | + |
| 88 | + return (language.name for language in |
| 89 | + [Path(f.path) for f in os.scandir(language_dir) if f.is_dir()]) |
0 commit comments