codekingpro/portable-devtools
114k
1"""2 flask_security.babel3 ~~~~~~~~~~~~~~~~~~~~4 5 I18N support for Flask-Security.6 7 :copyright: (c) 2019-2023 by J. Christopher Wagner (jwag).8 :license: MIT, see LICENSE for more details.9 10 As of Flask-Babel 2.0.0 - it supports the Flask-BabelEx Domain extension - and it11 is maintained. If that isn't installed fall back to a Null Domain12"""13 14# flake8: noqa: F81115 16from collections.abc import Iterable17import atexit18from contextlib import ExitStack19from importlib_resources import files, as_file20 21from flask import current_app22from .utils import config_value as cv23 24 25def has_babel_ext():26 # Has the application initialized the appropriate babel extension....27 return current_app and "babel" in current_app.extensions28 29 30try:31 from flask_babel import Domain, get_locale32 from babel.support import LazyProxy33 from babel.lists import format_list34 35 class FsDomain(Domain):36 def __init__(self, app):37 # By default, we use our packaged translations. However, we have to allow38 # for app to add translation directories or completely override ours.39 # Grabbing the packaged translations is a bit complex - so we use40 # the keyword 'builtin' to mean ours.41 cfdir = cv("I18N_DIRNAME", app=app)42 if cfdir == "builtin" or (43 isinstance(cfdir, Iterable) and "builtin" in cfdir44 ):45 fm = ExitStack()46 atexit.register(fm.close)47 ref = files("flask_security") / "translations"48 path = fm.enter_context(as_file(ref))49 if cfdir == "builtin":50 dirs = [str(path)]51 else:52 dirs = [d if d != "builtin" else str(path) for d in cfdir]53 else:54 dirs = cfdir55 super().__init__(56 **{57 "domain": cv("I18N_DOMAIN", app=app),58 "translation_directories": dirs,59 }60 )61 62 def gettext(self, string, **variables):63 if not has_babel_ext():64 return string if not variables else string % variables65 return super().gettext(string, **variables)66 67 def ngettext(self, singular, plural, num, **variables): # pragma: no cover68 if not has_babel_ext():69 variables.setdefault("num", num)70 return (singular if num == 1 else plural) % variables71 return super().ngettext(singular, plural, num, **variables)72 73 @staticmethod74 def format_list(lst, **kwargs):75 # This is a Babel method76 if not has_babel_ext():77 return ", ".join(lst)78 ll = get_locale()79 return format_list(lst, locale=get_locale(), **kwargs)80 81 def is_lazy_string(obj):82 """Checks if the given object is a lazy string."""83 return isinstance(obj, LazyProxy)84 85 def make_lazy_string(__func, msg):86 """Creates a lazy string by invoking func with args."""87 return LazyProxy(__func, msg, enable_cache=False)88 89except ImportError: # pragma: no cover90 # Fake up just enough91 class FsDomain: # type: ignore[no-redef]92 def __init__(self, app):93 pass94 95 @staticmethod96 def gettext(string, **variables):97 return string if not variables else string % variables98 99 @staticmethod100 def ngettext(singular, plural, num, **variables):101 variables.setdefault("num", num)102 return (singular if num == 1 else plural) % variables103 104 @staticmethod105 def format_list(lst, **kwargs):106 # This is a Babel method107 if not has_babel_ext():108 return ", ".join(lst)109 110 def is_lazy_string(obj):111 return False112 113 def make_lazy_string(__func, msg):114 return msg115 