84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
import logging
|
|
|
|
from django.http import HttpRequest, JsonResponse
|
|
from django.utils.translation import get_language_from_request
|
|
|
|
from partyhub.i18n_bootstrap import locale_config, shared_i18n_catalog
|
|
|
|
LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
def lobby_i18n_catalog() -> dict:
|
|
return shared_i18n_catalog()
|
|
|
|
|
|
def i18n_locale_config() -> tuple[str, tuple[str, ...]]:
|
|
return locale_config()
|
|
|
|
|
|
def lobby_i18n_errors() -> dict:
|
|
return shared_i18n_catalog().get("backend", {}).get("error_codes", {})
|
|
|
|
|
|
def lobby_i18n_error_messages() -> dict:
|
|
return shared_i18n_catalog().get("backend", {}).get("errors", {})
|
|
|
|
|
|
def _quality_value(language_candidate: str) -> float | None:
|
|
for parameter in language_candidate.split(";")[1:]:
|
|
key, separator, value = parameter.partition("=")
|
|
if separator and key.strip().lower() == "q":
|
|
try:
|
|
return float(value.strip())
|
|
except ValueError:
|
|
return None
|
|
return None
|
|
|
|
|
|
def resolve_locale(request: HttpRequest) -> str:
|
|
default_locale, supported_locales = i18n_locale_config()
|
|
|
|
accept_language = request.META.get("HTTP_ACCEPT_LANGUAGE") or ""
|
|
for candidate in accept_language.split(","):
|
|
quality = _quality_value(candidate)
|
|
if quality is not None and quality <= 0:
|
|
continue
|
|
|
|
tag = candidate.split(";", 1)[0]
|
|
normalized = tag.strip().replace("_", "-").split("-", 1)[0].lower()
|
|
if normalized in supported_locales:
|
|
return normalized
|
|
|
|
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,
|
|
)
|