예제 #1
0
파일: ext.py 프로젝트: topless/invenio-i18n
class InvenioI18N(object):
    """Invenio I18N extension."""
    def __init__(self,
                 app=None,
                 date_formats=None,
                 localeselector=None,
                 timezoneselector=None,
                 entry_point_group='invenio_i18n.translations'):
        """Initialize extension.

        :param app: Flask application.
        :param data_formats: Override default date/time formatting.
        :param localeselector: Callback function used for locale selection.
            (Default: :func:`invenio_i18n.selectors.get_locale()`)
        :param timezoneselector: Callback function used for timezone selection.
            (Default: ``BABEL_DEFAULT_TIMEZONE``)
        :param entry_point_group: Entrypoint used to load translations from.
            Set to ``None`` to not load translations from entry points.
        """
        self.domain = MultidirDomain()
        self.babel = Babel(
            date_formats=date_formats,
            configure_jinja=True,
            default_domain=self.domain,
        )
        self.localeselector = localeselector
        self.timezoneselector = timezoneselector
        self.entry_point_group = entry_point_group
        self._locales_cache = None
        self._languages_cache = None

        if app:
            self.init_app(app)

    def init_app(self, app):
        """Flask application initialization.

        The initialization will:

         * Set default values for the configuration variables.
         * Load translations from paths specified in
           ``I18N_TRANSLATIONS_PATHS``.
         * Load translations from ``app.root_path>/translations`` if it exists.
         * Load translations from a specified entry point.
         * Add ``toutc`` and ``tousertimezone`` template filters.
         * Install a custom JSON encoder on app.
        """
        self.init_config(app)

        # Initialize Flask-BabelEx
        self.babel.init_app(app)
        self.babel.localeselector(self.localeselector or get_locale)
        self.babel.timezoneselector(self.timezoneselector or get_timezone)

        # 1. Paths listed in I18N_TRANSLATIONS_PATHS
        for p in app.config.get('I18N_TRANSLATIONS_PATHS', []):
            self.domain.add_path(p)
        # 2. <app.root_path>/translations
        app_translations = os.path.join(app.root_path, 'translations')
        if os.path.exists(app_translations):
            self.domain.add_path(app_translations)
        # 3. Entrypoints
        if self.entry_point_group:
            self.domain.add_entrypoint(self.entry_point_group)

        # Register Jinja2 template filters for date formatting (Flask-Babel
        # already installs other filters).
        app.add_template_filter(filter_to_utc, name='toutc')
        app.add_template_filter(filter_to_user_timezone, name='tousertimezone')
        app.add_template_filter(filter_language_name, name='language_name')
        app.add_template_filter(filter_language_name_local,
                                name='language_name_local')
        app.add_template_global(current_i18n, name='current_i18n')

        # Lazy string aware JSON encoder.
        app.json_encoder = get_lazystring_encoder(app)

        app.extensions['invenio-i18n'] = self

    def init_config(self, app):
        """Initialize configuration."""
        for k in dir(config):
            if k.startswith('I18N_'):
                app.config.setdefault(k, getattr(config, k))

    def iter_languages(self):
        """Iterate over list of languages."""
        default_lang = self.babel.default_locale.language
        default_title = self.babel.default_locale.get_display_name(
            default_lang)

        yield (default_lang, default_title)

        for l, title in current_app.config.get('I18N_LANGUAGES', []):
            yield l, title

    def get_languages(self):
        """Get list of languages."""
        if self._languages_cache is None:
            self._languages_cache = list(self.iter_languages())
        return self._languages_cache

    def get_locales(self):
        """Get a list of supported locales.

        Computes the list using ``I18N_LANGUAGES`` configuration variable.
        """
        if self._locales_cache is None:
            langs = [self.babel.default_locale]
            for l, dummy_title in current_app.config.get('I18N_LANGUAGES', []):
                langs.append(self.babel.load_locale(l))
            self._locales_cache = langs
        return self._locales_cache

    @property
    def locale(self):
        """Get current locale."""
        return get_current_locale()

    @property
    def language(self):
        """Get current language code."""
        return get_current_locale().language

    @property
    def timezone(self):
        """Get current timezone."""
        return get_current_timezone()
예제 #2
0
class InvenioI18N(object):
    """Invenio I18N extension."""

    def __init__(self, app=None, date_formats=None, localeselector=None,
                 timezoneselector=None,
                 entry_point_group='invenio_i18n.translations'):
        """Initialize extension.

        :param app: Flask application.
        :param data_formats: Override default date/time formatting.
        :param localeselector: Callback function used for locale selection.
            (Default: :func:`invenio_i18n.selectors.get_locale()`)
        :param timezoneselector: Callback function used for timezone selection.
            (Default: ``BABEL_DEFAULT_TIMEZONE``)
        :param entry_point_group: Entrypoint used to load translations from.
            Set to ``None`` to not load translations from entry points.
        """
        self.domain = MultidirDomain()
        self.babel = Babel(
            date_formats=date_formats,
            configure_jinja=True,
            default_domain=self.domain,
        )
        self.localeselector = localeselector
        self.timezoneselector = timezoneselector
        self.entry_point_group = entry_point_group
        self._locales_cache = None
        self._languages_cache = None

        if app:
            self.init_app(app)

    def init_app(self, app):
        """Flask application initialization.

        The initialization will:

         * Set default values for the configuration variables.
         * Load translations from paths specified in
           ``I18N_TRANSLATIONS_PATHS``.
         * Load translations from ``app.root_path>/translations`` if it exists.
         * Load translations from a specified entry point.
         * Add ``toutc`` and ``tousertimezone`` template filters.
         * Install a custom JSON encoder on app.
        """
        self.init_config(app)

        # Initialize Flask-BabelEx
        self.babel.init_app(app)
        self.babel.localeselector(self.localeselector or get_locale)
        self.babel.timezoneselector(self.timezoneselector or get_timezone)

        # 1. Paths listed in I18N_TRANSLATIONS_PATHS
        for p in app.config.get('I18N_TRANSLATIONS_PATHS', []):
            self.domain.add_path(p)
        # 2. <app.root_path>/translations
        app_translations = os.path.join(app.root_path, 'translations')
        if os.path.exists(app_translations):
            self.domain.add_path(app_translations)
        # 3. Entrypoints
        if self.entry_point_group:
            self.domain.add_entrypoint(self.entry_point_group)

        # Register blueprint if URL is set.
        if app.config['I18N_SET_LANGUAGE_URL'] \
           and app.config['I18N_LANGUAGES']:
            app.register_blueprint(
                blueprint, url_prefix=app.config['I18N_SET_LANGUAGE_URL'])

        # Register Jinja2 template filters for date formatting (Flask-Babel
        # already installs other filters).
        app.add_template_filter(filter_to_utc, name='toutc')
        app.add_template_filter(filter_to_user_timezone, name='tousertimezone')
        app.add_template_filter(filter_language_name, name='language_name')
        app.add_template_filter(
            filter_language_name_local, name='language_name_local')
        app.context_processor(lambda: dict(current_i18n=current_i18n))

        # Lazy string aware JSON encoder.
        app.json_encoder = get_lazystring_encoder(app)

        app.extensions['invenio-i18n'] = self

    def init_config(self, app):
        """Initialize configuration."""
        for k in dir(config):
            if k.startswith('I18N_'):
                app.config.setdefault(k, getattr(config, k))

    def iter_languages(self):
        """Iterate over list of languages."""
        default_lang = self.babel.default_locale.language
        default_title = self.babel.default_locale.get_display_name(
            default_lang)

        yield (default_lang, default_title)

        for l, title in current_app.config.get('I18N_LANGUAGES', []):
            yield l, title

    def get_languages(self):
        """Get list of languages."""
        if self._languages_cache is None:
            self._languages_cache = list(self.iter_languages())
        return self._languages_cache

    def get_locales(self):
        """Get a list of supported locales.

        Computes the list using ``I18N_LANGUAGES`` configuration variable.
        """
        if self._locales_cache is None:
            langs = [self.babel.default_locale]
            for l, dummy_title in current_app.config.get('I18N_LANGUAGES', []):
                langs.append(self.babel.load_locale(l))
            self._locales_cache = langs
        return self._locales_cache

    @property
    def locale(self):
        """Get current locale."""
        return get_current_locale()

    @property
    def language(self):
        """Get current language code."""
        return get_current_locale().language

    @property
    def timezone(self):
        """Get current timezone."""
        return get_current_timezone()
예제 #3
0
class InvenioI18N(object):
    """Invenio I18N module."""

    def __init__(
        self,
        app=None,
        date_formats=None,
        localeselector=None,
        timezoneselector=None,
        entrypoint="invenio_i18n.translations",
    ):
        """Initialize extension."""
        self.babel = Babel(date_formats=date_formats, configure_jinja=True, default_domain=MultidirDomain())

        self.localeselector = localeselector
        self.timezoneselector = timezoneselector
        self.entrypoint = entrypoint
        self._locales_cache = None

        if app:
            self.init_app(app)

    def init_app(self, app):
        """Flask application initialization."""
        # Initialize Flask-BabelEx
        app.config.setdefault("I18N_LANGUAGES", [])

        # TODO: allow to plug custom localeselector and timezoneselector
        self.babel.init_app(app)
        self.babel.localeselector(self.localeselector or get_locale)
        self.babel.timezoneselector(self.timezoneselector or get_timezone)

        # Add paths to search for message catalogs
        domain = self.babel._default_domain
        # 1. Paths listed in I18N_TRANSLATIONS_PATHS
        for p in app.config.get("I18N_TRANSLATIONS_PATHS", []):
            domain.add_path(p)
        # 2. <app.root_path>/translations
        app_translations = os.path.join(app.root_path, "translations")
        if os.path.exists(app_translations):
            domain.add_path(app_translations)
        # 3. Entrypoints
        if self.entrypoint:
            domain.add_entrypoint(self.entrypoint)

        # Register Jinja2 template filters for date formatting (Flask-Babel
        # already installs other filters).
        app.add_template_filter(filter_to_utc, name="toutc")
        app.add_template_filter(filter_to_user_timezone, name="tousertimezone")

        # Lazy string aware JSON encoder.
        app.json_encoder = get_lazystring_encoder(app)

        app.extensions["invenio-i18n"] = self

    def get_locales(self):
        """Get a list of supported locales."""
        if self._locales_cache is None:
            langs = [self.babel.default_locale]
            for l in current_app.config.get("I18N_LANGUAGES", []):
                langs.append(self.babel.load_locale(l))
            self._locales_cache = langs
        return self._locales_cache
예제 #4
0
class InvenioI18N(object):
    """Invenio I18N module."""
    def __init__(self,
                 app=None,
                 date_formats=None,
                 localeselector=None,
                 timezoneselector=None,
                 entrypoint='invenio_i18n.translations'):
        """Initialize extension."""
        self.babel = Babel(date_formats=date_formats,
                           configure_jinja=True,
                           default_domain=MultidirDomain())

        self.localeselector = localeselector
        self.timezoneselector = timezoneselector
        self.entrypoint = entrypoint
        self._locales_cache = None

        if app:
            self.init_app(app)

    def init_app(self, app):
        """Flask application initialization."""
        # Initialize Flask-BabelEx
        app.config.setdefault("I18N_LANGUAGES", [])

        # TODO: allow to plug custom localeselector and timezoneselector
        self.babel.init_app(app)
        self.babel.localeselector(self.localeselector or get_locale)
        self.babel.timezoneselector(self.timezoneselector or get_timezone)

        # Add paths to search for message catalogs
        domain = self.babel._default_domain
        # 1. Paths listed in I18N_TRANSLATIONS_PATHS
        for p in app.config.get("I18N_TRANSLATIONS_PATHS", []):
            domain.add_path(p)
        # 2. <app.root_path>/translations
        app_translations = os.path.join(app.root_path, 'translations')
        if os.path.exists(app_translations):
            domain.add_path(app_translations)
        # 3. Entrypoints
        if self.entrypoint:
            domain.add_entrypoint(self.entrypoint)

        # Register Jinja2 template filters for date formatting (Flask-Babel
        # already installs other filters).
        app.add_template_filter(filter_to_utc, name="toutc")
        app.add_template_filter(filter_to_user_timezone, name="tousertimezone")

        # Lazy string aware JSON encoder.
        app.json_encoder = get_lazystring_encoder(app)

        app.extensions['invenio-i18n'] = self

    def get_locales(self):
        """Get a list of supported locales."""
        if self._locales_cache is None:
            langs = [self.babel.default_locale]
            for l in current_app.config.get('I18N_LANGUAGES', []):
                langs.append(self.babel.load_locale(l))
            self._locales_cache = langs
        return self._locales_cache