Ejemplo n.º 1
0
def _locales_configuration(configuration: List):
    locales_configuration = OrderedDict()
    for locale_configuration in configuration:
        locale = locale_configuration['locale']
        parse_locale(locale, '-')
        locales_configuration[locale] = LocaleConfiguration(
            locale, locale_configuration['alias'] if 'alias' in locale_configuration else None)
    return locales_configuration
Ejemplo n.º 2
0
def _locales_configuration(configuration: List):
    locales_configuration = []
    for locale_configuration in configuration:
        locale = locale_configuration['locale']
        parse_locale(locale, '-')
        locales_configuration.append(LocaleConfiguration(
            locale,
            locale_configuration['alias'] if 'alias' in locale_configuration else None,
        ))
    return locales_configuration
Ejemplo n.º 3
0
    def get_locale():
        user = getattr(g, "user", {})
        user_language = user.get("language", app.config.get("DEFAULT_LANGUAGE", "en"))
        try:
            # Attempt to load the local using Babel.parse_local
            parse_locale(user_language.replace("-", "_"))
        except ValueError:
            # If Babel fails to recognise the locale, then use the default language
            user_language = app.config.get("DEFAULT_LANGUAGE", "en")

        return user_language.replace("-", "_")
Ejemplo n.º 4
0
    def get_locale():
        user = getattr(g, 'user', {})
        user_language = user.get('language',
                                 app.config.get('DEFAULT_LANGUAGE', 'en'))
        try:
            # Attempt to load the local using Babel.parse_local
            parse_locale(user_language.replace('-', '_'))
        except ValueError:
            # If Babel fails to recognise the locale, then use the default language
            user_language = app.config.get('DEFAULT_LANGUAGE', 'en')

        return user_language.replace('-', '_')
Ejemplo n.º 5
0
def sanitize_language_code(lang):
    """Sanitize the language code if the spelling is slightly wrong.

    For instance, 'pt-br' and 'pt_br' should be interpreted as 'pt_BR'.

    """
    try:
        lang = '_'.join(filter(None, parse_locale(lang)[:2]))
    except ValueError:
        if '-' in lang:
            try:
                lang = '_'.join(filter(None, parse_locale(lang, sep='-')[:2]))
            except ValueError:
                pass
    return lang
Ejemplo n.º 6
0
    def __init__(self, context, request: Request):
        self.request = request
        self.context = context
        _ = request.translate
        self.helper = request.registry['i18n_helper']
        self.lang = request.matchdict['lang']
        self.domain = request.matchdict['domain']

        self.locale = babel.Locale(*babel.parse_locale(self.lang))

        self.pot_file_path = os.path.join(self.helper.locale_dir,
                                          '{0}.pot'.format(self.domain))
        self.po_file_path = os.path.join(self.helper.locale_dir, self.lang,
                                         'LC_MESSAGES',
                                         '{0}.po'.format(self.domain))
        self.mo_file_path = os.path.join(self.helper.locale_dir, self.lang,
                                         'LC_MESSAGES',
                                         '{0}.mo'.format(self.domain))

        os.makedirs(os.path.join(self.helper.locale_dir, self.lang,
                                 'LC_MESSAGES'),
                    exist_ok=True)

        if os.path.exists(self.po_file_path):
            self.po = polib.pofile(self.po_file_path, encoding='UTF-8')
        else:
            self.po = polib.POFile(encoding='UTF-8')

        self.po.metadata = {
            'Content-Transfer-Encoding': '8bit',
            'Content-Type': 'text/plain; charset=UTF-8',
            'Language': self.lang
        }
Ejemplo n.º 7
0
    def new_lang_view(self):

        lang = self.request.POST.get('new_lang', '').strip()
        try:
            self.request.locale = babel.Locale(*babel.parse_locale(lang))

            if not os.path.isdir(os.path.join(self.helper.locale_dir, lang)):
                os.mkdir(os.path.join(self.helper.locale_dir, lang))
                os.mkdir(
                    os.path.join(self.helper._dir, 'locale', lang,
                                 'LC_MESSAGES'))
                # self.pot.save(os.path.join(self.helper.package_dir, 'locale', lang, 'LC_MESSAGES',
                #                            '{0}.po'.format(self.domain)))
                # self.pot.save_as_mofile(os.path.join(self.helper.package_dir, 'locale', lang, 'LC_MESSAGES',
                #                                      '{0}.mo'.format(self.domain)))

                self.request.flash_message.add(
                    message_type='success',
                    body='i18n_new_lang_creation_success',
                    domain='i18n_helper')

                return HTTPFound(location=self.request.route_url(
                    'i18n_helper.po', lang=lang, domain=self.domain))

            else:
                self.request.flash_message.add(message_type='danger',
                                               body='i18n_new_lang_lang_exist',
                                               domain='i18n_helper')

        except:
            self.request.flash_message.add(message_type='danger',
                                           body='i18n_new_lang_creation_error',
                                           domain='i18n_helper')

        return self.get_view()
Ejemplo n.º 8
0
    def for_locale(cls, locale="en"):
        """
        Returns a new Wordlist object using an included wordlist most
        appropriate to the provided locale, or the en wordlist as a default.

        This parses the locale string and first tries to find a file matching
        both the language and territory. Failing that, it tries to find one
        matching the language. Failing that, it falls back to `en`.

        Args:
        locale -- An RFC 4646 locale string, or a tuple in the form
                  (language, territory) (optional)
        """
        wordlists = get_wordlists_by_locale()
        if locale:
            if isinstance(locale, str):
                locale = parse_locale(locale)
            for locale_tuple in [locale[:2], (locale[0], None), ("en", "US")]:
                try:
                    return cls(resource_string(
                        'phrasebook',
                        wordlists[locale_tuple]).decode('utf-8').splitlines(),
                               locale=locale_tuple)
                except KeyError:
                    continue

        # This should never happen, since the "en" file should always be there
        # as a fallback. If for some reason it's not, exit with a helpful
        # exception message.
        raise Exception("No suitable wordlist file found")
Ejemplo n.º 9
0
 async def _filter_wikipedia_links(
         self, context, links: Iterable[Link]) -> Iterable[Entry]:
     locale = parse_locale(resolve_or_missing(context, 'locale'), '-')[0]
     return filter(
         None, await asyncio.gather(
             *[self._filter_wikipedia_link(locale, link)
               for link in links]))
Ejemplo n.º 10
0
    def select_lang_view(self):

        lang = self.request.POST.get('select_lang', '').strip()

        self.request.locale = babel.Locale(*babel.parse_locale(lang))

        return HTTPFound(location=self.request.route_url(
            'i18n_helper.po', lang=lang, domain=self.domain))
Ejemplo n.º 11
0
 def _filter_wikipedia_links(self, context,
                             links: Iterable[Link]) -> Iterable[Entry]:
     locale = parse_locale(context.resolve_or_missing('locale'), '-')[0]
     futures = [
         self._app.executor.submit(self._filter_wikipedia_link, locale,
                                   link) for link in links
     ]
     return filter(None,
                   [future.result() for future in as_completed(futures)])
Ejemplo n.º 12
0
 def language(self):
     l = self._cfg.language_default
     locale = self.locale  # is either None or something like 'en_US'
     if locale is not None:
         try:
             l = parse_locale(locale)[0]
         except ValueError:
             pass
     return l
Ejemplo n.º 13
0
def locale_keyboard():
    """Get inline keyboard markup with available locales."""
    keyboard = InlineKeyboardMarkup()
    for language in i18n.available_locales:
        keyboard.row(
            InlineKeyboardButton(
                Locale(parse_locale(language)[0]).display_name,
                callback_data="locale {}".format(language),
            ))
    return keyboard
Ejemplo n.º 14
0
def get_wordlists_by_locale():
    """
    Returns a mapping of locales to wordlist paths
    """
    locale_mapping = {}
    for file_path in resource_listdir('phrasebook', 'wordlists'):
        m = re.search('^(.*).txt$', file_path)
        if not m:
            continue

        # Ignore files that don't fit the format
        try:
            locale_mapping[parse_locale(m[1])[:2]] = 'wordlists/' + file_path
        except ValueError:
            continue

    return locale_mapping
Ejemplo n.º 15
0
 def _get_language_codes(language_code: str):
     """
     Return all acceptable language codes for a given language code, in order of priority.
     For example, for "en-US", it would return "en-US", "en", "und-US".
     """
     # first of all, return the language code as is
     yield language_code
     # if that does not produce a valid locale, split the language code in its individual parts
     try:
         language, territory, script, variant = babel.parse_locale(language_code, sep="-")
     except Exception:
         # the language code is not valid, we cannot give more codes for it
         pass
     else:
         # return the language only (eg. "en")
         if language:
             yield language
         # return a special language code that will try to get the most common language for the territory
         if territory:
             yield "und-" + territory
Ejemplo n.º 16
0
Archivo: base.py Proyecto: dkm/skylines
        def get_primary_languages():
            available = [lang['language_code'] for lang in languages()]
            requested = distinct(get_lang() or ['en'])

            # add primary languages
            primary = []
            for language in requested:
                if language in available:
                    primary.append(language)
                else:
                    try:
                        locale = parse_locale(language)
                    except:
                        continue

                    if locale[0] in available:
                        primary.append(locale[0])

            if len(primary) == 0:
                return [language_info('en')]

            return [language_info(lang) for lang in distinct(primary)]
Ejemplo n.º 17
0
def validate_locale(locale: str) -> str:
    parse_locale(locale, '-')
    return locale
Ejemplo n.º 18
0
    def __init__(self, context, request: Request):
        self.request = request
        self.context = context
        self.domain = request.matchdict['domain']
        _ = request.translate

        self.helper = request.registry['i18n_helper']

        self.pot = polib.pofile(os.path.join(self.helper.locale_dir,
                                             '{0}.pot'.format(self.domain)),
                                encoding='UTF-8')

        # LANG FORM
        langs_dir = self.helper.locale_dir
        created_langs_choices = []
        for lang in os.listdir(langs_dir):
            if os.path.isdir(os.path.join(langs_dir, lang)):
                lang_locale = babel.Locale(*babel.parse_locale(lang))
                created_langs_choices.append(
                    (lang, '{en_name}/{display_name}'.format(
                        en_name=lang_locale.english_name,
                        display_name=lang_locale.display_name)))

        available_langs_choices = sorted(locale.locale_alias)

        class NewLang(colander.Schema):
            new_lang = colander.SchemaNode(
                colander.String(),
                widget=deform.widget.AutocompleteInputWidget(
                    values=available_langs_choices, min_length=0),
                title=_("i18n_new_lang", domain='i18n_helper'))

        class SelectLang(colander.Schema):
            select_lang = colander.SchemaNode(
                colander.String(),
                widget=deform.widget.SelectWidget(
                    values=created_langs_choices),
                title=_("i18n_select_lang", domain='i18n_helper'))

        def validator(node, appstruct):
            return True

        schema = NewLang(validator=validator)
        schema = schema.bind(request=self.request)
        self.new_lang_form = deform.Form(schema,
                                         use_ajax=False,
                                         action=self.request.route_url(
                                             'i18n_helper.pot',
                                             domain=self.domain))
        self.new_lang_form.buttons.append(
            deform.Button(name='submit',
                          title=_('i18n_new_lang_submit',
                                  domain='i18n_helper')))

        schema = SelectLang(validator=validator)
        schema = schema.bind(request=self.request)
        self.select_lang_form = deform.Form(schema,
                                            use_ajax=False,
                                            action=self.request.route_url(
                                                'i18n_helper.pot',
                                                domain=self.domain))
        self.select_lang_form.buttons.append(
            deform.Button(name='submit',
                          title=_('i18n_select_lang_submit',
                                  domain='i18n_helper')))
Ejemplo n.º 19
0
    def __init__(self):
        """ Init Config instance """
        self.cache = CacheClass()

        if self.config_check_enabled:
            self._config_check()

        # define directories
        data_dir = os.path.normpath(self.data_dir)
        self.data_dir = data_dir
        if not getattr(self, 'plugin_dir', None):
            setattr(self, 'plugin_dir',
                    os.path.abspath(os.path.join(data_dir, 'plugin')))
        if not getattr(self, 'xapian_index_dir', None):
            setattr(self, 'xapian_index_dir',
                    os.path.abspath(os.path.join(data_dir, 'xapian')))

        # Try to decode certain names which allow unicode
        self._decode()

        # After that, pre-compile some regexes
        self.cache.item_dict_regex = re.compile(self.item_dict_regex,
                                                re.UNICODE)
        self.cache.item_group_regex = re.compile(self.item_group_regex,
                                                 re.UNICODE)

        # the ..._regexact versions only match if nothing is left (exact match)
        self.cache.item_dict_regexact = re.compile(
            u'^%s$' % self.item_dict_regex, re.UNICODE)
        self.cache.item_group_regexact = re.compile(
            u'^%s$' % self.item_group_regex, re.UNICODE)

        if not isinstance(self.superusers, list):
            msg = """The superusers setting in your wiki configuration is not
                    a list (e.g. ['Sample User', 'AnotherUser']).  Please change
                    it in your wiki configuration and try again."""
            raise error.ConfigurationError(msg)

        plugins._loadPluginModule(self)

        if self.user_defaults['timezone'] is None:
            self.user_defaults['timezone'] = self.timezone_default
        if self.user_defaults['theme_name'] is None:
            self.user_defaults['theme_name'] = self.theme_default
        # Note: do not assign user_defaults['locale'] = locale_default
        # to give browser language detection a chance.
        try:
            self.language_default = parse_locale(self.locale_default)[0]
        except ValueError:
            raise error.ConfigurationError(
                "Invalid locale_default value (give something like 'en_US').")

        # post process
        self.auth_can_logout = []
        self.auth_login_inputs = []
        found_names = []
        for auth in self.auth:
            if not auth.name:
                raise error.ConfigurationError(
                    "Auth methods must have a name.")
            if auth.name in found_names:
                raise error.ConfigurationError(
                    "Auth method names must be unique.")
            found_names.append(auth.name)
            if auth.logout_possible and auth.name:
                self.auth_can_logout.append(auth.name)
            for input in auth.login_inputs:
                if not input in self.auth_login_inputs:
                    self.auth_login_inputs.append(input)
        self.auth_have_login = len(self.auth_login_inputs) > 0
        self.auth_methods = found_names

        # internal dict for plugin `modules' lists
        self._site_plugin_lists = {}

        # we replace any string placeholders with config values
        # e.g u'%(item_root)s' % self
        self.navi_bar = [elem % self for elem in self.navi_bar]

        # check if python-xapian is installed
        if self.xapian_search:
            try:
                import xapian
            except ImportError, err:
                self.xapian_search = False
                logging.error(
                    "xapian_search was auto-disabled because python-xapian is not installed [%s]."
                    % str(err))
Ejemplo n.º 20
0
    def __init__(self):
        """ Init Config instance """
        self.cache = CacheClass()

        if self.config_check_enabled:
            self._config_check()

        # define directories
        data_dir = os.path.normpath(self.data_dir)
        self.data_dir = data_dir

        # Try to decode certain names which allow unicode
        self._decode()

        # After that, pre-compile some regexes
        self.cache.item_dict_regex = re.compile(self.item_dict_regex,
                                                re.UNICODE)
        self.cache.item_group_regex = re.compile(self.item_group_regex,
                                                 re.UNICODE)

        # the ..._regexact versions only match if nothing is left (exact match)
        self.cache.item_dict_regexact = re.compile(
            '^{0}$'.format(self.item_dict_regex), re.UNICODE)
        self.cache.item_group_regexact = re.compile(
            '^{0}$'.format(self.item_group_regex), re.UNICODE)

        # compiled functions ACL
        self.cache.acl_functions = AccessControlList(
            [self.acl_functions], valid=self.acl_rights_functions)

        plugins._loadPluginModule(self)

        if self.user_defaults[TIMEZONE] is None:
            self.user_defaults[TIMEZONE] = self.timezone_default
        if self.user_defaults[THEME_NAME] is None:
            self.user_defaults[THEME_NAME] = self.theme_default
        # Note: do not assign user_defaults['locale'] = locale_default
        # to give browser language detection a chance.
        try:
            self.language_default = parse_locale(self.locale_default)[0]
        except ValueError:
            raise error.ConfigurationError(
                "Invalid locale_default value (give something like 'en_US').")

        # post process
        self.auth_can_logout = []
        self.auth_login_inputs = []
        found_names = []
        for auth in self.auth:
            if not auth.name:
                raise error.ConfigurationError(
                    "Auth methods must have a name.")
            if auth.name in found_names:
                raise error.ConfigurationError(
                    "Auth method names must be unique.")
            found_names.append(auth.name)
            if auth.logout_possible and auth.name:
                self.auth_can_logout.append(auth.name)
            for input in auth.login_inputs:
                if input not in self.auth_login_inputs:
                    self.auth_login_inputs.append(input)
        self.auth_have_login = len(self.auth_login_inputs) > 0
        self.auth_methods = found_names

        # internal dict for plugin 'modules' lists
        self._site_plugin_lists = {}

        # check if mail is possible and set flag:
        self.mail_enabled = (self.mail_smarthost is not None or
                             self.mail_sendmail is not None) and self.mail_from
        self.mail_enabled = self.mail_enabled and True or False

        if self.namespace_mapping is None:
            raise error.ConfigurationError(
                "No storage configuration specified! You need to define a namespace_mapping."
            )

        if self.backend_mapping is None:
            raise error.ConfigurationError(
                "No storage configuration specified! You need to define a backend_mapping."
            )

        if self.acl_mapping is None:
            raise error.ConfigurationError(
                "No acl configuration specified! You need to define a acl_mapping."
            )

        if self.secrets is None:  # admin did not setup a real secret
            raise error.ConfigurationError(
                "No secret configured! You need to set secrets = 'somelongsecretstring' in your wiki config."
            )

        if self.interwikiname is None:  # admin did not setup a real interwikiname
            raise error.ConfigurationError(
                "No interwikiname configured! "
                "You need to set interwikiname = u'YourUniqueStableInterwikiName' in your wiki config."
            )

        secret_key_names = [
            'security/ticket',
        ]

        secret_min_length = 10
        if isinstance(self.secrets, str):
            if len(self.secrets) < secret_min_length:
                raise error.ConfigurationError(
                    "The secrets = '...' wiki config setting is a way too short string "
                    "(minimum length is {0} chars)!".format(secret_min_length))
            # for lazy people: set all required secrets to same value
            secrets = {}
            for key in secret_key_names:
                secrets[key] = self.secrets
            self.secrets = secrets

        # we check if we have all secrets we need and that they have minimum length
        for secret_key_name in secret_key_names:
            try:
                secret = self.secrets[secret_key_name]
                if len(secret) < secret_min_length:
                    raise ValueError
            except (KeyError, ValueError):
                raise error.ConfigurationError(
                    "You must set a (at least {0} chars long) secret string for secrets['{1}']!"
                    .format(secret_min_length, secret_key_name))

        from passlib.context import CryptContext
        try:
            self.cache.pwd_context = CryptContext(**self.passlib_crypt_context)
        except ValueError as err:
            raise error.ConfigurationError(
                "passlib_crypt_context configuration is invalid [{0}].".format(
                    err))
Ejemplo n.º 21
0
    def __init__(self):
        """ Init Config instance """
        self.cache = CacheClass()

        if self.config_check_enabled:
            self._config_check()

        # define directories
        data_dir = os.path.normpath(self.data_dir)
        self.data_dir = data_dir

        # Try to decode certain names which allow unicode
        self._decode()

        # After that, pre-compile some regexes
        self.cache.item_dict_regex = re.compile(self.item_dict_regex, re.UNICODE)
        self.cache.item_group_regex = re.compile(self.item_group_regex, re.UNICODE)

        # the ..._regexact versions only match if nothing is left (exact match)
        self.cache.item_dict_regexact = re.compile(u'^{0}$'.format(self.item_dict_regex, re.UNICODE))
        self.cache.item_group_regexact = re.compile(u'^{0}$'.format(self.item_group_regex, re.UNICODE))

        # compiled functions ACL
        self.cache.acl_functions = AccessControlList([self.acl_functions], valid=self.acl_rights_functions)

        plugins._loadPluginModule(self)

        if self.user_defaults[TIMEZONE] is None:
            self.user_defaults[TIMEZONE] = self.timezone_default
        if self.user_defaults[THEME_NAME] is None:
            self.user_defaults[THEME_NAME] = self.theme_default
        # Note: do not assign user_defaults['locale'] = locale_default
        # to give browser language detection a chance.
        try:
            self.language_default = parse_locale(self.locale_default)[0]
        except ValueError:
            raise error.ConfigurationError("Invalid locale_default value (give something like 'en_US').")

        # post process
        self.auth_can_logout = []
        self.auth_login_inputs = []
        found_names = []
        for auth in self.auth:
            if not auth.name:
                raise error.ConfigurationError("Auth methods must have a name.")
            if auth.name in found_names:
                raise error.ConfigurationError("Auth method names must be unique.")
            found_names.append(auth.name)
            if auth.logout_possible and auth.name:
                self.auth_can_logout.append(auth.name)
            for input in auth.login_inputs:
                if input not in self.auth_login_inputs:
                    self.auth_login_inputs.append(input)
        self.auth_have_login = len(self.auth_login_inputs) > 0
        self.auth_methods = found_names

        # internal dict for plugin `modules' lists
        self._site_plugin_lists = {}

        # check if mail is possible and set flag:
        self.mail_enabled = (self.mail_smarthost is not None or self.mail_sendmail is not None) and self.mail_from
        self.mail_enabled = self.mail_enabled and True or False

        if self.namespace_mapping is None:
            raise error.ConfigurationError(
                "No storage configuration specified! You need to define a namespace_mapping. "
                "For further reference, please see HelpOnStorageConfiguration.")

        if self.backend_mapping is None:
            raise error.ConfigurationError(
                "No storage configuration specified! You need to define a backend_mapping. " +
                "For further reference, please see HelpOnStorageConfiguration.")

        if self.acl_mapping is None:
            raise error.ConfigurationError(
                "No acl configuration specified! You need to define a acl_mapping. "
                "For further reference, please see HelpOnStorageConfiguration.")

        if self.secrets is None:  # admin did not setup a real secret
            raise error.ConfigurationError(
                "No secret configured! You need to set secrets = 'somelongsecretstring' in your wiki config.")

        if self.interwikiname is None:  # admin did not setup a real interwikiname
            raise error.ConfigurationError(
                "No interwikiname configured! "
                "You need to set interwikiname = u'YourUniqueStableInterwikiName' in your wiki config.")

        secret_key_names = ['security/ticket', ]
        if self.textchas:
            secret_key_names.append('security/textcha')

        secret_min_length = 10
        if isinstance(self.secrets, str):
            if len(self.secrets) < secret_min_length:
                raise error.ConfigurationError(
                    "The secrets = '...' wiki config setting is a way too short string "
                    "(minimum length is {0} chars)!".format(secret_min_length))
            # for lazy people: set all required secrets to same value
            secrets = {}
            for key in secret_key_names:
                secrets[key] = self.secrets
            self.secrets = secrets

        # we check if we have all secrets we need and that they have minimum length
        for secret_key_name in secret_key_names:
            try:
                secret = self.secrets[secret_key_name]
                if len(secret) < secret_min_length:
                    raise ValueError
            except (KeyError, ValueError):
                raise error.ConfigurationError(
                    "You must set a (at least {0} chars long) secret string for secrets['{1}']!".format(
                        secret_min_length, secret_key_name))

        from passlib.context import CryptContext
        try:
            self.cache.pwd_context = CryptContext(**self.passlib_crypt_context)
        except ValueError as err:
            raise error.ConfigurationError("passlib_crypt_context configuration is invalid [{0}].".format(err))
Ejemplo n.º 22
0
 def filters(self) -> Dict[str, Callable]:
     return {
         'wikipedia': environmentfilter(lambda environment, links: self._retriever.all(parse_locale(environment.globals['locale'], '-')[0], links)),
     }