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() requested = (get_language_from_request(request) or "").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, )