Compare commits

...

11 Commits

Author SHA1 Message Date
SantaSpeen 8792aaeeb9 [+] dedent fix 2025-05-13 18:43:21 +03:00
SantaSpeen 774a1b0ce3 [+] dedent 2025-05-13 18:35:31 +03:00
SantaSpeen 633c92608f [^] url 2025-03-24 00:55:49 +03:00
SantaSpeen 3f0fe22317 [КОСТЫЛЬ] if no {} in phrase - str JUST NOW 2025-03-23 05:34:26 +03:00
SantaSpeen 2a3eca2c31 [-] print 2025-03-23 04:19:19 +03:00
SantaSpeen f26cc65c7f .idea 2025-03-23 04:11:03 +03:00
SantaSpeen 0b9f8b6feb [!] fix2 __getattr__ 2025-03-23 03:45:30 +03:00
SantaSpeen 3581e6ae44 [!] fix __setattr__ 2025-03-23 03:00:10 +03:00
SantaSpeen c261f7e140 [^] builtins hack 2025-03-23 02:52:54 +03:00
SantaSpeen cf50296264 [+] NestedAccessor
[+] support __getattr__
[+] support some.key.here
2025-03-23 02:40:47 +03:00
SantaSpeen 6a0347e7c4 [-] resources 2025-03-23 02:23:23 +03:00
4 changed files with 109 additions and 5 deletions
+1
View File
@@ -168,3 +168,4 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
resources/
+1 -1
View File
@@ -21,5 +21,5 @@ fmt = "<green>{elapsed} -- {time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{leve
Добавление в проект: Добавление в проект:
```bash ```bash
git submodule add ssh://git@git.anidev.ru:222/andiev-soft/I18N-Module src/modules/i18n git submodule add ssh://git@git.anidev.ru:222/AnidevSoft/I18N-Module.git src/modules/i18n
``` ```
+32 -1
View File
@@ -1,3 +1,23 @@
class _i18_proxy:
@staticmethod
def __getattr__(item):
"""
Get the phrase from the locale file. If the phrase is not found, return the key in uppercase.
:param key: Key to search in the locale file.
:param kwargs: Arguments to format the phrase.
:return: The phrase from the locale file.
"""
@staticmethod
def __init__(**kwargs):
"""
Get the phrase from the locale file. If the phrase is not found, return the key in uppercase.
:param key: Key to search in the locale file.
:param kwargs: Arguments to format the phrase.
:return: The phrase from the locale file.
"""
class i18n: class i18n:
@staticmethod @staticmethod
def set_lang(lang, encoding=None) -> None: def set_lang(lang, encoding=None) -> None:
@@ -17,7 +37,18 @@ class i18n:
:return: The phrase from the locale file. :return: The phrase from the locale file.
""" """
@staticmethod @staticmethod
def __call__(key: str, **kwargs) -> str: def __getattr__(item):
"""
Get the phrase from the locale file. If the phrase is not found, return the key in uppercase.
:param key: Key to search in the locale file.
:param kwargs: Arguments to format the phrase.
:return: The phrase from the locale file.
"""
key = item.replace("_", ".") # заменяем _ на . для удобства
return _i18_proxy([key]) # Начинаем цепочку
@staticmethod
def __init__(key: str, **kwargs) -> str:
""" """
Get the phrase from the locale file. If the phrase is not found, return the key in uppercase. Get the phrase from the locale file. If the phrase is not found, return the key in uppercase.
+74 -2
View File
@@ -1,14 +1,65 @@
import builtins import builtins
import textwrap
from collections import defaultdict from collections import defaultdict
import json5 import json5
from loguru import logger from loguru import logger
try:
from . import utils from . import utils
except ImportError:
import utils
log = logger.bind(module="i18n", prefix="init") log = logger.bind(module="i18n", prefix="init")
log_load = logger.bind(module="i18n", prefix="load") log_load = logger.bind(module="i18n", prefix="load")
str_funcs = {attr for attr in dir(str)}
str_funcs.add('__func__')
str_funcs.remove('__init__')
str_funcs.remove('__len__')
str_funcs.remove('__hash__')
str_funcs.remove('__add__')
str_funcs.remove('__str__')
str_funcs.remove('__repr__')
class NestedAccessor:
def __init__(self, parent, key_chain):
self.parent: "I18N" = parent
self.key_chain = key_chain
self.__name__ = f'\r<{".".join(key_chain)}>'.upper()
# self.__func__ = self.key_chain
def __getattr__(self, item):
# Если нет метода, то возвращаем str
key = ".".join((*self.key_chain, item))
if key in self.parent.locale:
if "{" not in self.parent.locale[key]:
return self.parent.get_phrase(key)
if item in str_funcs:
return getattr(self(), item)
return NestedAccessor(self.parent, self.key_chain + [item])
def __len__(self):
return len(self())
def __hash__(self):
return hash(self())
def __call__(self, **kwargs):
key = ".".join(self.key_chain)
return self.parent.get_phrase(key, **kwargs)
def __add__(self, other):
return self() + other
def __str__(self):
return self()
def __repr__(self):
return f"<NestedAccessor key={'.'.join(self.key_chain)}>"
class I18N: class I18N:
def __init__(self, locale_dir, load_lang, encoding): def __init__(self, locale_dir, load_lang, encoding):
@@ -29,6 +80,10 @@ class I18N:
log.debug("Ready") log.debug("Ready")
self._load() self._load()
@property
def locale(self):
return self._locale
def _load(self): def _load(self):
if not self._locale_dir: if not self._locale_dir:
raise FileNotFoundError(f"Locale directory not found: {self._locale_dir}") raise FileNotFoundError(f"Locale directory not found: {self._locale_dir}")
@@ -63,11 +118,28 @@ class I18N:
# key: some.key.here # key: some.key.here
phrase = self._locale.get(key) phrase = self._locale.get(key)
if not phrase: if not phrase:
return key.upper() return f"<{key.upper()}>"
return phrase.format_map(defaultdict(lambda: '???', kwargs)) return textwrap.dedent(phrase.format_map(defaultdict(lambda: '<unknown>', kwargs)))
def __getattr__(self, item):
key = item.replace("_", ".") # заменяем _ на . для удобства
return NestedAccessor(self, [key]) # Начинаем цепочку
def __call__(self, key: str, **kwargs): def __call__(self, key: str, **kwargs):
return self.get_phrase(key, **kwargs) return self.get_phrase(key, **kwargs)
def __getitem__(self, key: str): def __getitem__(self, key: str):
return self.get_phrase(key) return self.get_phrase(key)
if __name__ == '__main__':
i18n = I18N("", "ru", "utf-8")
print(1, i18n.get_phrase("some.key.here", name="John"))
print(2, i18n("some.key.here", name="John"))
print(3, i18n["some.key.here"])
print(4, i18n.some_key_here(name="John"))
print(5, i18n.some_key_here)
print(6, i18n.some.key.here(name="John"))
print(7, i18n.some.key.here)
print(8, i18n.some.key.no.registered)