[Checkins] SVN: zope.i18n/trunk/ Feature: Added optional automatic
compilation of mo files from po files. You need to depend on
the `zope.i18n [compile]` extra and set an environment
variable called `zope.i18n.compile_mo_files` to any True
value to enable this option. Bumped the package version to 3.5dev,
as we added features and this is not a maintenance release anymore.
Hanno Schlichting
plone at hannosch.info
Sat Apr 26 06:53:04 EDT 2008
Log message for revision 85758:
Feature: Added optional automatic compilation of mo files from po files. You need to depend on the `zope.i18n [compile]` extra and set an environment variable called `zope.i18n.compile_mo_files` to any True value to enable this option. Bumped the package version to 3.5dev, as we added features and this is not a maintenance release anymore.
Changed:
U zope.i18n/trunk/CHANGES.txt
U zope.i18n/trunk/buildout.cfg
U zope.i18n/trunk/setup.py
A zope.i18n/trunk/src/zope/i18n/compile.py
U zope.i18n/trunk/src/zope/i18n/tests/locale2/en/LC_MESSAGES/zope-i18n.mo
A zope.i18n/trunk/src/zope/i18n/tests/locale3/
D zope.i18n/trunk/src/zope/i18n/tests/locale3/__init__.py
D zope.i18n/trunk/src/zope/i18n/tests/locale3/en/
A zope.i18n/trunk/src/zope/i18n/tests/locale3/en/
_U zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/
A zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.in
U zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo
U zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.po
A zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.po
U zope.i18n/trunk/src/zope/i18n/tests/test_zcml.py
U zope.i18n/trunk/src/zope/i18n/zcml.py
-=-
Modified: zope.i18n/trunk/CHANGES.txt
===================================================================
--- zope.i18n/trunk/CHANGES.txt 2008-04-26 10:36:13 UTC (rev 85757)
+++ zope.i18n/trunk/CHANGES.txt 2008-04-26 10:52:59 UTC (rev 85758)
@@ -2,9 +2,14 @@
CHANGES
=======
-3.4.1 (unreleased)
+3.5 (unreleased)
------------------
+- Feature: Added optional automatic compilation of mo files from po files.
+ You need to depend on the `zope.i18n [compile]` extra and set an environment
+ variable called `zope.i18n.compile_mo_files` to any True value to enable
+ this option.
+
- Feature: Re-use existing translation domains when registering new ones.
This allows multiple packages to register translations in the same domain.
If the same message exists in multiple catalogs the one registered first
Modified: zope.i18n/trunk/buildout.cfg
===================================================================
--- zope.i18n/trunk/buildout.cfg 2008-04-26 10:36:13 UTC (rev 85757)
+++ zope.i18n/trunk/buildout.cfg 2008-04-26 10:52:59 UTC (rev 85758)
@@ -1,8 +1,15 @@
[buildout]
develop = .
-parts = test
+parts = test test-compile
find-links = http://download.zope.org/distribution/
[test]
recipe = zc.recipe.testrunner
-eggs = zope.i18n
+eggs =
+ zope.i18n
+
+[test-compile]
+recipe = zc.recipe.testrunner
+eggs =
+ zope.i18n
+ python-gettext
Modified: zope.i18n/trunk/setup.py
===================================================================
--- zope.i18n/trunk/setup.py 2008-04-26 10:36:13 UTC (rev 85757)
+++ zope.i18n/trunk/setup.py 2008-04-26 10:52:59 UTC (rev 85758)
@@ -24,7 +24,7 @@
setup(
name='zope.i18n',
- version = '3.4.1dev',
+ version = '3.5dev',
author='Zope Corporation and Contributors',
author_email='zope3-dev at zope.org',
description='Zope3 Internationalization Support',
@@ -58,4 +58,7 @@
],
include_package_data = True,
zip_safe = False,
+ extras_require = dict(
+ compile = ['pythongettext'],
+ ),
)
Added: zope.i18n/trunk/src/zope/i18n/compile.py
===================================================================
--- zope.i18n/trunk/src/zope/i18n/compile.py (rev 0)
+++ zope.i18n/trunk/src/zope/i18n/compile.py 2008-04-26 10:52:59 UTC (rev 85758)
@@ -0,0 +1,46 @@
+import logging
+import os
+from os.path import join
+from stat import ST_MTIME
+
+HAS_PYTHON_GETTEXT = True
+try:
+ from pythongettext.msgfmt import Msgfmt
+ from pythongettext.msgfmt import PoSyntaxError
+except ImportError:
+ HAS_PYTHON_GETTEXT = False
+
+logger = logging.getLogger('zope.i18n')
+
+
+def compile_mo_file(domain, lc_messages_path):
+ """Creates or updates a mo file in the locales folder."""
+ if not HAS_PYTHON_GETTEXT:
+ return
+
+ base = join(lc_messages_path, domain)
+ pofile = str(base + '.po')
+ mofile = str(base + '.mo')
+
+ po_mtime = 0
+ try:
+ po_mtime = os.stat(pofile)[ST_MTIME]
+ except (IOError, OSError):
+ return
+
+ mo_mtime = 0
+ if os.path.exists(mofile):
+ # Update mo file?
+ try:
+ mo_mtime = os.stat(mofile)[ST_MTIME]
+ except (IOError, OSError):
+ return
+
+ if po_mtime > mo_mtime:
+ try:
+ mo = Msgfmt(pofile, domain).getAsFile()
+ fd = open(mofile, 'wb')
+ fd.write(mo.read())
+ fd.close()
+ except (IOError, OSError, PoSyntaxError):
+ logger.warn('Error while compiling %s' % pofile)
Property changes on: zope.i18n/trunk/src/zope/i18n/compile.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zope.i18n/trunk/src/zope/i18n/tests/locale2/en/LC_MESSAGES/zope-i18n.mo
===================================================================
(Binary files differ)
Copied: zope.i18n/trunk/src/zope/i18n/tests/locale3 (from rev 85741, zope.i18n/trunk/src/zope/i18n/tests/locale)
Deleted: zope.i18n/trunk/src/zope/i18n/tests/locale3/__init__.py
===================================================================
--- zope.i18n/trunk/src/zope/i18n/tests/locale/__init__.py 2008-04-26 07:46:02 UTC (rev 85741)
+++ zope.i18n/trunk/src/zope/i18n/tests/locale3/__init__.py 2008-04-26 10:52:59 UTC (rev 85758)
@@ -1,2 +0,0 @@
-#
-# This file is necessary to make this directory a package.
Copied: zope.i18n/trunk/src/zope/i18n/tests/locale3/en (from rev 85757, zope.i18n/trunk/src/zope/i18n/tests/locale/en)
Property changes on: zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES
___________________________________________________________________
Name: svn:ignore
+ zope-i18n2.mo
Added: zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.in
===================================================================
(Binary files differ)
Property changes on: zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.in
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo
===================================================================
(Binary files differ)
Modified: zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.po
===================================================================
--- zope.i18n/trunk/src/zope/i18n/tests/locale/en/LC_MESSAGES/zope-i18n.po 2008-04-26 10:36:13 UTC (rev 85757)
+++ zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.po 2008-04-26 10:52:59 UTC (rev 85758)
@@ -1,14 +1,11 @@
msgid ""
msgstr ""
"Project-Id-Version: Zope 3\n"
-"PO-Revision-Date: 2002/06/13\n"
+"PO-Revision-Date: 2008/04/26\n"
"Last-Translator: Zope 3 contributors\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
-msgid "New Domain"
-msgstr "New Domain translated"
-
-msgid "New Language"
-msgstr "New Language translated"
+msgid "I'm a newer file"
+msgstr "I'm a newer file translated"
Added: zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.po
===================================================================
--- zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.po (rev 0)
+++ zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.po 2008-04-26 10:52:59 UTC (rev 85758)
@@ -0,0 +1,11 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Zope 3\n"
+"PO-Revision-Date: 2008/04/26\n"
+"Last-Translator: Zope 3 contributors\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "I'm a new file"
+msgstr "I'm a new file translated"
Property changes on: zope.i18n/trunk/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.po
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zope.i18n/trunk/src/zope/i18n/tests/test_zcml.py
===================================================================
--- zope.i18n/trunk/src/zope/i18n/tests/test_zcml.py 2008-04-26 10:36:13 UTC (rev 85757)
+++ zope.i18n/trunk/src/zope/i18n/tests/test_zcml.py 2008-04-26 10:52:59 UTC (rev 85758)
@@ -16,13 +16,18 @@
$Id$
"""
import os
+import shutil
import unittest
-import zope.component
-import zope.i18n.tests
+from zope.component import getUtility
+from zope.component import queryUtility
from zope.component.testing import PlacelessSetup
from zope.configuration import xmlconfig
+
+import zope.i18n.tests
from zope.i18n.interfaces import ITranslationDomain
+from zope.i18n.compile import HAS_PYTHON_GETTEXT
+from zope.i18n import zcml
template = """\
<configure
@@ -38,7 +43,7 @@
self.context = xmlconfig.file('meta.zcml', zope.i18n)
def testRegisterTranslations(self):
- self.assert_(zope.component.queryUtility(ITranslationDomain) is None)
+ self.assert_(queryUtility(ITranslationDomain) is None)
xmlconfig.string(
template % '''
<configure package="zope.i18n.tests">
@@ -47,12 +52,12 @@
''', self.context)
path = os.path.join(os.path.dirname(zope.i18n.tests.__file__),
'locale', 'en', 'LC_MESSAGES', 'zope-i18n.mo')
- util = zope.component.getUtility(ITranslationDomain, 'zope-i18n')
+ util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEquals(util._catalogs,
{'test': ['test'], 'en': [unicode(path)]})
def testRegisterDistributedTranslations(self):
- self.assert_(zope.component.queryUtility(ITranslationDomain) is None)
+ self.assert_(queryUtility(ITranslationDomain) is None)
xmlconfig.string(
template % '''
<configure package="zope.i18n.tests">
@@ -69,7 +74,7 @@
'locale', 'en', 'LC_MESSAGES', 'zope-i18n.mo')
path2 = os.path.join(os.path.dirname(zope.i18n.tests.__file__),
'locale2', 'en', 'LC_MESSAGES', 'zope-i18n.mo')
- util = zope.component.getUtility(ITranslationDomain, 'zope-i18n')
+ util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEquals(util._catalogs,
{'test': ['test', 'test'],
'en': [unicode(path1), unicode(path2)]})
@@ -83,7 +88,37 @@
msg = util.translate(u'New Language', target_language='en')
self.assertEquals(msg, u'New Language translated')
+ if HAS_PYTHON_GETTEXT:
+ def testRegisterAndCompileTranslations(self):
+ zcml.COMPILE_MO_FILES = True
+ self.assert_(queryUtility(ITranslationDomain) is None)
+ # Copy an old and outdated file over, so we can test if the
+ # newer file check works
+ testpath = os.path.join(os.path.dirname(zope.i18n.tests.__file__))
+ basepath = os.path.join(testpath, 'locale3', 'en', 'LC_MESSAGES')
+ in_ = os.path.join(basepath, 'zope-i18n.in')
+ path = os.path.join(basepath, 'zope-i18n.mo')
+ shutil.copy2(in_, path)
+
+ xmlconfig.string(
+ template % '''
+ <configure package="zope.i18n.tests">
+ <i18n:registerTranslations directory="locale3" />
+ </configure>
+ ''', self.context)
+ util = getUtility(ITranslationDomain, 'zope-i18n')
+ self.assertEquals(util._catalogs,
+ {'test': ['test'], 'en': [unicode(path)]})
+
+ msg = util.translate(u"I'm a newer file", target_language='en')
+ self.assertEquals(msg, u"I'm a newer file translated")
+
+ util = getUtility(ITranslationDomain, 'zope-i18n2')
+ msg = util.translate(u"I'm a new file", target_language='en')
+ self.assertEquals(msg, u"I'm a new file translated")
+
+
def test_suite():
return unittest.makeSuite(DirectivesTest)
Modified: zope.i18n/trunk/src/zope/i18n/zcml.py
===================================================================
--- zope.i18n/trunk/src/zope/i18n/zcml.py 2008-04-26 10:36:13 UTC (rev 85757)
+++ zope.i18n/trunk/src/zope/i18n/zcml.py 2008-04-26 10:52:59 UTC (rev 85758)
@@ -1,4 +1,5 @@
-##############################################################################
+
+# ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
@@ -21,6 +22,7 @@
from zope.interface import Interface
from zope.configuration.fields import Path
+from zope.i18n.compile import compile_mo_file
from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
from zope.i18n.testmessagecatalog import TestMessageCatalog
from zope.i18n.translationdomain import TranslationDomain
@@ -28,6 +30,10 @@
from zope.component import queryUtility
from zope.component.zcml import utility
+COMPILE_MO_FILES_KEY = 'zope.i18n.compile_mo_files'
+COMPILE_MO_FILES = os.environ.get(COMPILE_MO_FILES_KEY, False)
+
+
class IRegisterTranslationsDirective(Interface):
"""Register translations with the global site manager."""
@@ -47,6 +53,12 @@
for language in os.listdir(path):
lc_messages_path = os.path.join(path, language, 'LC_MESSAGES')
if os.path.isdir(lc_messages_path):
+ # Preprocess files and update or compile the mo files
+ if COMPILE_MO_FILES:
+ for domain_file in os.listdir(lc_messages_path):
+ if domain_file.endswith('.po'):
+ domain = domain_file[:-3]
+ compile_mo_file(domain, lc_messages_path)
for domain_file in os.listdir(lc_messages_path):
if domain_file.endswith('.mo'):
domain_path = os.path.join(lc_messages_path, domain_file)
More information about the Checkins
mailing list