Commit 37d7b1ca authored by Patrik Dufresne's avatar Patrik Dufresne

Change translation layer

parent f391ebed
...@@ -159,7 +159,7 @@ class AuthFormTool(BaseAuth): ...@@ -159,7 +159,7 @@ class AuthFormTool(BaseAuth):
# Add welcome message to params. Try to load translated message. # Add welcome message to params. Try to load translated message.
params["welcome_msg"] = app.cfg.get_config("WelcomeMsg") params["welcome_msg"] = app.cfg.get_config("WelcomeMsg")
if hasattr(cherrypy.response, 'i18n'): if hasattr(cherrypy.response, 'i18n'):
lang = cherrypy.response.i18n._lang lang = cherrypy.response.i18n.locale.language
params["welcome_msg"] = app.cfg.get_config("WelcomeMsg[%s]" % (lang), params["welcome_msg"]) params["welcome_msg"] = app.cfg.get_config("WelcomeMsg[%s]" % (lang), params["welcome_msg"])
return main_page._compile_template("login.html", **params).encode("utf-8") return main_page._compile_template("login.html", **params).encode("utf-8")
......
This diff is collapsed.
...@@ -25,8 +25,7 @@ from future.utils.surrogateescape import encodefilename ...@@ -25,8 +25,7 @@ from future.utils.surrogateescape import encodefilename
import logging import logging
from rdiffweb.core import Component from rdiffweb.core import Component
from rdiffweb.i18n import get_current_lang from rdiffweb.librdiff import RdiffRepo, DoesNotExistError
from rdiffweb.librdiff import RdiffRepo, AccessDeniedError, DoesNotExistError
from rdiffweb.rdw_plugin import ITemplateFilterPlugin from rdiffweb.rdw_plugin import ITemplateFilterPlugin
...@@ -123,8 +122,9 @@ class MainPage(Component): ...@@ -123,8 +122,9 @@ class MainPage(Component):
This method should be used by subclasses to provide default template This method should be used by subclasses to provide default template
value. value.
""" """
loc = cherrypy.response.i18n.locale
parms = { parms = {
"lang": get_current_lang(), "lang": loc.language,
"version": self.app.get_version(), "version": self.app.get_version(),
"extra_head_templates": [], "extra_head_templates": [],
} }
......
...@@ -107,6 +107,9 @@ class RdiffwebApp(Application): ...@@ -107,6 +107,9 @@ class RdiffwebApp(Application):
native_str('/'): { native_str('/'): {
'tools.authform.on': True, 'tools.authform.on': True,
'tools.i18n.on': True, 'tools.i18n.on': True,
'tools.i18n.default': 'en_US',
'tools.i18n.mo_dir': self._localedirs(),
'tools.i18n.domain': 'messages',
'tools.encode.on': True, 'tools.encode.on': True,
'tools.encode.encoding': 'utf-8', 'tools.encode.encoding': 'utf-8',
'tools.gzip.on': True, 'tools.gzip.on': True,
...@@ -201,6 +204,20 @@ class RdiffwebApp(Application): ...@@ -201,6 +204,20 @@ class RdiffwebApp(Application):
if tempdir: if tempdir:
os.environ["TMPDIR"] = tempdir os.environ["TMPDIR"] = tempdir
def _localedirs(self):
"""
Return a list of locales directory where to search for mo files. This
include locales from plugins.
"""
localesdirs = [
pkg_resources.resource_filename('rdiffweb', 'locales') # @UndefinedVariable
]
# Get more directory from app plugins.
for p in self.plugins.get_all_plugins():
if p.get_localesdir():
localesdirs.append(p.get_localesdir())
return localesdirs
def _setup_session_storage(self, config): def _setup_session_storage(self, config):
# Configure session storage. # Configure session storage.
session_storage = self.cfg.get_config("SessionStorage") session_storage = self.cfg.get_config("SessionStorage")
......
...@@ -24,7 +24,6 @@ from builtins import object ...@@ -24,7 +24,6 @@ from builtins import object
from builtins import str from builtins import str
from io import StringIO from io import StringIO
from jinja2 import Environment, PackageLoader from jinja2 import Environment, PackageLoader
from jinja2.ext import _make_new_gettext, _make_new_ngettext
from jinja2.loaders import ChoiceLoader, FileSystemLoader from jinja2.loaders import ChoiceLoader, FileSystemLoader
import logging import logging
import time import time
...@@ -217,16 +216,6 @@ def url_for_status_entry(date, repo=None): ...@@ -217,16 +216,6 @@ def url_for_status_entry(date, repo=None):
return ''.join(url) return ''.join(url)
def _get_translation(domain):
"""
Used in templates to load a different translation domain.
"""
t = i18n.get_translation(domain)
t.ugettext = _make_new_gettext(t.ugettext)
t.ungettext = _make_new_ngettext(t.ungettext)
return t
class TemplateManager(object): class TemplateManager(object):
""" """
Uses to generate HTML page from template using Jinja2 templating. Uses to generate HTML page from template using Jinja2 templating.
...@@ -261,8 +250,6 @@ class TemplateManager(object): ...@@ -261,8 +250,6 @@ class TemplateManager(object):
self.jinja_env.globals['url_for_restore'] = url_for_restore self.jinja_env.globals['url_for_restore'] = url_for_restore
self.jinja_env.globals['url_for_settings'] = url_for_settings self.jinja_env.globals['url_for_settings'] = url_for_settings
self.jinja_env.globals['url_for_status_entry'] = url_for_status_entry self.jinja_env.globals['url_for_status_entry'] = url_for_status_entry
self.jinja_env.globals['load_translation'] = _get_translation
self.jinja_env.globals['get_translation'] = _get_translation
def add_templatesdir(self, templates_dir): def add_templatesdir(self, templates_dir):
""" """
......
...@@ -25,6 +25,7 @@ Module used to test the i18n tools. Check if translation are properly loaded. ...@@ -25,6 +25,7 @@ Module used to test the i18n tools. Check if translation are properly loaded.
from __future__ import unicode_literals from __future__ import unicode_literals
from cherrypy import _cpconfig
import cherrypy import cherrypy
import gettext import gettext
import pkg_resources import pkg_resources
...@@ -38,37 +39,46 @@ class Test(unittest.TestCase): ...@@ -38,37 +39,46 @@ class Test(unittest.TestCase):
def setUp(self): def setUp(self):
self.mo_dir = pkg_resources.resource_filename('rdiffweb', 'locales') # @UndefinedVariable self.mo_dir = pkg_resources.resource_filename('rdiffweb', 'locales') # @UndefinedVariable
cherrypy.request.config = _cpconfig.Config()
def tearDown(self): def tearDown(self):
pass pass
def test_load_translation(self): def test_load_translation(self):
# Load default translation # Load default translation
t = i18n.get_translation() i18n.get_lang(self.mo_dir, 'en_US', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("en", t._lang) self.assertEqual("en", l.language)
def test_load_translation_with_accept_language_fr(self): def test_load_translation_with_accept_language_fr(self):
# Mock a header # Mock a header
cherrypy.request.headers["Accept-Language"] = "fr_CA,fr,en_en_US" cherrypy.request.headers["Accept-Language"] = "fr_CA,fr,en_en_US"
# Load default translation # Load default translation
t = i18n.get_translation() i18n.get_lang(self.mo_dir, 'en_US', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("fr", t._lang) self.assertEqual("fr", l.language)
def test_load_translation_with_accept_language_unknown(self): def test_load_translation_with_accept_language_unknown(self):
# Mock a header # Mock a header
cherrypy.request.headers["Accept-Language"] = "br_CA" cherrypy.request.headers["Accept-Language"] = "br_CA"
# Load default translation # Load default translation
t = i18n.get_translation() i18n.get_lang(self.mo_dir, 'en_US', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("en", t._lang) self.assertEqual("en", l.language)
def test_translation_with_fr(self): def test_translation_with_fr(self):
# Get trans # Get trans
t = i18n._translation("messages", [self.mo_dir], ["fr"]) i18n.get_lang(self.mo_dir, 'fr', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("fr", t._lang) self.assertEqual("fr", l.language)
# Test translation object # Test translation object
self.assertEqual("Modifier", t.gettext("Edit")) self.assertEqual("Modifier", t.gettext("Edit"))
# Check if the translation fallback # Check if the translation fallback
...@@ -77,30 +87,38 @@ class Test(unittest.TestCase): ...@@ -77,30 +87,38 @@ class Test(unittest.TestCase):
def test_translation_with_en(self): def test_translation_with_en(self):
# Get trans # Get trans
t = i18n._translation("messages", [self.mo_dir], ["en"]) i18n.get_lang(self.mo_dir, 'en', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("en", t._lang) self.assertEqual("en", l.language)
pass pass
def test_translation_with_en_us(self): def test_translation_with_en_us(self):
# Get trans # Get trans
t = i18n._translation("messages", [self.mo_dir], ["en_US"]) i18n.get_lang(self.mo_dir, 'en_US', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("en", t._lang) self.assertEqual("en", l.language)
pass pass
def test_translation_with_fr_ca(self): def test_translation_with_fr_ca(self):
# Get trans # Get trans
t = i18n._translation("messages", [self.mo_dir], ["fr_CA"]) i18n.get_lang(self.mo_dir, 'fr_CA', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("fr", t._lang) self.assertEqual("fr", l.language)
pass pass
def test_translation_with_en_fr(self): def test_translation_with_en_fr(self):
# Get trans # Get trans
t = i18n._translation("messages", [self.mo_dir], ["en", "fr"]) i18n.get_lang(self.mo_dir, 'en', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("en", t._lang) self.assertEqual("en", l.language)
# Test translation object # Test translation object
self.assertEqual("Edit", t.gettext("Edit")) self.assertEqual("Edit", t.gettext("Edit"))
# Check if the translation fallback # Check if the translation fallback
...@@ -109,20 +127,15 @@ class Test(unittest.TestCase): ...@@ -109,20 +127,15 @@ class Test(unittest.TestCase):
def test_translation_with_fr_en(self): def test_translation_with_fr_en(self):
# Get trans # Get trans
t = i18n._translation("messages", [self.mo_dir], ["fr", "en"]) i18n.get_lang(self.mo_dir, 'fr', 'messages')
t = cherrypy.response.i18n.trans
l = cherrypy.response.i18n.locale
self.assertIsInstance(t, gettext.GNUTranslations) self.assertIsInstance(t, gettext.GNUTranslations)
self.assertEqual("fr", t._lang) self.assertEqual("fr", l.language)
# Test translation object # Test translation object
self.assertEqual("Modifier", t.gettext("Edit")) self.assertEqual("Modifier", t.gettext("Edit"))
pass pass
def test_translation_with_unknown(self):
# Get trans
t = i18n._translation("messages", [self.mo_dir], ["br"])
self.assertIsInstance(t, gettext.NullTranslations)
self.assertEqual("en_US", t._lang)
pass
class TestI18nWebCase(WebCase): class TestI18nWebCase(WebCase):
...@@ -132,25 +145,25 @@ class TestI18nWebCase(WebCase): ...@@ -132,25 +145,25 @@ class TestI18nWebCase(WebCase):
# Query the page without login-in # Query the page without login-in
self.getPage("/", headers=[("Accept-Language", "es")]) self.getPage("/", headers=[("Accept-Language", "es")])
self.assertStatus('200 OK') self.assertStatus('200 OK')
self.assertHeaderItemValue("Content-Language", "en") self.assertHeaderItemValue("Content-Language", "en_US")
self.assertInBody("Sign in") self.assertInBody("Sign in")
def testLanguage_En(self): def testLanguage_En(self):
self.getPage("/", headers=[("Accept-Language", "en-US,en;q=0.8")]) self.getPage("/", headers=[("Accept-Language", "en-US,en;q=0.8")])
self.assertStatus('200 OK') self.assertStatus('200 OK')
self.assertHeaderItemValue("Content-Language", "en") self.assertHeaderItemValue("Content-Language", "en_US")
self.assertInBody("Sign in") self.assertInBody("Sign in")
def testLanguage_EnFr(self): def testLanguage_EnFr(self):
self.getPage("/", headers=[("Accept-Language", "en-US,en;q=0.8,fr-CA;q=0.8")]) self.getPage("/", headers=[("Accept-Language", "en-US,en;q=0.8,fr-CA;q=0.8")])
self.assertStatus('200 OK') self.assertStatus('200 OK')
self.assertHeaderItemValue("Content-Language", "en") self.assertHeaderItemValue("Content-Language", "en_US")
self.assertInBody("Sign in") self.assertInBody("Sign in")
def testLanguage_Fr(self): def testLanguage_Fr(self):
self.getPage("/", headers=[("Accept-Language", "fr-CA;q=0.8,fr;q=0.6")]) self.getPage("/", headers=[("Accept-Language", "fr-CA;q=0.8,fr;q=0.6")])
self.assertStatus('200 OK') self.assertStatus('200 OK')
self.assertHeaderItemValue("Content-Language", "fr") self.assertHeaderItemValue("Content-Language", "fr_CA")
self.assertInBody("Se connecter") self.assertInBody("Se connecter")
......
...@@ -162,6 +162,7 @@ install_requires = [ ...@@ -162,6 +162,7 @@ install_requires = [
"Jinja2>=2.6,<=2.8.1", "Jinja2>=2.6,<=2.8.1",
"future>=0.15.2", "future>=0.15.2",
"psutil>=2.1.1", "psutil>=2.1.1",
"babel>=0.9.6",
] ]
if PY2: if PY2:
install_requires.extend(["pysqlite>=2.6.3"]) install_requires.extend(["pysqlite>=2.6.3"])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment