From 0d93e083974a7f0787471366ab874f7354b0a5e2 Mon Sep 17 00:00:00 2001 From: profitroll Date: Tue, 20 Jun 2023 12:30:27 +0200 Subject: [PATCH] Added BotLocale class --- libbot/i18n/__init__.py | 1 + libbot/i18n/classes/bot_locale.py | 121 ++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 libbot/i18n/classes/bot_locale.py diff --git a/libbot/i18n/__init__.py b/libbot/i18n/__init__.py index 04353c1..fc8ed34 100644 --- a/libbot/i18n/__init__.py +++ b/libbot/i18n/__init__.py @@ -3,6 +3,7 @@ from pathlib import Path from typing import Any, Dict from libbot import config_get, json_read, sync +from libbot.i18n.classes.bot_locale import BotLocale async def _(key: str, *args: str, locale: str = sync.config_get("locale")) -> Any: diff --git a/libbot/i18n/classes/bot_locale.py b/libbot/i18n/classes/bot_locale.py new file mode 100644 index 0000000..4df1397 --- /dev/null +++ b/libbot/i18n/classes/bot_locale.py @@ -0,0 +1,121 @@ +from os import listdir +from pathlib import Path +from typing import Any, Dict, Union + +from libbot import sync + + +class BotLocale: + """Small addon that can be used by bot clients' classes in order to minimize I/O""" + + def __init__(self, locales_folder: Union[str, Path, None] = None) -> None: + if locales_folder is None: + locales_folder = Path(sync.config_get("locale", "locations")) + elif isinstance(locales_folder, str): + locales_folder = Path(locales_folder) + elif not isinstance(locales_folder, Path): + raise TypeError("'locales_folder' must be a valid path or path-like object") + + files_locales: list = listdir(locales_folder) + + valid_locales: list = [ + ".".join(entry.split(".")[:-1]) for entry in files_locales + ] + + self.default: str = sync.config_get("locale") + self.locales: dict = {} + + for lc in valid_locales: + self.locales[lc] = sync.json_read(Path(f"{locales_folder}/{lc}.json")) + + def _(self, key: str, *args: str, locale: Union[str, None] = None) -> Any: + """Get value of locale string + + ### Args: + * key (`str`): The last key of the locale's keys path + * *args (`list`): Path to key like: `dict[args][key]` + * locale (`Union[str, None]`, *optional*): Locale to looked up in. Defaults to config's `"locale"` value + + ### Returns: + * `Any`: Value of provided locale key. Is usually `str`, `dict` or `list` + """ + + if locale is None: + locale = self.default + + try: + this_dict = self.locales[locale] + except KeyError: + try: + this_dict = self.locales[self.default] + except KeyError: + return f'⚠️ Locale in config is invalid: could not get "{key}" in {args} from locale "{locale}"' + + this_key = this_dict + for dict_key in args: + this_key = this_key[dict_key] + + try: + return this_key[key] + except KeyError: + return f'⚠️ Locale in config is invalid: could not get "{key}" in {args} from locale "{locale}"' + + def in_all_locales(self, key: str, *args: str) -> list: + """Get value of the provided key and path in all available locales + + ### Args: + * key (`str`): The last key of the locale's keys path. + * *args (`list`): Path to key like: `dict[args][key]`. + + ### Returns: + * `list`: List of values in all locales + """ + + output = [] + + for name, lc in self.locales.items(): + try: + this_dict = lc + except KeyError: + continue + + this_key = this_dict + for dict_key in args: + this_key = this_key[dict_key] + + try: + output.append(this_key[key]) + except KeyError: + continue + + return output + + def in_every_locale(self, key: str, *args: str) -> Dict[str, Any]: + """Get value of the provided key and path in every available locale with locale tag + + ### Args: + * key (`str`): The last key of the locale's keys path. + * *args (`list`): Path to key like: `dict[args][key]`. + + ### Returns: + * `Dict[str, Any]`: Locale is a key and it's value from locale file is a value + """ + + output = {} + + for name, lc in self.locales.items(): + try: + this_dict = lc + except KeyError: + continue + + this_key = this_dict + for dict_key in args: + this_key = this_key[dict_key] + + try: + output[name] = this_key[key] + except KeyError: + continue + + return output