nlbone 0.7.30__py3-none-any.whl → 0.7.31__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nlbone/adapters/i18n/__init__.py +7 -3
- nlbone/adapters/i18n/engine.py +10 -3
- nlbone/adapters/i18n/loaders.py +35 -12
- nlbone/adapters/i18n/locales/fa-IR.json +0 -7
- nlbone/config/settings.py +2 -0
- {nlbone-0.7.30.dist-info → nlbone-0.7.31.dist-info}/METADATA +1 -1
- {nlbone-0.7.30.dist-info → nlbone-0.7.31.dist-info}/RECORD +10 -10
- {nlbone-0.7.30.dist-info → nlbone-0.7.31.dist-info}/WHEEL +0 -0
- {nlbone-0.7.30.dist-info → nlbone-0.7.31.dist-info}/entry_points.txt +0 -0
- {nlbone-0.7.30.dist-info → nlbone-0.7.31.dist-info}/licenses/LICENSE +0 -0
nlbone/adapters/i18n/__init__.py
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
+
from nlbone.config.settings import get_settings
|
|
4
|
+
|
|
3
5
|
from .engine import I18nAdapter
|
|
4
|
-
from .loaders import JSONFileLoader
|
|
6
|
+
from .loaders import JSONFileLoader, CompositeLoader
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
loader = CompositeLoader()
|
|
9
|
+
loader.add_loader(JSONFileLoader(locales_path=Path(__file__).parent.joinpath("./locales").__str__()))
|
|
10
|
+
JSONFileLoader(locales_path=lambda: get_settings().PROJECT_LOCALE_PATH)
|
|
11
|
+
translator = I18nAdapter(loader=loader, default_locale="fa-IR")
|
nlbone/adapters/i18n/engine.py
CHANGED
|
@@ -7,12 +7,19 @@ from .loaders import BaseLoader
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class I18nAdapter(TranslationPort):
|
|
10
|
-
def __init__(self, loader: BaseLoader, default_locale: str = "fa"):
|
|
10
|
+
def __init__(self, loader: BaseLoader, default_locale: str = "fa-IR"):
|
|
11
11
|
self.default_locale = default_locale
|
|
12
|
-
self.
|
|
12
|
+
self.loader = loader
|
|
13
|
+
self._translations: Optional[Dict[str, Dict[str, str]]] = None
|
|
14
|
+
|
|
15
|
+
def _ensure_loaded(self):
|
|
16
|
+
if self._translations is None:
|
|
17
|
+
self._translations = self.loader.load()
|
|
13
18
|
|
|
14
19
|
def translate(self, key: str, locale: Optional[str] = None, **kwargs) -> str:
|
|
15
|
-
|
|
20
|
+
self._ensure_loaded()
|
|
21
|
+
|
|
22
|
+
target_locale = locale or self.default_locale
|
|
16
23
|
|
|
17
24
|
locale_data = self._translations.get(target_locale, {})
|
|
18
25
|
text = locale_data.get(key)
|
nlbone/adapters/i18n/loaders.py
CHANGED
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Any, Dict
|
|
5
|
+
from typing import Any, Dict, List, Callable, Union
|
|
6
6
|
|
|
7
7
|
logger = logging.getLogger(__name__)
|
|
8
8
|
|
|
@@ -13,33 +13,38 @@ class BaseLoader(ABC):
|
|
|
13
13
|
pass
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
from typing import Callable, Union
|
|
17
|
+
|
|
18
|
+
|
|
16
19
|
class JSONFileLoader(BaseLoader):
|
|
17
|
-
def __init__(self, locales_path: str):
|
|
18
|
-
self.
|
|
20
|
+
def __init__(self, locales_path: Union[str, Callable[[], str]]):
|
|
21
|
+
self.locales_path_provider = locales_path
|
|
19
22
|
|
|
20
23
|
def load(self) -> Dict[str, Dict[str, str]]:
|
|
21
24
|
translations: Dict[str, Dict[str, str]] = {}
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
if callable(self.locales_path_provider):
|
|
27
|
+
path_str = self.locales_path_provider()
|
|
28
|
+
else:
|
|
29
|
+
path_str = self.locales_path_provider
|
|
30
|
+
|
|
31
|
+
if not path_str:
|
|
32
|
+
return translations
|
|
33
|
+
|
|
34
|
+
path_obj = Path(path_str)
|
|
24
35
|
|
|
25
36
|
if not path_obj.exists():
|
|
26
|
-
logger.warning(f"Locales directory not found at: {self.locales_path}")
|
|
27
37
|
return translations
|
|
28
38
|
|
|
29
39
|
for file_path in path_obj.glob("*.json"):
|
|
30
40
|
try:
|
|
31
41
|
lang_code = file_path.stem
|
|
32
|
-
|
|
33
42
|
with open(file_path, "r", encoding="utf-8") as f:
|
|
34
43
|
data = json.load(f)
|
|
35
44
|
|
|
36
45
|
flat_data = self._flatten_dict(data)
|
|
37
46
|
translations[lang_code] = flat_data
|
|
38
47
|
|
|
39
|
-
logger.info(f"Loaded locale '{lang_code}' with {len(flat_data)} keys.")
|
|
40
|
-
|
|
41
|
-
except json.JSONDecodeError as e:
|
|
42
|
-
logger.error(f"Invalid JSON format in {file_path}: {e}")
|
|
43
48
|
except Exception as e:
|
|
44
49
|
logger.error(f"Error loading locale {file_path}: {e}")
|
|
45
50
|
|
|
@@ -49,10 +54,28 @@ class JSONFileLoader(BaseLoader):
|
|
|
49
54
|
items = []
|
|
50
55
|
for k, v in d.items():
|
|
51
56
|
new_key = f"{parent_key}{sep}{k}" if parent_key else k
|
|
52
|
-
|
|
53
57
|
if isinstance(v, dict):
|
|
54
58
|
items.extend(self._flatten_dict(v, new_key, sep=sep).items())
|
|
55
59
|
else:
|
|
56
60
|
items.append((new_key, str(v)))
|
|
57
|
-
|
|
58
61
|
return dict(items)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class CompositeLoader(BaseLoader):
|
|
65
|
+
def __init__(self):
|
|
66
|
+
self.loaders = []
|
|
67
|
+
|
|
68
|
+
def add_loader(self, loader: BaseLoader):
|
|
69
|
+
self.loaders.append(loader)
|
|
70
|
+
|
|
71
|
+
def load(self) -> Dict[str, Dict[str, str]]:
|
|
72
|
+
merged_translations: Dict[str, Dict[str, str]] = {}
|
|
73
|
+
|
|
74
|
+
for loader in self.loaders:
|
|
75
|
+
data = loader.load()
|
|
76
|
+
for lang, keys in data.items():
|
|
77
|
+
if lang not in merged_translations:
|
|
78
|
+
merged_translations[lang] = {}
|
|
79
|
+
merged_translations[lang].update(keys)
|
|
80
|
+
|
|
81
|
+
return merged_translations
|
nlbone/config/settings.py
CHANGED
|
@@ -113,6 +113,8 @@ class Settings(BaseSettings):
|
|
|
113
113
|
RABBITMQ_TICKETING_EXCHANGE: str = "crm_stage.ticket"
|
|
114
114
|
RABBITMQ_TICKETING_ROUTING_KEY_CREATE_V1: str = "crm_stage.ticket.create.v1"
|
|
115
115
|
|
|
116
|
+
PROJECT_LOCALE_PATH: str = ""
|
|
117
|
+
|
|
116
118
|
model_config = SettingsConfigDict(
|
|
117
119
|
env_prefix="",
|
|
118
120
|
env_file=None,
|
|
@@ -30,10 +30,10 @@ nlbone/adapters/http_clients/pricing/pricing_service.py,sha256=_15vyEwJD3S2DJG-y
|
|
|
30
30
|
nlbone/adapters/http_clients/uploadchi/__init__.py,sha256=uBzEOuVtY22teWW2b36Pitkdk5yVdSqa6xbg22JfTNg,105
|
|
31
31
|
nlbone/adapters/http_clients/uploadchi/uploadchi.py,sha256=erpjOees25FW0nuK1PkYS-oU0h8MeRV9Rhs1cf3gaEs,4881
|
|
32
32
|
nlbone/adapters/http_clients/uploadchi/uploadchi_async.py,sha256=PQbVNeaYde5CmgT3vcnQoI1PGeSs9AxHlPFuB8biOmU,4717
|
|
33
|
-
nlbone/adapters/i18n/__init__.py,sha256=
|
|
34
|
-
nlbone/adapters/i18n/engine.py,sha256=
|
|
35
|
-
nlbone/adapters/i18n/loaders.py,sha256=
|
|
36
|
-
nlbone/adapters/i18n/locales/fa-IR.json,sha256=
|
|
33
|
+
nlbone/adapters/i18n/__init__.py,sha256=fS97TR7HEc7fiDC2ufQKoFOxXDNkGA4njAFIB3EmhLk,426
|
|
34
|
+
nlbone/adapters/i18n/engine.py,sha256=55DbbVPPHG64o640BzWDsjaxRfu6GykZzVBqME03iDE,1078
|
|
35
|
+
nlbone/adapters/i18n/loaders.py,sha256=7td0Cmn0ehjDO2S2qeH31zwl8UyWI7quzedP9PnPhWk,2381
|
|
36
|
+
nlbone/adapters/i18n/locales/fa-IR.json,sha256=QL4XSuSIL82wYhBrvyOAoMM0rG9yjKuOue43_YItuSM,208
|
|
37
37
|
nlbone/adapters/messaging/__init__.py,sha256=o6ZiMihm_MhRXfcEpcjHBB3JGQovQbg3pxe0qS6516c,41
|
|
38
38
|
nlbone/adapters/messaging/event_bus.py,sha256=MSM70JPHoDK17efWlh20ATT1O0KW7xWnwZ5D-gI6U_w,3773
|
|
39
39
|
nlbone/adapters/messaging/rabbitmq.py,sha256=Io3flSj8DMIHExJguh3hDgWT4LuDoPYb_xmQQ3k47Cs,1894
|
|
@@ -47,7 +47,7 @@ nlbone/adapters/ticketing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
47
47
|
nlbone/adapters/ticketing/client.py,sha256=J1-eT3qQDAJqrHcVpP1oqWNsRNnJ54dDdBeez-m9wyY,1291
|
|
48
48
|
nlbone/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
49
|
nlbone/config/logging.py,sha256=Ot6Ctf7EQZlW8YNB-uBdleqI6wixn5fH0Eo6QRgNkQk,4358
|
|
50
|
-
nlbone/config/settings.py,sha256=
|
|
50
|
+
nlbone/config/settings.py,sha256=vOB8RQ5iBdbRpvcbBF7Cdpr9IwdarrHPz-ncQ_yQA8g,4785
|
|
51
51
|
nlbone/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
52
|
nlbone/core/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
53
|
nlbone/core/application/base_worker.py,sha256=5brIToSd-vi6tw0ukhHnUZGZhOLq1SQ-NRRy-kp6D24,1193
|
|
@@ -114,8 +114,8 @@ nlbone/utils/http.py,sha256=0yeI34j5FfelqvX3PJnKknSXji1jl15VYbVIIvrSbXg,997
|
|
|
114
114
|
nlbone/utils/normalize_mobile.py,sha256=sGH4tV9gX-6eVKozviNWJhm1DN1J28Nj-ERldCYkS_E,732
|
|
115
115
|
nlbone/utils/redactor.py,sha256=-V4HrHmHwPi3Kez587Ek1uJlgK35qGSrwBOvcbw8Jas,1279
|
|
116
116
|
nlbone/utils/time.py,sha256=DjjyQ9GLsfXoT6NK8RDW2rOlJg3e6sF04Jw6PBUrSvg,1268
|
|
117
|
-
nlbone-0.7.
|
|
118
|
-
nlbone-0.7.
|
|
119
|
-
nlbone-0.7.
|
|
120
|
-
nlbone-0.7.
|
|
121
|
-
nlbone-0.7.
|
|
117
|
+
nlbone-0.7.31.dist-info/METADATA,sha256=18DKVQix7O0AX3SAPyjkekbvQpeNzlizIQ0KVPW3E8s,2295
|
|
118
|
+
nlbone-0.7.31.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
119
|
+
nlbone-0.7.31.dist-info/entry_points.txt,sha256=CpIL45t5nbhl1dGQPhfIIDfqqak3teK0SxPGBBr7YCk,59
|
|
120
|
+
nlbone-0.7.31.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
121
|
+
nlbone-0.7.31.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|