77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
import json
|
|
import logging
|
|
from functools import lru_cache
|
|
from pathlib import Path
|
|
|
|
from django.http import HttpRequest, JsonResponse
|
|
from django.utils.translation import get_language_from_request
|
|
|
|
LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
@lru_cache(maxsize=1)
|
|
def lobby_i18n_catalog() -> dict:
|
|
catalog_path = Path(__file__).resolve().parents[1] / "shared" / "i18n" / "lobby.json"
|
|
with catalog_path.open(encoding="utf-8") as handle:
|
|
return json.load(handle)
|
|
|
|
|
|
@lru_cache(maxsize=1)
|
|
def i18n_locale_config() -> tuple[str, tuple[str, ...]]:
|
|
locales = lobby_i18n_catalog().get("locales", {})
|
|
default_locale = str(locales.get("default", "en")).strip().lower() or "en"
|
|
supported_locales = tuple(
|
|
locale.strip().lower() for locale in locales.get("supported", ["en", "da"]) if str(locale).strip()
|
|
) or ("en", "da")
|
|
return default_locale, supported_locales
|
|
|
|
|
|
def lobby_i18n_errors() -> dict:
|
|
return lobby_i18n_catalog().get("backend", {}).get("error_codes", {})
|
|
|
|
|
|
def lobby_i18n_error_messages() -> dict:
|
|
return lobby_i18n_catalog().get("backend", {}).get("errors", {})
|
|
|
|
|
|
def resolve_locale(request: HttpRequest) -> str:
|
|
default_locale, supported_locales = i18n_locale_config()
|
|
|
|
raw_accept_language = (request.META.get("HTTP_ACCEPT_LANGUAGE") or "").split(",", 1)[0]
|
|
raw_requested = raw_accept_language.split(";", 1)[0].strip().replace("_", "-").split("-", 1)[0].lower()
|
|
if raw_requested in supported_locales:
|
|
return raw_requested
|
|
|
|
requested = (get_language_from_request(request) or "").replace("_", "-").split("-", 1)[0].lower()
|
|
if requested in supported_locales:
|
|
return requested
|
|
return default_locale
|
|
|
|
|
|
def resolve_error_message(*, key: str, locale: str) -> str:
|
|
default_locale, _supported_locales = i18n_locale_config()
|
|
translations = lobby_i18n_error_messages().get(key)
|
|
if not isinstance(translations, dict):
|
|
LOGGER.warning("i18n key missing in shared catalog", extra={"key": key, "locale": locale})
|
|
return key
|
|
|
|
if locale in translations and translations[locale]:
|
|
return translations[locale]
|
|
if default_locale in translations and translations[default_locale]:
|
|
return translations[default_locale]
|
|
|
|
LOGGER.warning("i18n translation missing for key", extra={"key": key, "locale": locale})
|
|
return key
|
|
|
|
|
|
def api_error(request: HttpRequest, *, key: str, status: int) -> JsonResponse:
|
|
locale = resolve_locale(request)
|
|
return JsonResponse(
|
|
{
|
|
"error": resolve_error_message(key=key, locale=locale),
|
|
"error_code": key,
|
|
"locale": locale,
|
|
},
|
|
status=status,
|
|
)
|