# DRF Rack # Библиотека классов расширений для Django REST Framework # # Автор: Николай В. Анохин # Все права защищены. Лицензия: 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)