mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-02-08 00:43:12 -05:00
Feature/improve localization (#1147)
* use locale to set language header * rewrite i18n provider and drop dependency * rename file * rename CrudMixin to HttpRepo * refactor: code-cleanup * add crowdin source * remove unused translations * grab translations from dev branch * add translation support for foods, units, and labels * remove rich import
This commit is contained in:
2
mealie/pkgs/i18n/__init__.py
Normal file
2
mealie/pkgs/i18n/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .json_provider import *
|
||||
from .provider_factory import *
|
||||
34
mealie/pkgs/i18n/json_provider.py
Normal file
34
mealie/pkgs/i18n/json_provider.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class JsonProvider:
|
||||
translations: dict
|
||||
|
||||
def __init__(self, path: Path | dict):
|
||||
if isinstance(path, Path):
|
||||
self.translations = json.loads(path.read_text())
|
||||
else:
|
||||
self.translations = path
|
||||
|
||||
def t(self, key: str, default=None, **kwargs) -> str:
|
||||
keys = key.split(".")
|
||||
|
||||
translation_value: dict | str = self.translations
|
||||
last = len(keys) - 1
|
||||
|
||||
for i, k in enumerate(keys):
|
||||
if k not in translation_value:
|
||||
break
|
||||
|
||||
try:
|
||||
translation_value = translation_value[k] # type: ignore
|
||||
except Exception:
|
||||
break
|
||||
|
||||
if i == last:
|
||||
return translation_value
|
||||
|
||||
return default or key
|
||||
43
mealie/pkgs/i18n/provider_factory.py
Normal file
43
mealie/pkgs/i18n/provider_factory.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
from .json_provider import JsonProvider
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class InUseProvider:
|
||||
provider: JsonProvider
|
||||
locks: int
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class ProviderFactory:
|
||||
directory: Path
|
||||
fallback_locale: str = "en-US"
|
||||
filename_format = "{locale}.{format}"
|
||||
|
||||
_store: dict[str, InUseProvider] = field(default_factory=dict)
|
||||
|
||||
@property
|
||||
def fallback_file(self) -> Path:
|
||||
return self.directory / self.filename_format.format(locale=self.fallback_locale, format="json")
|
||||
|
||||
def _load(self, locale: str) -> JsonProvider:
|
||||
filename = self.filename_format.format(locale=locale, format="json")
|
||||
path = self.directory / filename
|
||||
|
||||
return JsonProvider(path) if path.exists() else JsonProvider(self.fallback_file)
|
||||
|
||||
def release(self, locale) -> None:
|
||||
if locale in self._store:
|
||||
self._store[locale].locks -= 1
|
||||
if self._store[locale].locks == 0:
|
||||
del self._store[locale]
|
||||
|
||||
def get(self, locale: str) -> JsonProvider:
|
||||
if locale in self._store:
|
||||
self._store[locale].locks += 1
|
||||
else:
|
||||
self._store[locale] = InUseProvider(provider=self._load(locale), locks=1)
|
||||
|
||||
return self._store[locale].provider
|
||||
Reference in New Issue
Block a user