pyramid-localize 0.1.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyramid_localize/__init__.py +62 -0
- pyramid_localize/config/config.yml +13 -0
- pyramid_localize/models.py +37 -0
- pyramid_localize/negotiator.py +41 -0
- pyramid_localize/request.py +124 -0
- pyramid_localize/resources/locale/pyramid_localize.pot +58 -0
- pyramid_localize/resources/templates/_list.mako +33 -0
- pyramid_localize/resources/templates/index.mako +19 -0
- pyramid_localize/resources/templates/layout.mako +12 -0
- pyramid_localize/routing/__init__.py +5 -0
- pyramid_localize/routing/predicates.py +18 -0
- pyramid_localize/subscribers/__init__.py +5 -0
- pyramid_localize/subscribers/fake.py +27 -0
- pyramid_localize/subscribers/i18n.py +27 -0
- pyramid_localize/tools.py +100 -0
- pyramid_localize/views/__init__.py +5 -0
- pyramid_localize/views/catalogue.py +225 -0
- pyramid_localize-0.1.0.dist-info/DESCRIPTION.rst +118 -0
- pyramid_localize-0.1.0.dist-info/METADATA +153 -0
- pyramid_localize-0.1.0.dist-info/RECORD +30 -0
- pyramid_localize-0.1.0.dist-info/WHEEL +6 -0
- pyramid_localize-0.1.0.dist-info/metadata.json +1 -0
- pyramid_localize-0.1.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +1 -0
- tests/conftest.py +58 -0
- tests/test_negotiator.py +55 -0
- tests/test_predicates.py +23 -0
- tests/test_request.py +89 -0
- tests/test_subscribers.py +80 -0
- tests/test_tools.py +105 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""pyramid_localize configuration module."""
|
|
6
|
+
|
|
7
|
+
try: # pragma: no cover
|
|
8
|
+
import babel
|
|
9
|
+
except ImportError: # pragma: no cover
|
|
10
|
+
babel = False
|
|
11
|
+
|
|
12
|
+
from tzf.pyramid_yml import config_defaults
|
|
13
|
+
|
|
14
|
+
from pyramid_localize.request import (
|
|
15
|
+
locale, database_locales, locales, locale_id
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__version__ = '0.1.0'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def includeme(configurator):
|
|
22
|
+
"""pyramid_localize configuration method."""
|
|
23
|
+
# let's check if we have any configuration, or not
|
|
24
|
+
if babel:
|
|
25
|
+
configurator.scan('pyramid_localize.subscribers.i18n')
|
|
26
|
+
configuration = configurator.registry.get('config', {}).get('localize')
|
|
27
|
+
if configuration:
|
|
28
|
+
configurator.include('pyramid_mako')
|
|
29
|
+
# once user allowed for localization, lets set up default values!
|
|
30
|
+
config_defaults(configurator, 'pyramid_localize:config')
|
|
31
|
+
|
|
32
|
+
configurator.set_locale_negotiator('pyramid_localize.negotiator.locale_negotiator')
|
|
33
|
+
translation_dirs = configuration.translation.dirs
|
|
34
|
+
# if it's not a list, lets make it a list.
|
|
35
|
+
# This is to allow creating both single, and list-like config entry
|
|
36
|
+
if not isinstance(translation_dirs, list):
|
|
37
|
+
translation_dirs = [translation_dirs]
|
|
38
|
+
|
|
39
|
+
# let's add destination folder to the list
|
|
40
|
+
if 'destination' in configuration.translation:
|
|
41
|
+
translation_dirs.append(configuration.translation.destination)
|
|
42
|
+
|
|
43
|
+
configurator.add_translation_dirs(*translation_dirs)
|
|
44
|
+
# let scan all subscribers
|
|
45
|
+
configurator.scan('pyramid_localize.views')
|
|
46
|
+
|
|
47
|
+
configurator.add_route(name='localize:index', pattern='catalogue')
|
|
48
|
+
configurator.add_route(name='localize:update', pattern='catalogue/update')
|
|
49
|
+
configurator.add_route(name='localize:compile', pattern='catalogue/compile')
|
|
50
|
+
configurator.add_route(name='localize:reload', pattern='catalogue/reload')
|
|
51
|
+
|
|
52
|
+
# getting requests methods
|
|
53
|
+
configurator.add_request_method(locale, name='locale', reify=True)
|
|
54
|
+
configurator.add_request_method(database_locales, name='_database_locales', reify=True)
|
|
55
|
+
configurator.add_request_method(locales, name='locales')
|
|
56
|
+
configurator.add_request_method(locale_id, name='locale_id', reify=True)
|
|
57
|
+
|
|
58
|
+
# if configured
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
# including fake subscribers
|
|
62
|
+
configurator.scan('pyramid_localize.subscribers.fake')
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
4
|
+
#
|
|
5
|
+
# This module is part of pyramid_localize and is released under
|
|
6
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
7
|
+
localize:
|
|
8
|
+
pybabel: pybabel
|
|
9
|
+
locales: # available and default locale for your app
|
|
10
|
+
available: [en, de, pl]
|
|
11
|
+
default: en
|
|
12
|
+
translation:
|
|
13
|
+
dirs: []
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""Language model."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from sqlalchemy import Column
|
|
9
|
+
from sqlalchemy import Sequence
|
|
10
|
+
from sqlalchemy import Integer
|
|
11
|
+
from sqlalchemy import String
|
|
12
|
+
from sqlalchemy import Unicode
|
|
13
|
+
from sqlalchemy import DateTime
|
|
14
|
+
from sqlalchemy import func
|
|
15
|
+
|
|
16
|
+
from pyramid_basemodel import Base
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Language(Base):
|
|
20
|
+
|
|
21
|
+
"""Language table model definition."""
|
|
22
|
+
|
|
23
|
+
__tablename__ = 'languages'
|
|
24
|
+
|
|
25
|
+
id = Column(Integer, Sequence(__tablename__ + '_sq'), primary_key=True)
|
|
26
|
+
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False)
|
|
27
|
+
name = Column(Unicode(45), nullable=False)
|
|
28
|
+
native_name = Column(Unicode(45), nullable=False)
|
|
29
|
+
language_code = Column(String(2), unique=True, nullable=False) # ISO 639-1 (Alpha2)
|
|
30
|
+
|
|
31
|
+
def __unicode__(self): # pragma: no cover
|
|
32
|
+
"""Language to unicode conversion."""
|
|
33
|
+
return self.name
|
|
34
|
+
|
|
35
|
+
def __str__(self): # pragma: no cover
|
|
36
|
+
"""Language to string conversion."""
|
|
37
|
+
return self.name.encode('utf8')
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""Locale negotiator."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def locale_negotiator(request):
|
|
9
|
+
"""
|
|
10
|
+
Locale negotiator.
|
|
11
|
+
|
|
12
|
+
It sets best suited locale variable for given user:
|
|
13
|
+
|
|
14
|
+
1. Check for presence and value of **request._LOCALE_** value
|
|
15
|
+
2. Then tries the address url, if the first part has locale indicator.
|
|
16
|
+
3. It checks cookies, for value set here
|
|
17
|
+
4. Tries to best match accepted language for browser user is visiting
|
|
18
|
+
website with
|
|
19
|
+
5. Defaults to **localize.locales.default** configuration setting value
|
|
20
|
+
|
|
21
|
+
:param pyramid.request.Request request: a request object
|
|
22
|
+
:returns: locale name
|
|
23
|
+
:rtype: str
|
|
24
|
+
"""
|
|
25
|
+
available_languages = request.registry['config'].localize.locales.available
|
|
26
|
+
locale = request.registry['config'].localize.locales.default
|
|
27
|
+
# We do not have a matchdict present at the moment, lets get our own split
|
|
28
|
+
# (request.path is always a /, so we'll get two elements)
|
|
29
|
+
route_elements = request.path.split('/')
|
|
30
|
+
if hasattr(request, '_LOCALE_') and request._LOCALE_ in available_languages:
|
|
31
|
+
locale = request._LOCALE_
|
|
32
|
+
# we check if route_element[1] is a locale indicator for path
|
|
33
|
+
elif len(route_elements[1]) == 2 and route_elements[1] in available_languages:
|
|
34
|
+
locale = route_elements[1]
|
|
35
|
+
elif request.cookies and '_LOCALE_' in request.cookies and\
|
|
36
|
+
request.cookies['_LOCALE_'] in available_languages:
|
|
37
|
+
locale = request.cookies['_LOCALE_']
|
|
38
|
+
elif request.accept_language:
|
|
39
|
+
locale = request.accept_language.best_match(available_languages)
|
|
40
|
+
|
|
41
|
+
return locale
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""Request related code."""
|
|
6
|
+
|
|
7
|
+
import warnings
|
|
8
|
+
|
|
9
|
+
from pyramid.compat import text_type
|
|
10
|
+
import pyramid_basemodel
|
|
11
|
+
|
|
12
|
+
from pyramid_localize.models import Language
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LocalizeRequestMixin(object):
|
|
16
|
+
|
|
17
|
+
"""Mixin adding overwriting Request methods."""
|
|
18
|
+
|
|
19
|
+
def default_locale(self, **kw):
|
|
20
|
+
"""
|
|
21
|
+
Set up default locale for path kwargs.
|
|
22
|
+
|
|
23
|
+
Can be used in custom route_url overwrites.
|
|
24
|
+
|
|
25
|
+
:param kwargs kw: list of route parts
|
|
26
|
+
|
|
27
|
+
:returns: kw
|
|
28
|
+
"""
|
|
29
|
+
if '__LOCALE__' not in kw \
|
|
30
|
+
or kw['__LOCALE__'] not in self.registry['config'].localize.locales.available:
|
|
31
|
+
kw['__LOCALE__'] = self.locale_name
|
|
32
|
+
|
|
33
|
+
return kw
|
|
34
|
+
|
|
35
|
+
def route_url(self, route_name, *elements, **kw):
|
|
36
|
+
"""
|
|
37
|
+
Overwrite original route_url to handle default locale within route.
|
|
38
|
+
|
|
39
|
+
.. note:: see :meth:`pyramid.request.Request.route_url`
|
|
40
|
+
"""
|
|
41
|
+
return super(LocalizeRequestMixin, self).route_url(
|
|
42
|
+
route_name, *elements, **self.default_locale(**kw)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def locale(request):
|
|
47
|
+
"""
|
|
48
|
+
Return locale name.
|
|
49
|
+
|
|
50
|
+
.. warning::
|
|
51
|
+
|
|
52
|
+
Since pyramid 1.5 this function is obsolete and will be deprecated
|
|
53
|
+
in future versions of pyramid_localize
|
|
54
|
+
|
|
55
|
+
When called for the first time, it ask environment for language code,
|
|
56
|
+
which is later available as a pure property
|
|
57
|
+
overriding this method
|
|
58
|
+
|
|
59
|
+
:returns: language code needed for translations
|
|
60
|
+
:rtype: string
|
|
61
|
+
"""
|
|
62
|
+
warnings.warn(
|
|
63
|
+
'request.locale is deprecated as of pyramid_localize 0.1. '
|
|
64
|
+
'Please use request.locale_name delivered by Pyramid 1.5.',
|
|
65
|
+
DeprecationWarning,
|
|
66
|
+
2
|
|
67
|
+
)
|
|
68
|
+
return request.locale_name
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def locale_id(request):
|
|
72
|
+
"""
|
|
73
|
+
Return database id of a current locale name.
|
|
74
|
+
|
|
75
|
+
:returns: database id of a language code needed for translations
|
|
76
|
+
:rtype: int
|
|
77
|
+
"""
|
|
78
|
+
if request.locale_name not in request._database_locales:
|
|
79
|
+
_create_locale(request.locale_name, request)
|
|
80
|
+
|
|
81
|
+
return request._database_locales[request.locale_name].id
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def database_locales(request):
|
|
85
|
+
"""
|
|
86
|
+
Return list of all database locales available.
|
|
87
|
+
|
|
88
|
+
:returns: dictionary of Language objects language_code: Language
|
|
89
|
+
:rtype: dict
|
|
90
|
+
"""
|
|
91
|
+
locales = {}
|
|
92
|
+
for language in pyramid_basemodel.Session.query(Language).all():
|
|
93
|
+
locales[language.language_code] = language
|
|
94
|
+
|
|
95
|
+
return locales
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def locales(request, config=False):
|
|
99
|
+
"""
|
|
100
|
+
Return a list of locales.
|
|
101
|
+
|
|
102
|
+
:param bool config: Whether to restrict list with config
|
|
103
|
+
|
|
104
|
+
:returns: dictionary of Language objects language_code: Language
|
|
105
|
+
:rtype: dict
|
|
106
|
+
"""
|
|
107
|
+
if config:
|
|
108
|
+
locales = {}
|
|
109
|
+
for locale in request.registry['config'].localize.locales.available:
|
|
110
|
+
if locale not in request._database_locales:
|
|
111
|
+
_create_locale(locale, request)
|
|
112
|
+
locales[locale] = request._database_locales[locale]
|
|
113
|
+
|
|
114
|
+
return locales
|
|
115
|
+
|
|
116
|
+
return request._database_locales
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _create_locale(locale, request):
|
|
120
|
+
new_locale = Language(name=text_type(locale),
|
|
121
|
+
native_name=text_type(locale),
|
|
122
|
+
language_code=text_type(locale))
|
|
123
|
+
pyramid_basemodel.Session.add(new_locale)
|
|
124
|
+
request._database_locales = database_locales(request)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Translations template for pyramid_localize.
|
|
2
|
+
# Copyright (C) 2013 ORGANIZATION
|
|
3
|
+
# This file is distributed under the same license as the pyramid_localize
|
|
4
|
+
# project.
|
|
5
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
|
6
|
+
#
|
|
7
|
+
#, fuzzy
|
|
8
|
+
msgid ""
|
|
9
|
+
msgstr ""
|
|
10
|
+
"Project-Id-Version: pyramid_localize 0.0.1\n"
|
|
11
|
+
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
|
12
|
+
"POT-Creation-Date: 2013-06-06 22:20+0200\n"
|
|
13
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
14
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
15
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
16
|
+
"MIME-Version: 1.0\n"
|
|
17
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
19
|
+
"Generated-By: Babel 0.9.6\n"
|
|
20
|
+
|
|
21
|
+
#: pyramid_localize/resources/templates/_list.mako:5
|
|
22
|
+
msgid "Language"
|
|
23
|
+
msgstr ""
|
|
24
|
+
|
|
25
|
+
#: pyramid_localize/resources/templates/_list.mako:6
|
|
26
|
+
msgid "Translation domain"
|
|
27
|
+
msgstr ""
|
|
28
|
+
|
|
29
|
+
#: pyramid_localize/resources/templates/_list.mako:7
|
|
30
|
+
#: pyramid_localize/resources/templates/_list.mako:8
|
|
31
|
+
#: pyramid_localize/resources/templates/_list.mako:9
|
|
32
|
+
msgid "${type} modification time"
|
|
33
|
+
msgstr ""
|
|
34
|
+
|
|
35
|
+
#: pyramid_localize/resources/templates/index.mako:4
|
|
36
|
+
msgid "Translations"
|
|
37
|
+
msgstr ""
|
|
38
|
+
|
|
39
|
+
#: pyramid_localize/resources/templates/index.mako:6
|
|
40
|
+
msgid "Update catalog"
|
|
41
|
+
msgstr ""
|
|
42
|
+
|
|
43
|
+
#: pyramid_localize/resources/templates/index.mako:7
|
|
44
|
+
msgid "Compile catalog"
|
|
45
|
+
msgstr ""
|
|
46
|
+
|
|
47
|
+
#: pyramid_localize/resources/templates/index.mako:8
|
|
48
|
+
msgid "Reload catalog"
|
|
49
|
+
msgstr ""
|
|
50
|
+
|
|
51
|
+
#: pyramid_localize/resources/templates/layout.mako:3
|
|
52
|
+
msgid "Welcome, to pyramid_localize!"
|
|
53
|
+
msgstr ""
|
|
54
|
+
|
|
55
|
+
#: pyramid_localize/views/catalog.py:166
|
|
56
|
+
msgid "Localizators has been reloaded"
|
|
57
|
+
msgstr ""
|
|
58
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<%doc>
|
|
2
|
+
Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
3
|
+
|
|
4
|
+
This module is part of pyramid_localize and is released under
|
|
5
|
+
the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
6
|
+
</%doc>
|
|
7
|
+
<table class="table table-hover">
|
|
8
|
+
<thead>
|
|
9
|
+
<tr>
|
|
10
|
+
<th>${_('Language', domain='pyramid_localize')}</th>
|
|
11
|
+
<th>${_('Translation domain', domain='pyramid_localize')}</th>
|
|
12
|
+
<th>${_('${type} modification time', domain='pyramid_localize', mapping={'type': 'pot'})}</th>
|
|
13
|
+
<th>${_('${type} modification time', domain='pyramid_localize', mapping={'type': 'po'})}</th>
|
|
14
|
+
<th>${_('${type} modification time', domain='pyramid_localize', mapping={'type': 'mo'})}</th>
|
|
15
|
+
</tr>
|
|
16
|
+
</thead>
|
|
17
|
+
<tbody>
|
|
18
|
+
% for language in translations:
|
|
19
|
+
<tr>
|
|
20
|
+
<td rowspan="${len(translations[language]) if len(translations[language]) > 1 else 1}">${language}</td>
|
|
21
|
+
% for domain in translations[language]:
|
|
22
|
+
<td>${domain}</td>
|
|
23
|
+
<td>${translations[language][domain]['pot']}</td>
|
|
24
|
+
<td>${translations[language][domain]['po']}</td>
|
|
25
|
+
<td>${translations[language][domain]['mo']}</td>
|
|
26
|
+
% if len(translations[language]) > 1:
|
|
27
|
+
</tr><tr>
|
|
28
|
+
% endif
|
|
29
|
+
% endfor
|
|
30
|
+
</tr>
|
|
31
|
+
% endfor
|
|
32
|
+
</tbody>
|
|
33
|
+
</table>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<%doc>
|
|
2
|
+
Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
3
|
+
|
|
4
|
+
This module is part of pyramid_localize and is released under
|
|
5
|
+
the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
6
|
+
</%doc>
|
|
7
|
+
<%inherit file="pyramid_localize:resources/templates/layout.mako" />
|
|
8
|
+
<div class="row">
|
|
9
|
+
<div class="span9">
|
|
10
|
+
<h1>${_('Translations', domain='pyramid_localize')}</h1>
|
|
11
|
+
<p>
|
|
12
|
+
<a href="${request.route_path('localize:update')}" class="btn">${_('Update catalog', domain='pyramid_localize')}</a>
|
|
13
|
+
<a href="${request.route_path('localize:compile')}" class="btn">${_('Compile catalog', domain='pyramid_localize')}</a>
|
|
14
|
+
<a href="${request.route_path('localize:reload')}" class="btn">${_('Reload catalog', domain='pyramid_localize')}</a>
|
|
15
|
+
</p>
|
|
16
|
+
<%include file="_list.mako" />
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<%doc>
|
|
2
|
+
Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
3
|
+
|
|
4
|
+
This module is part of pyramid_localize and is released under
|
|
5
|
+
the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
6
|
+
</%doc>
|
|
7
|
+
<html>
|
|
8
|
+
<body>
|
|
9
|
+
<h1>${_('Welcome, to pyramid_localize!', domain='pyramid_localize')}</h1>
|
|
10
|
+
${next.body()}
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""Localize route predicate."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def language(field):
|
|
9
|
+
"""Create language predicate for given url match field."""
|
|
10
|
+
def predicate(info, request):
|
|
11
|
+
"""Check whether language is one of the defaults."""
|
|
12
|
+
if field in info['match'] and\
|
|
13
|
+
info['match'][field] in request.registry['config'].localize.locales.available:
|
|
14
|
+
return True
|
|
15
|
+
return False
|
|
16
|
+
return predicate
|
|
17
|
+
|
|
18
|
+
language.__text__ = 'language predicate, to determine allowed languages in route'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""Subscribers adding mocked translation methods to render context, and request."""
|
|
6
|
+
|
|
7
|
+
from pyramid.events import subscriber
|
|
8
|
+
from pyramid.events import BeforeRender
|
|
9
|
+
from pyramid.events import NewRequest
|
|
10
|
+
|
|
11
|
+
from pyramid_localize.tools import dummy_autotranslate
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@subscriber(BeforeRender)
|
|
15
|
+
def global_renderer(event):
|
|
16
|
+
"""BeforeRender subscriber, adds fake localizer, and translation methods to context."""
|
|
17
|
+
request = event['request']
|
|
18
|
+
try:
|
|
19
|
+
event['_'] = request._
|
|
20
|
+
except AttributeError:
|
|
21
|
+
event['_'] = dummy_autotranslate
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@subscriber(NewRequest)
|
|
25
|
+
def add_localizer(event):
|
|
26
|
+
"""NewRequest subscriber, adds fake localizer and translation methods to request."""
|
|
27
|
+
event.request._ = dummy_autotranslate
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""i18n subscribers."""
|
|
6
|
+
|
|
7
|
+
from pyramid.events import subscriber
|
|
8
|
+
from pyramid.events import BeforeRender
|
|
9
|
+
from pyramid.events import NewRequest
|
|
10
|
+
|
|
11
|
+
from pyramid_localize.tools import set_localizer
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@subscriber(BeforeRender)
|
|
15
|
+
def global_renderer(event):
|
|
16
|
+
"""BeforeRender subscriber, adds localizer, and translation methods to context."""
|
|
17
|
+
request = event['request']
|
|
18
|
+
set_localizer(request)
|
|
19
|
+
|
|
20
|
+
event['_'] = request._
|
|
21
|
+
event['localizer'] = request.localizer
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@subscriber(NewRequest)
|
|
25
|
+
def add_localizer(event):
|
|
26
|
+
"""NewRequest subscriber, adds localizer and translation methods to request."""
|
|
27
|
+
set_localizer(event.request)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 by pyramid_localize authors and contributors <see AUTHORS file>
|
|
2
|
+
#
|
|
3
|
+
# This module is part of pyramid_localize and is released under
|
|
4
|
+
# the MIT License (MIT): http://opensource.org/licenses/MIT
|
|
5
|
+
"""methods in this module are tools, thank to which pyramid_localize works most of its magic."""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from translationstring import _interp_regex
|
|
12
|
+
from pyramid.i18n import make_localizer
|
|
13
|
+
from pyramid.i18n import TranslationString
|
|
14
|
+
from pyramid.asset import resolve_asset_spec
|
|
15
|
+
from pyramid.path import package_path
|
|
16
|
+
from pyramid.interfaces import ILocalizer
|
|
17
|
+
from pyramid.interfaces import ITranslationDirectories
|
|
18
|
+
from pyramid.compat import text_type
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def set_localizer(request, reset=False):
|
|
24
|
+
"""
|
|
25
|
+
Set localizer and auto_translate methods for request.
|
|
26
|
+
|
|
27
|
+
:param pyramid.request.Request request: request object
|
|
28
|
+
:param bool reset: flag that directs resetting localizer within app
|
|
29
|
+
"""
|
|
30
|
+
if reset:
|
|
31
|
+
|
|
32
|
+
for locale in request.registry['config'].localize.locales.available:
|
|
33
|
+
logger.debug('Resetting {0} localizator'.format(locale))
|
|
34
|
+
tdirs = request.registry.queryUtility(ITranslationDirectories,
|
|
35
|
+
default=[])
|
|
36
|
+
localizer = make_localizer(locale, tdirs)
|
|
37
|
+
request.registry.registerUtility(localizer, ILocalizer,
|
|
38
|
+
name=locale)
|
|
39
|
+
|
|
40
|
+
def auto_translate(*args, **kwargs):
|
|
41
|
+
# lets pass default domain, so we don't have to determine it with
|
|
42
|
+
# each _() function in apps.
|
|
43
|
+
if len(args) <= 1 and 'domain' not in kwargs:
|
|
44
|
+
kwargs['domain'] = request.registry['config'].localize.domain
|
|
45
|
+
|
|
46
|
+
# unlike in examples we use TranslationString, to make sure we always
|
|
47
|
+
# use appropriate domain
|
|
48
|
+
return request.localizer.translate(TranslationString(*args, **kwargs))
|
|
49
|
+
|
|
50
|
+
request._ = auto_translate
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def destination_path(request):
|
|
54
|
+
"""
|
|
55
|
+
Return absolute path of the translation destination.
|
|
56
|
+
|
|
57
|
+
:param pyramid.request.Request request: a request object
|
|
58
|
+
|
|
59
|
+
:returns: A combined translation destination path
|
|
60
|
+
:rtype: str
|
|
61
|
+
"""
|
|
62
|
+
package_name, filename = resolve_asset_spec(
|
|
63
|
+
request.registry['config'].localize.translation.destination
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
if package_name is None: # absolute filename
|
|
67
|
+
directory = filename
|
|
68
|
+
else:
|
|
69
|
+
__import__(package_name)
|
|
70
|
+
package = sys.modules[package_name]
|
|
71
|
+
directory = os.path.join(package_path(package), filename)
|
|
72
|
+
return directory
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def dummy_autotranslate(msgid, domain=None, default=None, mapping=None):
|
|
76
|
+
"""
|
|
77
|
+
Method that simulate autotranslate.
|
|
78
|
+
|
|
79
|
+
:param str msgid: Message or message id
|
|
80
|
+
:param str domain: Translation domain
|
|
81
|
+
:param str default: Default message
|
|
82
|
+
:param dict mapping: Mapping dictionary for message variables
|
|
83
|
+
|
|
84
|
+
:returns: *translated* string
|
|
85
|
+
:rtype: str
|
|
86
|
+
"""
|
|
87
|
+
# Try to return defaults first:
|
|
88
|
+
tstr = None
|
|
89
|
+
if default:
|
|
90
|
+
tstr = default
|
|
91
|
+
else:
|
|
92
|
+
tstr = msgid
|
|
93
|
+
|
|
94
|
+
if mapping and tstr:
|
|
95
|
+
def replace(match):
|
|
96
|
+
whole, param1, param2 = match.groups()
|
|
97
|
+
return text_type(mapping.get(param1 or param2, whole))
|
|
98
|
+
tstr = _interp_regex.sub(replace, tstr)
|
|
99
|
+
|
|
100
|
+
return tstr
|