Source code for schedula.utils.form.server.locale

# coding=utf-8
# -*- coding: UTF-8 -*-
#
# Copyright 2015-2025, Vincenzo Arcidiacono;
# Licensed under the EUPL (the 'Licence');
# You may not use this work except in compliance with the Licence.
# You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl

"""
It provides functions to build the language service.
"""
import os
import functools
import os.path as osp
from flask_babel import Babel, Domain
from werkzeug.exceptions import NotFound
from werkzeug.datastructures.accept import LanguageAccept
from flask import (
    jsonify, current_app, request, session, Blueprint, send_from_directory
)

bp = Blueprint('locales', __name__)


[docs] @functools.lru_cache() def get_domain(domain): return Domain(domain=domain)
[docs] def lazy_gettext(*args, domain=None, **kwargs): return get_domain(domain).lazy_gettext(*args, **kwargs)
[docs] @bp.route('/<language>/<namespace>', methods=['GET']) def locales(language, namespace): for d in current_app.extensions['babel'].translation_directories: try: return send_from_directory( d, f'{osp.join(language, "LC_MESSAGES", namespace)}.po', as_attachment=True ) except NotFound: pass raise NotFound()
[docs] @bp.route('/languages.json', methods=['GET']) def get_locales(): return jsonify(current_app.config.get('BABEL_LANGUAGES'))
[docs] def _set_locale(languages): get = current_app.config.get session['locale'] = locale = languages.best_match( get('BABEL_LANGUAGES'), get('BABEL_DEFAULT_LOCALE') ) return locale
[docs] @bp.route('/<lang>', methods=['POST']) def set_locale(lang): languages = LanguageAccept([(lang, 2)] + request.accept_languages) return jsonify({"language": _set_locale(languages)})
[docs] @bp.route('/<lang>', methods=['GET']) def get_locale(lang): locale = session.get('locale') if not locale: return set_locale(lang) return jsonify({"language": locale})
[docs] def _get_locale(): return session.get('locale') or _set_locale(request.accept_languages)
[docs] class Locales:
[docs] def __init__(self, app, *args, **kwargs): if app is not None: self.init_app(app, *args, **kwargs)
[docs] def init_app(self, app, *args, locale_selector=_get_locale, **kwargs): app.extensions = getattr(app, 'extensions', {}) app.config['BABEL_DEFAULT_LOCALE'] = app.config.get( 'BABEL_DEFAULT_LOCALE', os.environ.get( 'BABEL_DEFAULT_LOCALE', 'en_US' ) ) app.config['BABEL_LANGUAGES'] = app.config.get( 'BABEL_LANGUAGES', { 'af_ZA': {"icon": "🇿🇦", "label": "Afrikaans"}, 'ca_ES': {"icon": "🇪🇸", "label": "Català"}, 'da_DK': {"icon": "🇩🇰", "label": "Dansk"}, 'de_DE': {"icon": "🇩🇪", "label": "Deutsch"}, 'en_US': {"icon": "🇺🇸", "label": "English"}, 'es_ES': {"icon": "🇪🇸", "label": "Español"}, 'eu_ES': {"icon": "🇪🇸", "label": "Euskara"}, 'fr_FR': {"icon": "🇫🇷", "label": "Français"}, 'hu_HU': {"icon": "🇭🇺", "label": "Magyar"}, 'hy_AM': {"icon": "🇦🇲", "label": "Հայերեն"}, 'is_IS': {"icon": "🇮🇸", "label": "Íslenska"}, 'it_IT': {"icon": "🇮🇹", "label": "Italiano"}, 'ja_JP': {"icon": "🇯🇵", "label": "日本語"}, 'nl_NL': {"icon": "🇳🇱", "label": "Nederlands"}, 'pl_PL': {"icon": "🇵🇱", "label": "Polski"}, 'pt_BR': {"icon": "🇧🇷", "label": "Português (Brasil)"}, 'pt_PT': {"icon": "🇵🇹", "label": "Português (Portugal)"}, 'ru_RU': {"icon": "🇷🇺", "label": "Русский"}, 'tr_TR': {"icon": "🇹🇷", "label": "Türkçe"}, 'zh_Hans_CN': {"icon": "🇨🇳", "label": "中文(简体)"} } ) directories = [] it = app.config.get( 'BABEL_TRANSLATION_DIRECTORIES', os.environ.get('BABEL_TRANSLATION_DIRECTORIES', 'translations') ) if isinstance(it, str): it = [it] for k in it: directories.extend(k.split(';')) if not directories: directories.append('translations') tdir = osp.join(osp.dirname(__file__), 'translations') if tdir not in directories: directories.append(tdir) app.config['BABEL_TRANSLATION_DIRECTORIES'] = ';'.join(directories) Babel(app, *args, locale_selector=locale_selector, **kwargs) app.register_blueprint(bp, url_prefix='/locales') app.extensions['locates'] = self