Files
drf-rack/net/xeaf/rack/managers/locale_manager.py

127 lines
4.2 KiB
Python

# DRF Rack
# Библиотека классов расширений для Django REST Framework
#
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
# Все права защищены. Лицензия: MIT
"""
Описание класса LocaleManager
"""
from django.conf import settings
from django.utils import translation
from rest_framework.request import Request
from net.xeaf.rack.enums import UILanguage
class LocaleManager:
"""
Реализует методы работы с локализацией
"""
UI_LANGUAGE_PARAM = "x-ui-language"
""" Идентификатор параметра языка интерфейса """
UI_LANGUAGE_META = "HTTP_ACCEPT_LANGUAGE"
""" Идентификатор заголовка языка интерфейса """
@classmethod
def get_default_language(cls) -> UILanguage:
"""
Возвращает языка интерфейса пользователя по умолчанию
:return: Язык интерфейса пользователя по умолчанию
"""
return UILanguage.from_string(settings.LANGUAGE_CODE)
@classmethod
def get_accepted_language(cls, language_code: str) -> UILanguage:
"""
Проверяет и возвращает допустимый код языка
:param language_code: Код языка интерфейса пользователя
:return: Допустимый код языка интерфейса пользователя
"""
try:
return UILanguage.from_string(language_code)
except ValueError:
return cls.get_default_language()
@classmethod
def get_request_language(cls, request: Request | None) -> UILanguage:
"""
Возвращает идентификатор языка из запроса
:param request: Информация о запросе
:return: Язык интерфейса пользователя из запроса
"""
if not request:
return cls.get_default_language()
if request.method == "GET":
language_code = request.query_params.get(cls.UI_LANGUAGE_PARAM, None)
if language_code:
return cls.get_accepted_language(language_code=language_code)
try:
language_code = cls.process_accepted_language(request)
return cls.get_accepted_language(language_code=language_code)
except KeyError:
return cls.get_default_language()
@classmethod
def set_request_language(cls, request: Request | None, ui_language: UILanguage) -> None:
"""
Задает язык интерфейса пользователя для запроса
:param request: Информация о запросе
:param ui_language: Язык интерфейса пользователя
"""
translation.activate(str(ui_language).lower())
if request:
request.LANGUAGE_CODE = str(translation.get_language()).upper()
@classmethod
def process_accepted_language(cls, request: Request) -> str:
"""
Обрабатывает значение META_ACCEPTED_LANGUAGE
:param request: Информация о запросе
:return: Код языка интерфейса пользователя из запроса
"""
index = -1
result = cls.get_default_language()
language = request.META[cls.UI_LANGUAGE_META]
for ui_lang in UILanguage.values():
lang = ui_lang.lower()
try:
idx = language.index(lang)
if index == -1 or idx < index:
index = idx
result = lang
except ValueError:
pass
return result
@classmethod
def adjust_request_language(cls, request: Request) -> None:
"""
Настраивает язык интерфейса пользователя
:param request: Информация о запросе
"""
language = cls.get_request_language(request)
cls.set_request_language(request, language)