127 lines
4.2 KiB
Python
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)
|