Skip to content

Commit 86dc879

Browse files
committed
Rend l'i18n plugins universel et synchro avec l'app
1 parent 78244ea commit 86dc879

2 files changed

Lines changed: 92 additions & 5 deletions

File tree

Core/i18n.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,13 @@ def _on_result(res):
856856
engines_loader.registry.apply_translations(self, tr)
857857
except Exception:
858858
pass
859+
# Propagate translations to plugin SDK (independent from BCASL)
860+
try:
861+
from Plugins_SDK.GeneralContext import apply_translations as sdk_apply_tr
862+
863+
sdk_apply_tr(self, tr)
864+
except Exception:
865+
pass
859866
except Exception:
860867
pass
861868
meta = tr.get("_meta", {})

Plugins_SDK/GeneralContext/i18n.py

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from __future__ import annotations
1717

1818
from typing import Any, Optional, Callable
19+
import os
20+
import json
1921

2022
_GLOBAL_TR: dict[str, Any] = {}
2123
_GLOBAL_LANG: str = "en"
@@ -96,10 +98,16 @@ def register_plugin_translations(plugin_id: str, tr: dict) -> None:
9698

9799
def translate(plugin_id: str, key: str, default: Optional[str] = None) -> str:
98100
try:
99-
if plugin_id and plugin_id in _PLUGIN_TR:
100-
val = _PLUGIN_TR[plugin_id].get(key)
101-
if isinstance(val, str):
102-
return val
101+
if plugin_id:
102+
if plugin_id in _PLUGIN_TR:
103+
val = _PLUGIN_TR[plugin_id].get(key)
104+
if isinstance(val, str):
105+
return val
106+
low = str(plugin_id).lower()
107+
if low in _PLUGIN_TR:
108+
val = _PLUGIN_TR[low].get(key)
109+
if isinstance(val, str):
110+
return val
103111
except Exception:
104112
pass
105113
try:
@@ -125,6 +133,10 @@ def unregister_i18n_handler(fn: Callable[[Any, dict], None]) -> None:
125133

126134
def apply_translations(gui, tr: dict) -> None:
127135
set_translations(gui, tr)
136+
try:
137+
_load_all_plugin_languages(get_language_code())
138+
except Exception:
139+
pass
128140
for fn in list(_HANDLERS):
129141
try:
130142
fn(gui, tr)
@@ -136,7 +148,6 @@ def load_plugin_language_file(plugin_package: str, code: str) -> dict:
136148
"""Load language file for a plugin from its package's languages folder."""
137149
try:
138150
import importlib.resources as ilr
139-
import json
140151

141152
lang_data = {}
142153
if not plugin_package:
@@ -160,3 +171,72 @@ def load_plugin_language_file(plugin_package: str, code: str) -> dict:
160171
return lang_data
161172
except Exception:
162173
return {}
174+
175+
176+
def _discover_plugins_dir() -> str | None:
177+
try:
178+
base = os.path.abspath(
179+
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)
180+
)
181+
cand = os.path.join(base, "Plugins")
182+
if os.path.isdir(cand):
183+
return cand
184+
except Exception:
185+
pass
186+
return None
187+
188+
189+
def _load_plugin_languages_from_fs(plugins_dir: str, code: str) -> dict[str, dict]:
190+
data: dict[str, dict] = {}
191+
normalized = normalize_language_code(code)
192+
candidates = [
193+
f"{normalized}.json",
194+
f"{normalized.lower()}.json",
195+
"en.json",
196+
]
197+
try:
198+
for entry in os.listdir(plugins_dir):
199+
plugin_path = os.path.join(plugins_dir, entry)
200+
if not os.path.isdir(plugin_path):
201+
continue
202+
if not os.path.isfile(os.path.join(plugin_path, "__init__.py")):
203+
continue
204+
lang_dir = os.path.join(plugin_path, "languages")
205+
if not os.path.isdir(lang_dir):
206+
continue
207+
payload: dict = {}
208+
for name in candidates:
209+
p = os.path.join(lang_dir, name)
210+
if not os.path.isfile(p):
211+
continue
212+
try:
213+
with open(p, encoding="utf-8") as f:
214+
content = json.load(f)
215+
if isinstance(content, dict):
216+
payload.update(content)
217+
break
218+
except Exception:
219+
continue
220+
if payload:
221+
data[entry] = payload
222+
except Exception:
223+
pass
224+
return data
225+
226+
227+
def _load_all_plugin_languages(code: str) -> None:
228+
"""Load translations for all plugins in Plugins/ folder."""
229+
try:
230+
_PLUGIN_TR.clear()
231+
except Exception:
232+
pass
233+
plugins_dir = _discover_plugins_dir()
234+
if not plugins_dir:
235+
return
236+
data = _load_plugin_languages_from_fs(plugins_dir, code)
237+
for plugin_id, tr in data.items():
238+
register_plugin_translations(plugin_id, tr)
239+
try:
240+
register_plugin_translations(str(plugin_id).lower(), tr)
241+
except Exception:
242+
pass

0 commit comments

Comments
 (0)