Example #1
0
def negotiate_locale(preferred_locale: str,
                     available_locales: List[str]) -> Optional[str]:
    negotiated_locale = babel.negotiate_locale([preferred_locale],
                                               available_locales)
    if negotiated_locale is not None:
        return negotiated_locale
    preferred_locale = preferred_locale.split('-', 1)[0]
    for available_locale in available_locales:
        negotiated_locale = babel.negotiate_locale(
            [preferred_locale], [available_locale.split('-', 1)[0]])
        if negotiated_locale is not None:
            return available_locale
Example #2
0
def set_best_lang():
    """
    Get the best language/locale for the current user. This means that first
    the session will be checked, and then in the absence of an explicitly-set
    language, we will try to guess it from the browser settings and only
    after that fall back to the server's default.
    """

    if not has_request_context():
        return 'en_GB' if current_app.config['TESTING'] else HelperMaKaCInfo.getMaKaCInfoInstance().getLang()
    elif session.lang is not None:
        return session.lang

    # try to use browser language
    preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
    resolved_lang = negotiate_locale(preferred, list(get_all_locales()), aliases=LOCALE_ALIASES)

    if not resolved_lang:
        if current_app.config['TESTING']:
            return 'en_GB'

        with DBMgr.getInstance().global_connection():
            # fall back to server default
            minfo = HelperMaKaCInfo.getMaKaCInfoInstance()
            resolved_lang = minfo.getLang()

    session.lang = resolved_lang
    return resolved_lang
Example #3
0
 def getkey(self, key):
     locales = []
     for locale, strings in self._data.items():
         if key in strings:
             locales += [locale]
     locale = negotiate_locale(self._languages, locales)
     return self._data.get(locale, {}).get(key, False)
Example #4
0
def set_best_lang():
    """
    Get the best language/locale for the current user. This means that first
    the session will be checked, and then in the absence of an explicitly-set
    language, we will try to guess it from the browser settings and only
    after that fall back to the server's default.
    """

    if not has_request_context():
        return 'en_GB' if current_app.config[
            'TESTING'] else HelperMaKaCInfo.getMaKaCInfoInstance().getLang()
    elif session.lang is not None:
        return session.lang

    # try to use browser language
    preferred = [
        x.replace('-', '_') for x in request.accept_languages.values()
    ]
    resolved_lang = negotiate_locale(preferred,
                                     list(get_all_locales()),
                                     aliases=LOCALE_ALIASES)

    if not resolved_lang:
        if current_app.config['TESTING']:
            return 'en_GB'

        with DBMgr.getInstance().global_connection():
            # fall back to server default
            minfo = HelperMaKaCInfo.getMaKaCInfoInstance()
            resolved_lang = minfo.getLang()

    session.lang = resolved_lang
    return resolved_lang
Example #5
0
def detect_language():
    if 'lang' in request.args:
        requested_locale = request.args['lang']
        locales = [unicode(l) for l in babel.list_translations()]
        locale = negotiate_locale([requested_locale,], locales)
        session['locale'] = locale
        flask_babel.refresh()
Example #6
0
def set_best_lang(check_session=True):
    """
    Get the best language/locale for the current user. This means that first
    the session will be checked, and then in the absence of an explicitly-set
    language, we will try to guess it from the browser settings and only
    after that fall back to the server's default.
    """
    from indico.core.config import Config

    if not has_request_context():
        return 'en_GB' if current_app.config['TESTING'] else Config.getInstance().getDefaultLocale()
    elif 'lang' in g:
        return g.lang
    elif check_session and session.lang is not None:
        return session.lang

    # try to use browser language
    preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
    resolved_lang = negotiate_locale(preferred, list(get_all_locales()), aliases=LOCALE_ALIASES)

    if not resolved_lang:
        if current_app.config['TESTING']:
            return 'en_GB'

        # fall back to server default
        resolved_lang = Config.getInstance().getDefaultLocale()

    # As soon as we looked up a language, cache it during the request.
    # This will be returned when accessing `session.lang` since there's code
    # which reads the language from there and might fail (e.g. by returning
    # lazy strings) if it's not set.
    g.lang = resolved_lang
    return resolved_lang
Example #7
0
 def gettext(self, english_text):
     locales = []
     for locale, strings in self._data.items():
         if english_text in strings:
             locales += [locale]
     locale = negotiate_locale(self._languages, locales)
     return self._data.get(locale, {}).get(english_text, english_text)
Example #8
0
def get_user_locale():
	preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
	if 'l' in request.args:
		preferred = [request.args['l']]
	elif 'fb_locale' in request.args:
		preferred = [request.args['fb_locale']]
	return negotiate_locale(preferred, AVAILABLE_LOCALES)
Example #9
0
def set_best_lang(check_session=True):
    """
    Get the best language/locale for the current user. This means that first
    the session will be checked, and then in the absence of an explicitly-set
    language, we will try to guess it from the browser settings and only
    after that fall back to the server's default.
    """
    from indico.core.config import config

    if not has_request_context():
        return 'en_GB' if current_app.config['TESTING'] else config.DEFAULT_LOCALE
    elif 'lang' in g:
        return g.lang
    elif check_session and session.lang is not None:
        return session.lang

    # try to use browser language
    preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
    resolved_lang = negotiate_locale(preferred, list(get_all_locales()), aliases=LOCALE_ALIASES)

    if not resolved_lang:
        if current_app.config['TESTING']:
            return 'en_GB'

        # fall back to server default
        resolved_lang = config.DEFAULT_LOCALE

    # As soon as we looked up a language, cache it during the request.
    # This will be returned when accessing `session.lang` since there's code
    # which reads the language from there and might fail (e.g. by returning
    # lazy strings) if it's not set.
    g.lang = resolved_lang
    return resolved_lang
Example #10
0
def set_best_lang(check_session=True):
    """Get the best language/locale for the current user.

    This means that first the session will be checked, and then in the
    absence of an explicitly-set language, we will try to guess it from
    the browser settings and only after that fall back to
    the server's default.
    """
    from indico.core.config import config

    if not has_request_context():
        return 'en_GB' if current_app.config[
            'TESTING'] else config.DEFAULT_LOCALE
    elif 'lang' in g:
        return g.lang
    elif check_session and session.lang is not None:
        return session.lang

    # chinese uses `zh-Hans-CN`, but browsers send `zh-CN`
    all_locales = {
        _remove_locale_script(loc).lower(): loc
        for loc in get_all_locales()
    }

    # try to use browser language
    preferred = [
        x.replace('-', '_') for x in request.accept_languages.values()
    ]
    resolved_lang = negotiate_locale(preferred,
                                     list(all_locales),
                                     aliases=LOCALE_ALIASES)

    if not resolved_lang:
        if current_app.config['TESTING']:
            return 'en_GB'

        # fall back to server default
        resolved_lang = config.DEFAULT_LOCALE

    # restore script information if necessary
    try:
        resolved_lang = all_locales[resolved_lang.lower()]
    except KeyError:
        # this happens if we have e.g. a development setup with no built languages.
        # in this case `get_all_locales()` only contains `en_EN`
        return 'en_GB'

    # normalize to xx_YY capitalization
    resolved_lang = re.sub(
        r'^([a-zA-Z]+)_([a-zA-Z]+)$',
        lambda m: '{}_{}'.format(m.group(1).lower(),
                                 m.group(2).upper()), resolved_lang)

    # As soon as we looked up a language, cache it during the request.
    # This will be returned when accessing `session.lang` since there's code
    # which reads the language from there and might fail (e.g. by returning
    # lazy strings) if it's not set.
    g.lang = resolved_lang
    return resolved_lang
Example #11
0
def get_locale():
    user = getattr(g, 'user', None)
    if user is not None:
        return user.locale or 'en'
    preferred = [
        x.replace('-', '_') for x in list(request.accept_languages.values())
    ]
    return negotiate_locale(preferred, ['pt_BR', 'en_US'])
Example #12
0
 def getkey(self, key, lang_code=None):
     locales = []
     for locale, strings in self._data.items():
         if key in strings:
             locales += [locale]
     target_locales = [lang_code] if lang_code else self._languages
     locale = negotiate_locale(target_locales, locales)
     return self._data.get(locale, {}).get(key, False)
Example #13
0
def get_locale(locale=None):
    global locales
    
    if locales is None:
        locales = babel.localedata.list()

    locale = util_get_locale(locale)
    return babel.negotiate_locale([locale, 'en'], locales)
Example #14
0
def get_locale():
    from_cookie = request.cookies.get('lang', None)

    if from_cookie and from_cookie in config.LOCALE_PREFER:
        return from_cookie
    else:
        preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
        return negotiate_locale(preferred, config.LOCALE_PREFER)
Example #15
0
    def __get_language_match(self, languageCode, languageIds):
        """Compares ``languageCode`` to the provided ``languageIds`` to find
        the closest match and returns it, if a match is not found returns
        ``None``.

        e.g. if ``languageCode`` is ``en_CA`` and ``languageIds`` contains
        ``en``, the return value will be ``en``
        """
        # special case
        if languageCode == 'zh':
            return 'zh-Hans'

        # this will take care of cases such as mapping en_CA to en
        if '-' in languageCode:
            match = negotiate_locale([languageCode], languageIds, sep='-')
        else:
            match = negotiate_locale([languageCode], languageIds)

        if match:
            return match

        # handle other cases
        if '-' in languageCode:
            locale = Locale.parse(languageCode, sep='-')
        else:
            locale = Locale.parse(languageCode)

        for languageId in languageIds:
            if '-' not in languageId:
                continue

            # normalize the languageId
            nLanguageId = Locale.parse(languageId, sep='-')

            # 1. lang subtag must match
            # 2. either script or territory subtag must match AND
            #    one of them must not be None, i.e. do not allow None == None
            if locale.language == nLanguageId.language and \
                (((locale.script or nLanguageId.script) and
                 (locale.script == nLanguageId.script)) or \
                 (locale.territory or nLanguageId.territory) and
                 (locale.territory == nLanguageId.territory)):
                return languageId

        return None
Example #16
0
    def __get_language_match(self, languageCode, languageIds):
        """Compares ``languageCode`` to the provided ``languageIds`` to find
        the closest match and returns it, if a match is not found returns
        ``None``.

        e.g. if ``languageCode`` is ``en_CA`` and ``languageIds`` contains
        ``en``, the return value will be ``en``
        """
        # special case
        if languageCode == 'zh':
            return 'zh-Hans'

        # this will take care of cases such as mapping en_CA to en
        if '-' in languageCode:
            match = negotiate_locale([languageCode], languageIds, sep='-')
        else:
            match = negotiate_locale([languageCode], languageIds)

        if match:
            return match

        # handle other cases
        if '-' in languageCode:
            locale = Locale.parse(languageCode, sep='-')
        else:
            locale = Locale.parse(languageCode)

        for languageId in languageIds:
            if '-' not in languageId:
                continue

            # normalize the languageId
            nLanguageId = Locale.parse(languageId, sep='-')

            # 1. lang subtag must match
            # 2. either script or territory subtag must match AND
            #    one of them must not be None, i.e. do not allow None == None
            if locale.language == nLanguageId.language and \
                (((locale.script or nLanguageId.script) and
                (locale.script == nLanguageId.script)) or \
                (locale.territory or nLanguageId.territory) and
                (locale.territory == nLanguageId.territory)):
                    return languageId

        return None
Example #17
0
def get_locale():
    locales = app.config.get("LOCALES", {}).keys()
    sent = request.accept_languages.values()
    g.locale = negotiate_locale((v.replace("-", "_") for v in sent), locales)

    if not g.locale:
        g.locale = "en"

    return g.locale
Example #18
0
File: app.py Project: keur/moffle
def get_locale():
    from_cookie = request.cookies.get('lang', None)

    if from_cookie and from_cookie in config.LOCALE_PREFER:
        return from_cookie
    else:
        preferred = [
            x.replace('-', '_') for x in request.accept_languages.values()
        ]
        return negotiate_locale(preferred, config.LOCALE_PREFER)
Example #19
0
 def select_language(self, lang: str):
     """
     Usage:
     with Jinja2Env().select_language(lang) as env:
         txt = env.get_template('template.jinja2').render(*args, **kwargs)
     """
     neg_lang = babel.negotiate_locale(preferred=[lang],
                                       available=self.translations.keys())
     translation = self.translations.get(neg_lang, self.translations['en'])
     # install_gettext_translations is available when instantiating env with extension jinja2.ext.i18n
     self.env.install_gettext_translations(translation, newstyle=True)
     yield self.env
Example #20
0
    def __init__(
        self,
        request,
        locales, default_locale=(None, None),
        dirname=None, domain=None,
        timezone=None, default_timezone=None
    ):
        """
        A locale with negotiated language and territory

        In:
          - ``request`` -- the HTTP request object
          - ``locales`` -- tuples of (language, territory) accepted by the application
            (i.e ``[('fr', 'FR'), ('de', 'DE'), ('en',)]``)
          - ``default_locale`` -- tuple of (language, territory) to use if the
            negociation failed

          - ``dirname`` -- the directory containing the ``MO`` files
          - ``domain`` -- the messages domain

          - ``timezone`` -- the timezone (timezone object or code)
            (i.e ``pytz.timezone('America/Los_Angeles')`` or ``America/Los_Angeles``)
          - ``default_timezone`` -- default timezone when a ``datetime`` object has
            no associated timezone. If no default timezone is given, the ``timezone``
            value is used
        """
        locale = negotiate_locale(
            request.accept_language,
            map('-'.join, locales),
            '-'
        )

        if not locale:
            language, territory = (default_locale + (None,))[:2]
        else:
            locale = core.LOCALE_ALIASES.get(locale, locale).replace('_', '-')

            if '-' not in locale:
                language = locale
                territory = None
            else:
                language, territory = locale.split('-')
                territory = territory.upper()

        super(NegotiatedLocale, self).__init__(
            language, territory,
            dirname=dirname, domain=domain,
            timezone=timezone, default_timezone=default_timezone
        )
Example #21
0
    def __init__(
        self,
        request,
        locales, default_locale=(None, None),
        dirname=None, domain=None,
        timezone=None, default_timezone=None
    ):
        """
        A locale with negotiated language and territory

        In:
          - ``request`` -- the HTTP request object
          - ``locales`` -- tuples of (language, territory) accepted by the application
            (i.e ``[('fr', 'FR'), ('de', 'DE'), ('en',)]``)
          - ``default_locale`` -- tuple of (language, territory) to use if the
            negociation failed

          - ``dirname`` -- the directory containing the ``MO`` files
          - ``domain`` -- the messages domain

          - ``timezone`` -- the timezone (timezone object or code)
            (i.e ``pytz.timezone('America/Los_Angeles')`` or ``America/Los_Angeles``)
          - ``default_timezone`` -- default timezone when a ``datetime`` object has
            no associated timezone. If no default timezone is given, the ``timezone``
            value is used
        """
        locale = negotiate_locale(
            map(itemgetter(0), sorted(request.accept_language.parsed or (), key=itemgetter(1), reverse=True)),
            ['-'.join(locale).rstrip('-') for locale in locales],
            '-'
        )

        if not locale:
            language, territory = (default_locale + (None,))[:2]
        else:
            locale = core.LOCALE_ALIASES.get(locale, locale).replace('_', '-')

            if '-' not in locale:
                language = locale
                territory = None
            else:
                language, territory = locale.split('-')
                territory = territory.upper()

        super(NegotiatedLocale, self).__init__(
            language, territory,
            dirname=dirname, domain=domain,
            timezone=timezone, default_timezone=default_timezone
        )
Example #22
0
def negotiate_localizeds(preferred_locale: str,
                         localizeds: Iterable[Localized]) -> Localized:
    localizeds = list(localizeds)
    negotiated_locale = negotiate_locale(
        [preferred_locale], map(lambda localized: localized.locale,
                                localizeds), '-')
    if negotiated_locale is None:
        if len(localizeds) > 0:
            return localizeds[0]
        else:
            raise ValueError(
                'Cannot negotiate if there are no localized values.')
    for localized in localizeds:
        if localized.locale == negotiated_locale:
            return localized
Example #23
0
def get_locale():
    # if a user is logged in, use the locale from the user settings
    user = getattr(g, 'user', None)
    if user is not None and hasattr(user, "locale"):
        if user.name != 'Guest':  # if the account is the guest account bypass the config lang settings
            return user.locale

    preferred = list()
    if request.accept_languages:
        for x in request.accept_languages.values():
            try:
                preferred.append(str(Locale.parse(x.replace('-', '_'))))
            except (UnknownLocaleError, ValueError) as e:
                log.debug('Could not parse locale "%s": %s', x, e)

    return negotiate_locale(preferred or ['en'], get_available_translations())
Example #24
0
def get_locale():
    if current_user() and current_user().locale_code:
        return current_user().locale_code

    # look for session variable in pre-logged-in state
    # confirm request context - not available from celery tasks
    if has_request_context():
        if session.get('locale_code'):
            return session['locale_code']
        browser_pref = negotiate_locale(
            preferred=(l.replace('-', '_')
                       for l in request.accept_languages.values()),
            available=(c.code for c in Coding.query.filter_by(
                system=IETF_LANGUAGE_TAG)),
        )
        if browser_pref:
            return browser_pref
    return current_app.config.get("DEFAULT_LOCALE")
Example #25
0
def negociate_locale():
    # if a user is logged in, use the locale from the user settings
    user = getattr(g, 'user', None)
    # user = None
    if user is not None and hasattr(user, "locale"):
        if user.nickname != 'Guest':   # if the account is the guest account bypass the config lang settings
            return user.locale

    preferred = set()
    if request.accept_languages:
        for x in request.accept_languages.values():
            try:
                preferred.add(str(LC.parse(x.replace('-', '_'))))
            except (UnknownLocaleError, ValueError) as e:
                log.warning('Could not parse locale "%s": %s', x, e)
                # preferred.append('en')

    return negotiate_locale(preferred or ['en'], _BABEL_TRANSLATIONS)
Example #26
0
def select_locale():
    """Select a suitable locale

    Try to pick a locale from the following ordered sources:

        1. The user's explicit locale setting

        2. The best match according to the ``Accept-Language`` request header

    :returns: The locale string

    :rtype: str
    """
    locale = get_user_locale_setting()
    if locale is not None:
        return str(locale)
    return negotiate_locale(
        request.accept_languages.values(),
        list(map(str, possible_locales())), sep='-')
Example #27
0
def get_locale():
    if current_user() and current_user().locale_code:
        return current_user().locale_code

    # look for session variable in pre-logged-in state
    # confirm request context - not available from celery tasks
    if has_request_context():
        if session.get('locale_code'):
            return session['locale_code']
        browser_pref = negotiate_locale(
            preferred=(
                l.replace('-', '_') for l in request.accept_languages.values()
            ),
            available=(
                c.code for c in Coding.query.filter_by(system=IETF_LANGUAGE_TAG)
            ),
        )
        if browser_pref:
            return browser_pref
    return current_app.config.get("DEFAULT_LOCALE")
Example #28
0
def get_locale():
    # Safari (macOS and iOS) sends Accept-Language: zh-cn, but Werkzeug cannot
    # match it to zh. Fix it here.
    # https://github.com/pallets/werkzeug/issues/450#issuecomment-26621966
    preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
    locale = negotiate_locale(preferred, settings['locales'].keys())

    if request.preferences.get_value('locale') != '':
        locale = request.preferences.get_value('locale')

    if 'locale' in request.args\
       and request.args['locale'] in settings['locales']:
        locale = request.args['locale']

    if 'locale' in request.form\
       and request.form['locale'] in settings['locales']:
        locale = request.form['locale']

    if locale == 'zh_TW':
        locale = 'zh_Hant_TW'

    return locale
 def get_locale():
     preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
     return negotiate_locale(preferred, config.SUPPORTED_LOCALES)
Example #30
0
 def negotiate_locale(self, accept_langs):
     def normalize_locale(loc):
         return unicode(loc).replace('-', '_')
     langs = map(normalize_locale, accept_langs)
     return negotiate_locale(langs, self.available_locales, sep="_") or self.default_locale_name
 def get_locale():
     preferred = [
         x.replace('-', '_') for x in request.accept_languages.values()
     ]
     return negotiate_locale(preferred, config.SUPPORTED_LOCALES)
    def _init_translate(self, alert):
        """Run in background at startup, initializes data, contacts server,
        does that sort of setup procedure.
        """

        # XXX: Maybe instead of failing here, how about creating a transient
        #      local server, would use whatever web APIs possible. Not really
        #      sure.

        if not self.client.can_connect():
            self.remove_alert(alert)
            self._create_alert(
                _("Connection error"),
                _("Couldn't connect to the server!"))

        from_lang_store = self.lang_from.get_model()

        # Try to set the default from language selection to the user's
        # locale.

        # XXX: If default_locale fails (theoretically could if ENV isn't
        #      proper), this will raise babel.core.UnknownLocaleError.
        locale = babel.default_locale(category="LANG")
        self.locale = Locale(locale)

        self._logger.info("Setting locale to %s", repr(self.locale))

        pairs = self.client.language_pairs()

        from_langs = set()

        # TODO: maybe try falling back to first two letters?
        for pair in pairs:
            try:
                from_locale = Locale.parse(pair[0])
                from_name = from_locale.get_language_name(self.locale)
            except (babel.UnknownLocaleError, ValueError):
                # Fall back to language code
                from_name = pair[0]
                self._logger.error('Failed to get a locale for %s', pair[0])

            from_langs.add((pair[0], from_name))

        from_langs = sorted(list(from_langs), (lambda x, y: cmp(x[1], y[1])))

        for lang in from_langs:
            from_lang_store.append(lang)

        # Fall back to whatever the first option is.
        self.lang_from.set_active(0)

        for idx, lang in enumerate(from_langs):
            # Check if the user's locale is "good enough".
            #
            # e.g. if locale is "en_US", and "en" is in the combobox, then will
            # return non-None.
            if babel.negotiate_locale([lang[0]], [locale]) is not None:
                self.lang_from.set_active(idx)
                break

        # Make sure the to_lang combobox is up to date
        self._lang_from_changed_cb(self.lang_from)

        # Enable the button
        self.translate_button.set_sensitive(True)
        self.remove_alert(alert)