1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
"""
flask_security.babel
~~~~~~~~~~~~~~~~~~~~
I18N support for Flask-Security.
:copyright: (c) 2019-2023 by J. Christopher Wagner (jwag).
:license: MIT, see LICENSE for more details.
As of Flask-Babel 2.0.0 - it supports the Flask-BabelEx Domain extension - and it
is maintained. If that isn't installed fall back to a Null Domain
"""
# flake8: noqa: F811
from collections.abc import Iterable
import atexit
from contextlib import ExitStack
from importlib.resources import files, as_file
from flask import current_app
from .utils import config_value as cv
def has_babel_ext():
# Has the application initialized the appropriate babel extension....
return current_app and "babel" in current_app.extensions
try:
from flask_babel import Domain, get_locale
from babel.support import LazyProxy
from babel.lists import format_list
class FsDomain(Domain):
def __init__(self, app):
# By default, we use our packaged translations. However, we have to allow
# for app to add translation directories or completely override ours.
# Grabbing the packaged translations is a bit complex - so we use
# the keyword 'builtin' to mean ours.
cfdir = cv("I18N_DIRNAME", app=app)
if cfdir == "builtin" or (
isinstance(cfdir, Iterable) and "builtin" in cfdir
):
fm = ExitStack()
atexit.register(fm.close)
ref = files("flask_security") / "translations"
path = fm.enter_context(as_file(ref))
if cfdir == "builtin":
dirs = [str(path)]
else:
dirs = [d if d != "builtin" else str(path) for d in cfdir]
else:
dirs = cfdir
super().__init__(
**{
"domain": cv("I18N_DOMAIN", app=app),
"translation_directories": dirs,
}
)
def gettext(self, string, **variables):
if not has_babel_ext():
return string if not variables else string % variables
return super().gettext(string, **variables)
def ngettext(self, singular, plural, num, **variables): # pragma: no cover
if not has_babel_ext():
variables.setdefault("num", num)
return (singular if num == 1 else plural) % variables
return super().ngettext(singular, plural, num, **variables)
@staticmethod
def format_list(lst, **kwargs):
# This is a Babel method
if not has_babel_ext():
return ", ".join(lst)
ll = get_locale()
return format_list(lst, locale=get_locale(), **kwargs)
def is_lazy_string(obj):
"""Checks if the given object is a lazy string."""
return isinstance(obj, LazyProxy)
def make_lazy_string(__func, msg):
"""Creates a lazy string by invoking func with args."""
return LazyProxy(__func, msg, enable_cache=False)
except ImportError: # pragma: no cover
# Fake up just enough
class FsDomain: # type: ignore[no-redef]
def __init__(self, app):
pass
@staticmethod
def gettext(string, **variables):
return string if not variables else string % variables
@staticmethod
def ngettext(singular, plural, num, **variables):
variables.setdefault("num", num)
return (singular if num == 1 else plural) % variables
@staticmethod
def format_list(lst, **kwargs):
# This is a Babel method
if not has_babel_ext():
return ", ".join(lst)
def is_lazy_string(obj):
return False
def make_lazy_string(__func, msg):
return msg
|