forked from I2P_Developers/i2p.www
merge of '5b4836353e90a3c1e388a18fe4184b748f920317'
and '6fd06d2ac31dd55d96ed51f368f4b3cf5c5faef0'
This commit is contained in:
2
.mtn-ignore
Normal file
2
.mtn-ignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
env
|
||||||
|
pots
|
75
.tx/config
75
.tx/config
@@ -1,10 +1,73 @@
|
|||||||
[I2P.website]
|
[I2P.website_about]
|
||||||
source_file = ./messages.pot
|
source_file = ./pots/about.pot
|
||||||
source_lang = en
|
source_lang = en
|
||||||
trans.de = i2p2www/translations/de/LC_MESSAGES/messages.po
|
trans.de = i2p2www/translations/de/LC_MESSAGES/about.po
|
||||||
trans.es = i2p2www/translations/es/LC_MESSAGES/messages.po
|
trans.es = i2p2www/translations/es/LC_MESSAGES/about.po
|
||||||
trans.fr = i2p2www/translations/fr/LC_MESSAGES/messages.po
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/about.po
|
||||||
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/messages.po
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/about.po
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[I2P.website_blog]
|
||||||
|
source_file = ./pots/blog.pot
|
||||||
|
source_lang = en
|
||||||
|
trans.de = i2p2www/translations/de/LC_MESSAGES/blog.po
|
||||||
|
trans.es = i2p2www/translations/es/LC_MESSAGES/blog.po
|
||||||
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/blog.po
|
||||||
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/blog.po
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[I2P.website_comparison]
|
||||||
|
source_file = ./pots/comparison.pot
|
||||||
|
source_lang = en
|
||||||
|
trans.de = i2p2www/translations/de/LC_MESSAGES/comparison.po
|
||||||
|
trans.es = i2p2www/translations/es/LC_MESSAGES/comparison.po
|
||||||
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/comparison.po
|
||||||
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/comparison.po
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[I2P.website_docs]
|
||||||
|
source_file = ./pots/docs.pot
|
||||||
|
source_lang = en
|
||||||
|
trans.de = i2p2www/translations/de/LC_MESSAGES/docs.po
|
||||||
|
trans.es = i2p2www/translations/es/LC_MESSAGES/docs.po
|
||||||
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/docs.po
|
||||||
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/docs.po
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[I2P.website_get-involved]
|
||||||
|
source_file = ./pots/get-involved.pot
|
||||||
|
source_lang = en
|
||||||
|
trans.de = i2p2www/translations/de/LC_MESSAGES/get-involved.po
|
||||||
|
trans.es = i2p2www/translations/es/LC_MESSAGES/get-involved.po
|
||||||
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/get-involved.po
|
||||||
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/get-involved.po
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[I2P.website_misc]
|
||||||
|
source_file = ./pots/misc.pot
|
||||||
|
source_lang = en
|
||||||
|
trans.de = i2p2www/translations/de/LC_MESSAGES/misc.po
|
||||||
|
trans.es = i2p2www/translations/es/LC_MESSAGES/misc.po
|
||||||
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/misc.po
|
||||||
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/misc.po
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[I2P.website_priority]
|
||||||
|
source_file = ./pots/priority.pot
|
||||||
|
source_lang = en
|
||||||
|
trans.de = i2p2www/translations/de/LC_MESSAGES/priority.po
|
||||||
|
trans.es = i2p2www/translations/es/LC_MESSAGES/priority.po
|
||||||
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/priority.po
|
||||||
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/priority.po
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[I2P.website_research]
|
||||||
|
source_file = ./pots/research.pot
|
||||||
|
source_lang = en
|
||||||
|
trans.de = i2p2www/translations/de/LC_MESSAGES/research.po
|
||||||
|
trans.es = i2p2www/translations/es/LC_MESSAGES/research.po
|
||||||
|
trans.fr = i2p2www/translations/fr/LC_MESSAGES/research.po
|
||||||
|
trans.sv_SE = i2p2www/translations/sv/LC_MESSAGES/research.po
|
||||||
type = PO
|
type = PO
|
||||||
|
|
||||||
[main]
|
[main]
|
||||||
|
2
babel.cfg/about
Normal file
2
babel.cfg/about
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[jinja2: **/pages/site/about/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
2
babel.cfg/blog
Normal file
2
babel.cfg/blog
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[jinja2: **/blog/**.rst]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_
|
2
babel.cfg/comparison
Normal file
2
babel.cfg/comparison
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[jinja2: **/pages/site/comparison/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
2
babel.cfg/docs
Normal file
2
babel.cfg/docs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[jinja2: **/pages/site/docs/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
2
babel.cfg/get-involved
Normal file
2
babel.cfg/get-involved
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[jinja2: **/pages/site/get-involved/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
2
babel.cfg/misc
Normal file
2
babel.cfg/misc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[jinja2: **/pages/site/misc/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
12
babel.cfg/priority
Normal file
12
babel.cfg/priority
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[jinja2: **/pages/blog/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
||||||
|
[jinja2: **/pages/downloads/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
||||||
|
[jinja2: **/pages/global/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
||||||
|
[jinja2: **/pages/global/macros]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_
|
||||||
|
[jinja2: **/pages/meetings/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
||||||
|
[jinja2: **/pages/site/*.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
2
babel.cfg/research
Normal file
2
babel.cfg/research
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[jinja2: **/pages/site/research/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
@@ -1,4 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. ./translation.vars
|
. ./translation.vars
|
||||||
|
|
||||||
TZ=UTC env/bin/pybabel compile -d $TRANSDIR
|
for domain in $(ls $BABELCFG); do
|
||||||
|
TZ=UTC env/bin/pybabel compile -D $domain -d $TRANSDIR
|
||||||
|
done
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. ./translation.vars
|
. ./translation.vars
|
||||||
|
|
||||||
|
if [ ! -e $POTDIR ]; then
|
||||||
|
mkdir $POTDIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
for domain in $(ls $BABELCFG); do
|
||||||
TZ=UTC ./pybabel extract --msgid-bugs-address="http://trac.i2p2.de" \
|
TZ=UTC ./pybabel extract --msgid-bugs-address="http://trac.i2p2.de" \
|
||||||
--project=$PROJECT \
|
--project=$PROJECT \
|
||||||
--version=$VERSION \
|
--version=$VERSION \
|
||||||
-F $BABELCFG \
|
-F $BABELCFG/$domain \
|
||||||
-o $POTFILE $PROJDIR
|
-o $POTDIR/$domain.pot $PROJDIR
|
||||||
|
done
|
||||||
|
@@ -32,6 +32,17 @@ SUPPORTED_LANGS = [
|
|||||||
# 'el',
|
# 'el',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
DEFAULT_GETTEXT_DOMAIN = 'priority'
|
||||||
|
GETTEXT_DOMAIN_MAPPING = {
|
||||||
|
'about': ['about'],
|
||||||
|
'blog': ['blog'],
|
||||||
|
'comparison': ['comparison'],
|
||||||
|
'docs': ['docs'],
|
||||||
|
'get-involved': ['get-involved'],
|
||||||
|
'misc': ['misc'],
|
||||||
|
'research': ['research'],
|
||||||
|
}
|
||||||
|
|
||||||
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'pages')
|
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'pages')
|
||||||
STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
|
STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
|
||||||
BLOG_DIR = os.path.join(os.path.dirname(__file__), 'blog')
|
BLOG_DIR = os.path.join(os.path.dirname(__file__), 'blog')
|
||||||
@@ -50,7 +61,7 @@ class MyFlask(Flask):
|
|||||||
|
|
||||||
app = application = MyFlask('i2p2www', template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR)
|
app = application = MyFlask('i2p2www', template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR)
|
||||||
app.debug = bool(os.environ.get('APP_DEBUG', 'False'))
|
app.debug = bool(os.environ.get('APP_DEBUG', 'False'))
|
||||||
babel = Babel(app)
|
babel = Babel(app, default_domain='priority')
|
||||||
cache = Cache(app, config={
|
cache = Cache(app, config={
|
||||||
'CACHE_DEFAULT_TIMEOUT': 600,
|
'CACHE_DEFAULT_TIMEOUT': 600,
|
||||||
#'CACHE_TYPE': '', # See http://packages.python.org/Flask-Cache/#configuring-flask-cache
|
#'CACHE_TYPE': '', # See http://packages.python.org/Flask-Cache/#configuring-flask-cache
|
||||||
@@ -67,7 +78,22 @@ def get_locale():
|
|||||||
return g.lang
|
return g.lang
|
||||||
# otherwise try to guess the language from the user accept
|
# otherwise try to guess the language from the user accept
|
||||||
# header the browser transmits. The best match wins.
|
# header the browser transmits. The best match wins.
|
||||||
return request.accept_languages.best_match(['en', 'es', 'zh', 'de', 'fr', 'it', 'nl', 'ru', 'sv', 'cs', 'ar'])
|
return request.accept_languages.best_match(SUPPORTED_LANGS)
|
||||||
|
|
||||||
|
@babel.domainselector
|
||||||
|
def get_domains():
|
||||||
|
domains = []
|
||||||
|
frags = request.path.split('/', 2)
|
||||||
|
if len(frags) == 3:
|
||||||
|
path = frags[2]
|
||||||
|
for subpath in GETTEXT_DOMAIN_MAPPING:
|
||||||
|
if path.startswith(subpath):
|
||||||
|
domains.extend(GETTEXT_DOMAIN_MAPPING[subpath])
|
||||||
|
# Always end with the priority domain, as it contains
|
||||||
|
# various template strings and is likely to be the most
|
||||||
|
# up-to-date (in case of any common translation strings).
|
||||||
|
domains.append(DEFAULT_GETTEXT_DOMAIN)
|
||||||
|
return domains
|
||||||
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
[python: **.py]
|
|
||||||
[jinja2: **/pages/**.html]
|
|
||||||
extensions=jinja2.ext.autoescape,jinja2.ext.with_,i2p2www.extensions.HighlightExtension
|
|
||||||
[jinja2: **/pages/global/macros]
|
|
||||||
extensions=jinja2.ext.autoescape,jinja2.ext.with_
|
|
||||||
[jinja2: **/blog/**.rst]
|
|
||||||
extensions=jinja2.ext.autoescape,jinja2.ext.with_
|
|
@@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
if [ $# -ge 1 ]
|
if [ $# -ge 1 ]
|
||||||
then
|
then
|
||||||
TZ=UTC env/bin/pybabel init -i $POTFILE -d $TRANSDIR -l $1
|
for domain in $(ls $BABELCFG); do
|
||||||
|
TZ=UTC env/bin/pybabel init -D $domain -i $POTDIR/$domain.pot -d $TRANSDIR -l $1
|
||||||
|
done
|
||||||
else
|
else
|
||||||
echo "Usage: ./init-new-po.sh lang"
|
echo "Usage: ./init-new-po.sh lang"
|
||||||
fi
|
fi
|
||||||
|
115
multi-domain.patch
Normal file
115
multi-domain.patch
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
--- env/lib/python2.7/site-packages/flaskext/babel.py 2013-07-13 00:00:00 +0000
|
||||||
|
+++ env/lib/python2.7/site-packages/flaskext/babel.py 2013-07-13 00:00:00 +0000
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from flask import _request_ctx_stack
|
||||||
|
from babel import dates, numbers, support, Locale
|
||||||
|
+from gettext import NullTranslations
|
||||||
|
from werkzeug import ImmutableDict
|
||||||
|
try:
|
||||||
|
from pytz.gae import pytz
|
||||||
|
@@ -55,9 +56,11 @@
|
||||||
|
})
|
||||||
|
|
||||||
|
def __init__(self, app=None, default_locale='en', default_timezone='UTC',
|
||||||
|
- date_formats=None, configure_jinja=True):
|
||||||
|
+ date_formats=None, configure_jinja=True,
|
||||||
|
+ default_domain=support.Translations.DEFAULT_DOMAIN):
|
||||||
|
self._default_locale = default_locale
|
||||||
|
self._default_timezone = default_timezone
|
||||||
|
+ self._default_domain = default_domain
|
||||||
|
self._date_formats = date_formats
|
||||||
|
self._configure_jinja = configure_jinja
|
||||||
|
self.app = app
|
||||||
|
@@ -77,6 +80,7 @@
|
||||||
|
|
||||||
|
app.config.setdefault('BABEL_DEFAULT_LOCALE', self._default_locale)
|
||||||
|
app.config.setdefault('BABEL_DEFAULT_TIMEZONE', self._default_timezone)
|
||||||
|
+ app.config.setdefault('BABEL_DEFAULT_DOMAIN', self._default_domain)
|
||||||
|
if self._date_formats is None:
|
||||||
|
self._date_formats = self.default_date_formats.copy()
|
||||||
|
|
||||||
|
@@ -95,6 +99,7 @@
|
||||||
|
|
||||||
|
self.locale_selector_func = None
|
||||||
|
self.timezone_selector_func = None
|
||||||
|
+ self.domain_selector_func = None
|
||||||
|
|
||||||
|
if self._configure_jinja:
|
||||||
|
app.jinja_env.filters.update(
|
||||||
|
@@ -142,6 +147,19 @@
|
||||||
|
self.timezone_selector_func = f
|
||||||
|
return f
|
||||||
|
|
||||||
|
+ def domainselector(self, f):
|
||||||
|
+ """Registers a callback function for domain selection. The default
|
||||||
|
+ behaves as if a function was registered that returns `None` all the
|
||||||
|
+ time. If `None` is returned, the domain falls back to the one from
|
||||||
|
+ the configuration.
|
||||||
|
+
|
||||||
|
+ This has to return the domain as a list of strings (eg: ``['messages']``)
|
||||||
|
+ """
|
||||||
|
+ assert self.domain_selector_func is None, \
|
||||||
|
+ 'a localeselector function is already registered'
|
||||||
|
+ self.domain_selector_func = f
|
||||||
|
+ return f
|
||||||
|
+
|
||||||
|
|
||||||
|
def list_translations(self):
|
||||||
|
"""Returns a list of all the locales translations exist for. The
|
||||||
|
@@ -178,6 +196,13 @@
|
||||||
|
"""
|
||||||
|
return timezone(self.app.config['BABEL_DEFAULT_TIMEZONE'])
|
||||||
|
|
||||||
|
+ @property
|
||||||
|
+ def default_domain(self):
|
||||||
|
+ """The default domain from the configuration as instance of a
|
||||||
|
+ `string` object.
|
||||||
|
+ """
|
||||||
|
+ return self.app.config['BABEL_DEFAULT_DOMAIN']
|
||||||
|
+
|
||||||
|
|
||||||
|
def get_translations():
|
||||||
|
"""Returns the correct gettext translations that should be used for
|
||||||
|
@@ -191,7 +216,10 @@
|
||||||
|
translations = getattr(ctx, 'babel_translations', None)
|
||||||
|
if translations is None:
|
||||||
|
dirname = os.path.join(ctx.app.root_path, 'translations')
|
||||||
|
- translations = support.Translations.load(dirname, [get_locale()])
|
||||||
|
+ locale = get_locale()
|
||||||
|
+ for domain in get_domains():
|
||||||
|
+ dt = support.Translations.load(dirname, [locale], domain)
|
||||||
|
+ translations = dt if translations is None or not hasattr(translations, 'merge') else translations.merge(dt)
|
||||||
|
ctx.babel_translations = translations
|
||||||
|
return translations
|
||||||
|
|
||||||
|
@@ -243,6 +271,29 @@
|
||||||
|
return tzinfo
|
||||||
|
|
||||||
|
|
||||||
|
+def get_domains():
|
||||||
|
+ """Returns the domains that should be used for this request as
|
||||||
|
+ `list` object. This returns `None` if used outside of
|
||||||
|
+ a request.
|
||||||
|
+ """
|
||||||
|
+ ctx = _request_ctx_stack.top
|
||||||
|
+ if ctx is None:
|
||||||
|
+ return None
|
||||||
|
+ domains = getattr(ctx, 'babel_domains', None)
|
||||||
|
+ if domains is None:
|
||||||
|
+ babel = ctx.app.extensions['babel']
|
||||||
|
+ if babel.domain_selector_func is None:
|
||||||
|
+ domains = [babel.default_domain]
|
||||||
|
+ else:
|
||||||
|
+ rv = babel.domain_selector_func()
|
||||||
|
+ if rv is None:
|
||||||
|
+ domains = [babel.default_domain]
|
||||||
|
+ else:
|
||||||
|
+ domains = rv
|
||||||
|
+ ctx.babel_domains = domains
|
||||||
|
+ return domains
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def refresh():
|
||||||
|
"""Refreshes the cached timezones and locale information. This can
|
||||||
|
be used to switch a translation between a request and if you want
|
@@ -11,4 +11,6 @@ else
|
|||||||
|
|
||||||
. $venv_dir/bin/activate
|
. $venv_dir/bin/activate
|
||||||
pip install -r reqs.txt
|
pip install -r reqs.txt
|
||||||
|
# Apply multi-domain patch to Flask-Babel
|
||||||
|
patch -p0 <multi-domain.patch
|
||||||
fi
|
fi
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
PROJECT=I2P
|
PROJECT=I2P
|
||||||
VERSION=website
|
VERSION=website
|
||||||
|
BABELCFG=babel.cfg
|
||||||
|
POTDIR=pots
|
||||||
PROJDIR=i2p2www
|
PROJDIR=i2p2www
|
||||||
BABELCFG=$PROJDIR/babel.cfg
|
|
||||||
POTFILE=messages.pot
|
|
||||||
TRANSDIR=$PROJDIR/translations
|
TRANSDIR=$PROJDIR/translations
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. ./translation.vars
|
. ./translation.vars
|
||||||
|
|
||||||
TZ=UTC env/bin/pybabel update -i $POTFILE -d $TRANSDIR
|
for domain in $(ls $BABELCFG); do
|
||||||
|
TZ=UTC env/bin/pybabel update -D $domain -i $POTDIR/$domain.pot -d $TRANSDIR
|
||||||
|
done
|
||||||
|
Reference in New Issue
Block a user