[Checkins] SVN: zope.app.i18n/tags/3.6.0/ Tag 3.6.0
Dan Korostelev
nadako at gmail.com
Wed Mar 18 09:39:43 EDT 2009
Log message for revision 98233:
Tag 3.6.0
Changed:
A zope.app.i18n/tags/3.6.0/
D zope.app.i18n/tags/3.6.0/CHANGES.txt
A zope.app.i18n/tags/3.6.0/CHANGES.txt
D zope.app.i18n/tags/3.6.0/README.txt
A zope.app.i18n/tags/3.6.0/README.txt
D zope.app.i18n/tags/3.6.0/buildout.cfg
A zope.app.i18n/tags/3.6.0/buildout.cfg
D zope.app.i18n/tags/3.6.0/setup.py
A zope.app.i18n/tags/3.6.0/setup.py
D zope.app.i18n/tags/3.6.0/src/zope/app/i18n/metadirectives.py
D zope.app.i18n/tags/3.6.0/src/zope/app/i18n/translationdomain.py
A zope.app.i18n/tags/3.6.0/src/zope/app/i18n/translationdomain.py
-=-
Deleted: zope.app.i18n/tags/3.6.0/CHANGES.txt
===================================================================
--- zope.app.i18n/trunk/CHANGES.txt 2009-03-18 11:48:25 UTC (rev 98224)
+++ zope.app.i18n/tags/3.6.0/CHANGES.txt 2009-03-18 13:39:43 UTC (rev 98233)
@@ -1,65 +0,0 @@
-=======
-CHANGES
-=======
-
-3.5.1 (unreleased)
-------------------
-
-- Some of ZCML configuration was moved into another packages:
-
- * The global INegotiator utility registration was moved into ``zope.i18n``.
- * The include of ``zope.i18n.locales`` was also moved into ``zope.i18n``.
- * The registration of IModifiableUserPreferredLanguages adapter was moved
- into ``zope.app.publisher``.
- * The IAttributeAnnotation implementation statement for HTTPRequest was moved
- into ``zope.publisher`` and will only apply if ``zope.annotation`` is
- available.
- * The IUserPreferredCharsets adapter registration was also moved into
- ``zope.publisher``.
-
-3.5.0 (2009-02-01)
-------------------
-
-- Use zope.container instead of zope.app.container.
-
-3.4.6 (2009-01-27)
-------------------
-
-- Fix a simple inconsistent MRO problem in tests
-
-- Substitute zope.app.zapi by direct calls to its wrapped apis. See bug
- 219302.
-
-3.4.5 (unreleased)
-------------------
-
-- This was skipped over by accident.
-
-3.4.4 (2007-10-23)
-------------------
-
-- Fix deprecation warning.
-
-3.4.3 (2007-10-23)
-------------------
-
-- Fix imports in tests.
-
-- Clean up long lines.
-
-3.4.2 (2007-9-26)
------------------
-
-- Release to fix packaging issues with 3.4.1.
-
-3.4.1 (2007-9-25)
------------------
-
-- Added missing Changes.txt and README.txt files to egg
-
-3.4.0 (2007-9-25)
------------------
-
-- Initial documented release
-
-- Move ZopeMessageFactory to zope.i18nmessageid
Copied: zope.app.i18n/tags/3.6.0/CHANGES.txt (from rev 98228, zope.app.i18n/trunk/CHANGES.txt)
===================================================================
--- zope.app.i18n/tags/3.6.0/CHANGES.txt (rev 0)
+++ zope.app.i18n/tags/3.6.0/CHANGES.txt 2009-03-18 13:39:43 UTC (rev 98233)
@@ -0,0 +1,71 @@
+=======
+CHANGES
+=======
+
+3.6.0 (2009-03-18)
+------------------
+
+- Some of ZCML configuration was moved into another packages:
+
+ * The global INegotiator utility registration was moved into ``zope.i18n``.
+ * The include of ``zope.i18n.locales`` was also moved into ``zope.i18n``.
+ * The registration of IModifiableUserPreferredLanguages adapter was moved
+ into ``zope.app.publisher``.
+ * The IAttributeAnnotation implementation statement for HTTPRequest was moved
+ into ``zope.publisher`` and will only apply if ``zope.annotation`` is
+ available.
+ * The IUserPreferredCharsets adapter registration was also moved into
+ ``zope.publisher``.
+
+- Depend on zope.component >= 3.6 instead of zope.app.component as the
+ `queryNextUtility` function was moved there.
+
+- Remove the old ``zope.app.i18n.metadirectives`` module as the directive was
+ moved to ``zope.i18n`` ages ago.
+
+3.5.0 (2009-02-01)
+------------------
+
+- Use zope.container instead of zope.app.container.
+
+3.4.6 (2009-01-27)
+------------------
+
+- Fix a simple inconsistent MRO problem in tests
+
+- Substitute zope.app.zapi by direct calls to its wrapped apis. See bug
+ 219302.
+
+3.4.5 (unreleased)
+------------------
+
+- This was skipped over by accident.
+
+3.4.4 (2007-10-23)
+------------------
+
+- Fix deprecation warning.
+
+3.4.3 (2007-10-23)
+------------------
+
+- Fix imports in tests.
+
+- Clean up long lines.
+
+3.4.2 (2007-9-26)
+-----------------
+
+- Release to fix packaging issues with 3.4.1.
+
+3.4.1 (2007-9-25)
+-----------------
+
+- Added missing Changes.txt and README.txt files to egg
+
+3.4.0 (2007-9-25)
+-----------------
+
+- Initial documented release
+
+- Move ZopeMessageFactory to zope.i18nmessageid
Deleted: zope.app.i18n/tags/3.6.0/README.txt
===================================================================
--- zope.app.i18n/trunk/README.txt 2009-03-18 11:48:25 UTC (rev 98224)
+++ zope.app.i18n/tags/3.6.0/README.txt 2009-03-18 13:39:43 UTC (rev 98233)
@@ -1 +0,0 @@
-Placeful internationalization of content objects.
Copied: zope.app.i18n/tags/3.6.0/README.txt (from rev 98226, zope.app.i18n/trunk/README.txt)
===================================================================
--- zope.app.i18n/tags/3.6.0/README.txt (rev 0)
+++ zope.app.i18n/tags/3.6.0/README.txt 2009-03-18 13:39:43 UTC (rev 98233)
@@ -0,0 +1,2 @@
+This package provides placeful persistent translation domains and
+message catalogs along with ZMI views for managing them.
\ No newline at end of file
Deleted: zope.app.i18n/tags/3.6.0/buildout.cfg
===================================================================
--- zope.app.i18n/trunk/buildout.cfg 2009-03-18 11:48:25 UTC (rev 98224)
+++ zope.app.i18n/tags/3.6.0/buildout.cfg 2009-03-18 13:39:43 UTC (rev 98233)
@@ -1,8 +0,0 @@
-[buildout]
-develop = .
-parts = test
-find-links = http://download.zope.org/distribution/
-
-[test]
-recipe = zc.recipe.testrunner
-eggs = zope.app.i18n [test]
Copied: zope.app.i18n/tags/3.6.0/buildout.cfg (from rev 98226, zope.app.i18n/trunk/buildout.cfg)
===================================================================
--- zope.app.i18n/tags/3.6.0/buildout.cfg (rev 0)
+++ zope.app.i18n/tags/3.6.0/buildout.cfg 2009-03-18 13:39:43 UTC (rev 98233)
@@ -0,0 +1,7 @@
+[buildout]
+develop = .
+parts = test
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = zope.app.i18n [test]
Deleted: zope.app.i18n/tags/3.6.0/setup.py
===================================================================
--- zope.app.i18n/trunk/setup.py 2009-03-18 11:48:25 UTC (rev 98224)
+++ zope.app.i18n/tags/3.6.0/setup.py 2009-03-18 13:39:43 UTC (rev 98233)
@@ -1,67 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Setup for zope.app.i18n package
-
-$Id$
-"""
-
-import os
-
-from setuptools import setup, find_packages
-
-def read(*rnames):
- return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-setup(name='zope.app.i18n',
- version = '3.5.1dev',
- author='Zope Corporation and Contributors',
- author_email='zope-dev at zope.org',
- description='Zope i18n',
- long_description=(
- read('README.txt')
- + '\n\n' +
- read('CHANGES.txt')
- ),
- keywords = "zope3 i18n message factory",
- classifiers = [
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Web Environment',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: Zope Public License',
- 'Programming Language :: Python',
- 'Natural Language :: English',
- 'Operating System :: OS Independent',
- 'Topic :: Internet :: WWW/HTTP',
- 'Framework :: Zope3'],
- url='http://pypi.python.org/pypi/zope.app.i18n',
- license='ZPL 2.1',
- packages=find_packages('src'),
- package_dir = {'': 'src'},
- namespace_packages=['zope', 'zope.app'],
- extras_require = dict(test=['zope.app.testing']),
- install_requires=['setuptools',
- 'zope.app.component',
- 'zope.app.publisher',
- 'zope.component',
- 'zope.container',
- 'zope.configuration',
- 'zope.i18n',
- 'zope.i18nmessageid',
- 'zope.interface',
- 'zope.security',
- 'ZODB3',
- ],
- include_package_data = True,
- zip_safe = False,
- )
Copied: zope.app.i18n/tags/3.6.0/setup.py (from rev 98227, zope.app.i18n/trunk/setup.py)
===================================================================
--- zope.app.i18n/tags/3.6.0/setup.py (rev 0)
+++ zope.app.i18n/tags/3.6.0/setup.py 2009-03-18 13:39:43 UTC (rev 98233)
@@ -0,0 +1,66 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup for zope.app.i18n package
+
+$Id$
+"""
+
+import os
+
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(name='zope.app.i18n',
+ version = '3.6.0',
+ author='Zope Corporation and Contributors',
+ author_email='zope-dev at zope.org',
+ description='Persistent translation domains and message catalogs',
+ long_description=(
+ read('README.txt')
+ + '\n\n' +
+ read('CHANGES.txt')
+ ),
+ keywords = "zope3 i18n message factory",
+ classifiers = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Framework :: Zope3'],
+ url='http://pypi.python.org/pypi/zope.app.i18n',
+ license='ZPL 2.1',
+ packages=find_packages('src'),
+ package_dir = {'': 'src'},
+ namespace_packages=['zope', 'zope.app'],
+ extras_require = dict(test=['zope.app.testing']),
+ install_requires=['setuptools',
+ 'zope.app.publisher',
+ 'zope.component>=3.6',
+ 'zope.container',
+ 'zope.configuration',
+ 'zope.i18n',
+ 'zope.i18nmessageid',
+ 'zope.interface',
+ 'zope.security',
+ 'ZODB3',
+ ],
+ include_package_data = True,
+ zip_safe = False,
+ )
Deleted: zope.app.i18n/tags/3.6.0/src/zope/app/i18n/metadirectives.py
===================================================================
--- zope.app.i18n/trunk/src/zope/app/i18n/metadirectives.py 2009-03-18 11:48:25 UTC (rev 98224)
+++ zope.app.i18n/tags/3.6.0/src/zope/app/i18n/metadirectives.py 2009-03-18 13:39:43 UTC (rev 98233)
@@ -1,29 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""``i18n`` ZCML namespace directive interfaces
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-from zope.interface import Interface
-from zope.configuration.fields import Path
-
-class IRegisterTranslationsDirective(Interface):
- """Register translations with the global site manager."""
-
- directory = Path(
- title=u"Directory",
- description=u"Directory containing the translations",
- required=True
- )
Deleted: zope.app.i18n/tags/3.6.0/src/zope/app/i18n/translationdomain.py
===================================================================
--- zope.app.i18n/trunk/src/zope/app/i18n/translationdomain.py 2009-03-18 11:48:25 UTC (rev 98224)
+++ zope.app.i18n/tags/3.6.0/src/zope/app/i18n/translationdomain.py 2009-03-18 13:39:43 UTC (rev 98233)
@@ -1,279 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""This is the standard, placeful Translation Domain for TTW development.
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import re
-from BTrees.OOBTree import OOBTree
-
-import zope.component
-from zope.interface import implements
-from zope.i18n import interpolate
-from zope.i18n.negotiator import negotiator
-from zope.i18n.interfaces import INegotiator, ITranslationDomain
-from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
-
-from zope.container.btree import BTreeContainer
-from zope.container.contained import Contained
-from zope.app.i18n.interfaces import ILocalTranslationDomain
-from zope.app.component import queryNextUtility
-
-
-class TranslationDomain(BTreeContainer, SimpleTranslationDomain, Contained):
- implements(ILocalTranslationDomain)
-
- def __init__(self):
- super(TranslationDomain, self).__init__()
- self._catalogs = OOBTree()
- self.domain = '<domain not activated>'
-
- def _registerMessageCatalog(self, language, catalog_name):
- if language not in self._catalogs.keys():
- self._catalogs[language] = []
-
- mc = self._catalogs[language]
- mc.append(catalog_name)
-
- def _unregisterMessageCatalog(self, language, catalog_name):
- self._catalogs[language].remove(catalog_name)
-
- def __setitem__(self, name, object):
- 'See IWriteContainer'
- super(TranslationDomain, self).__setitem__(name, object)
- self._registerMessageCatalog(object.language, name)
-
- def __delitem__(self, name):
- 'See IWriteContainer'
- object = self[name]
- super(TranslationDomain, self).__delitem__(name)
- self._unregisterMessageCatalog(object.language, name)
-
- def translate(self, msgid, mapping=None, context=None,
- target_language=None, default=None):
- """See interface `ITranslationDomain`"""
- if target_language is None and context is not None:
- avail_langs = self.getAvailableLanguages()
- # Let's negotiate the language to translate to. :)
- negotiator = zope.component.getUtility(INegotiator, context=self)
- target_language = negotiator.getLanguage(avail_langs, context)
-
- # Get the translation. Default is the source text itself.
- catalog_names = self._catalogs.get(target_language, [])
-
- for name in catalog_names:
- catalog = super(TranslationDomain, self).__getitem__(name)
- text = catalog.queryMessage(msgid)
- if text is not None:
- break
- else:
- # If nothing found, delegate to a translation server higher up the
- # tree.
- domain = queryNextUtility(self, ITranslationDomain, self.domain)
- if domain is not None:
- return domain.translate(msgid, mapping, context,
- target_language, default=default)
- if default is None:
- default = unicode(msgid)
- text = default
-
- # Now we need to do the interpolation
- return interpolate(text, mapping)
-
-
- def getMessageIds(self, filter='%'):
- 'See `IWriteTranslationDomain`'
- filter = filter.replace('%', '.*')
- filter_re = re.compile(filter)
-
- msgids = {}
- for language in self.getAvailableLanguages():
- for name in self._catalogs[language]:
- for msgid in self[name].getMessageIds():
- if filter_re.match(msgid) >= 0:
- msgids[msgid] = None
- return msgids.keys()
-
- def getMessages(self):
- 'See `IWriteTranslationDomain`'
- messages = []
- languages = self.getAvailableLanguages()
- for language in languages:
- for name in self._catalogs[language]:
- messages += self[name].getMessages()
- return messages
-
-
- def getMessage(self, msgid, language):
- 'See `IWriteTranslationDomain`'
- for name in self._catalogs.get(language, []):
- try:
- return self[name].getFullMessage(msgid)
- except:
- pass
- return None
-
- def getAllLanguages(self):
- 'See `IWriteTranslationDomain`'
- languages = {}
- for key in self._catalogs.keys():
- languages[key] = None
- return languages.keys()
-
-
- def getAvailableLanguages(self):
- 'See `IWriteTranslationDomain`'
- return list(self._catalogs.keys())
-
-
- def addMessage(self, msgid, msg, language, mod_time=None):
- 'See `IWriteTranslationDomain`'
- if not self._catalogs.has_key(language):
- if language not in self.getAllLanguages():
- self.addLanguage(language)
-
- catalog_name = self._catalogs[language][0]
- catalog = self[catalog_name]
- catalog.setMessage(msgid, msg, mod_time)
-
-
- def updateMessage(self, msgid, msg, language, mod_time=None):
- 'See `IWriteTranslationDomain`'
- catalog_name = self._catalogs[language][0]
- catalog = self[catalog_name]
- catalog.setMessage(msgid, msg, mod_time)
-
-
- def deleteMessage(self, msgid, language):
- 'See `IWriteTranslationDomain`'
- catalog_name = self._catalogs[language][0]
- catalog = self[catalog_name]
- catalog.deleteMessage(msgid)
-
-
- def addLanguage(self, language):
- 'See `IWriteTranslationDomain`'
- catalog = zope.component.createObject(u'zope.app.MessageCatalog',
- language)
- catalog.domain = self.domain
- self[language] = catalog
-
-
- def deleteLanguage(self, language):
- 'See `IWriteTranslationDomain`'
- # Delete all catalogs from the data storage
- for name in self._catalogs[language]:
- if self.has_key(name):
- del self[name]
- # Now delete the specifc catalog registry for this language
- del self._catalogs[language]
-
-
- def getMessagesMapping(self, languages, foreign_messages):
- 'See `ISyncTranslationDomain`'
- mapping = {}
- # Get all relevant local messages
- local_messages = []
- for language in languages:
- for name in self._catalogs.get(language, []):
- local_messages += self[name].getMessages()
-
-
- for fmsg in foreign_messages:
- ident = (fmsg['msgid'], fmsg['language'])
- mapping[ident] = (fmsg, self.getMessage(*ident))
-
- for lmsg in local_messages:
- ident = (lmsg['msgid'], lmsg['language'])
- if ident not in mapping.keys():
- mapping[ident] = (None, lmsg)
-
- return mapping
-
-
- def synchronize(self, messages_mapping):
- 'See `ISyncTranslationDomain`'
-
- for value in messages_mapping.values():
- fmsg = value[0]
- lmsg = value[1]
- if fmsg is None:
- self.deleteMessage(lmsg['msgid'], lmsg['language'])
- elif lmsg is None:
- self.addMessage(fmsg['msgid'],
- fmsg['msgstr'], fmsg['language'],
- fmsg['mod_time'])
- elif fmsg['mod_time'] > lmsg['mod_time']:
- self.updateMessage(fmsg['msgid'],
- fmsg['msgstr'], fmsg['language'],
- fmsg['mod_time'])
-
-
-def setDomainOnActivation(domain, event):
- """Set the permission id upon registration activation.
-
- Let's see how this notifier can be used. First we need to create an event
- using the permission instance and a registration stub:
-
- >>> class Registration:
- ... def __init__(self, obj, name):
- ... self.component = obj
- ... self.name = name
-
- >>> domain1 = TranslationDomain()
- >>> domain1.domain
- '<domain not activated>'
-
- >>> import zope.component.interfaces
- >>> event = zope.component.interfaces.Registered(
- ... Registration(domain1, 'domain1'))
-
- Now we pass the event into this function, and the id of the domain should
- be set to 'domain1'.
-
- >>> setDomainOnActivation(domain1, event)
- >>> domain1.domain
- 'domain1'
- """
- domain.domain = event.object.name
-
-
-def unsetDomainOnDeactivation(domain, event):
- """Unset the permission id up registration deactivation.
-
- Let's see how this notifier can be used. First we need to create an event
- using the permission instance and a registration stub:
-
- >>> class Registration:
- ... def __init__(self, obj, name):
- ... self.component = obj
- ... self.name = name
-
- >>> domain1 = TranslationDomain()
- >>> domain1.domain = 'domain1'
-
- >>> import zope.component.interfaces
- >>> event = zope.component.interfaces.Unregistered(
- ... Registration(domain1, 'domain1'))
-
- Now we pass the event into this function, and the id of the role should be
- set to '<domain not activated>'.
-
- >>> unsetDomainOnDeactivation(domain1, event)
- >>> domain1.domain
- '<domain not activated>'
- """
- domain.domain = '<domain not activated>'
Copied: zope.app.i18n/tags/3.6.0/src/zope/app/i18n/translationdomain.py (from rev 98227, zope.app.i18n/trunk/src/zope/app/i18n/translationdomain.py)
===================================================================
--- zope.app.i18n/tags/3.6.0/src/zope/app/i18n/translationdomain.py (rev 0)
+++ zope.app.i18n/tags/3.6.0/src/zope/app/i18n/translationdomain.py 2009-03-18 13:39:43 UTC (rev 98233)
@@ -0,0 +1,279 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""This is the standard, placeful Translation Domain for TTW development.
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import re
+from BTrees.OOBTree import OOBTree
+
+import zope.component
+from zope.interface import implements
+from zope.i18n import interpolate
+from zope.i18n.negotiator import negotiator
+from zope.i18n.interfaces import INegotiator, ITranslationDomain
+from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
+
+from zope.container.btree import BTreeContainer
+from zope.container.contained import Contained
+from zope.app.i18n.interfaces import ILocalTranslationDomain
+
+
+class TranslationDomain(BTreeContainer, SimpleTranslationDomain, Contained):
+ implements(ILocalTranslationDomain)
+
+ def __init__(self):
+ super(TranslationDomain, self).__init__()
+ self._catalogs = OOBTree()
+ self.domain = '<domain not activated>'
+
+ def _registerMessageCatalog(self, language, catalog_name):
+ if language not in self._catalogs.keys():
+ self._catalogs[language] = []
+
+ mc = self._catalogs[language]
+ mc.append(catalog_name)
+
+ def _unregisterMessageCatalog(self, language, catalog_name):
+ self._catalogs[language].remove(catalog_name)
+
+ def __setitem__(self, name, object):
+ 'See IWriteContainer'
+ super(TranslationDomain, self).__setitem__(name, object)
+ self._registerMessageCatalog(object.language, name)
+
+ def __delitem__(self, name):
+ 'See IWriteContainer'
+ object = self[name]
+ super(TranslationDomain, self).__delitem__(name)
+ self._unregisterMessageCatalog(object.language, name)
+
+ def translate(self, msgid, mapping=None, context=None,
+ target_language=None, default=None):
+ """See interface `ITranslationDomain`"""
+ if target_language is None and context is not None:
+ avail_langs = self.getAvailableLanguages()
+ # Let's negotiate the language to translate to. :)
+ negotiator = zope.component.getUtility(INegotiator, context=self)
+ target_language = negotiator.getLanguage(avail_langs, context)
+
+ # Get the translation. Default is the source text itself.
+ catalog_names = self._catalogs.get(target_language, [])
+
+ for name in catalog_names:
+ catalog = super(TranslationDomain, self).__getitem__(name)
+ text = catalog.queryMessage(msgid)
+ if text is not None:
+ break
+ else:
+ # If nothing found, delegate to a translation server higher up the
+ # tree.
+ domain = zope.component.queryNextUtility(self, ITranslationDomain,
+ self.domain)
+ if domain is not None:
+ return domain.translate(msgid, mapping, context,
+ target_language, default=default)
+ if default is None:
+ default = unicode(msgid)
+ text = default
+
+ # Now we need to do the interpolation
+ return interpolate(text, mapping)
+
+
+ def getMessageIds(self, filter='%'):
+ 'See `IWriteTranslationDomain`'
+ filter = filter.replace('%', '.*')
+ filter_re = re.compile(filter)
+
+ msgids = {}
+ for language in self.getAvailableLanguages():
+ for name in self._catalogs[language]:
+ for msgid in self[name].getMessageIds():
+ if filter_re.match(msgid) >= 0:
+ msgids[msgid] = None
+ return msgids.keys()
+
+ def getMessages(self):
+ 'See `IWriteTranslationDomain`'
+ messages = []
+ languages = self.getAvailableLanguages()
+ for language in languages:
+ for name in self._catalogs[language]:
+ messages += self[name].getMessages()
+ return messages
+
+
+ def getMessage(self, msgid, language):
+ 'See `IWriteTranslationDomain`'
+ for name in self._catalogs.get(language, []):
+ try:
+ return self[name].getFullMessage(msgid)
+ except:
+ pass
+ return None
+
+ def getAllLanguages(self):
+ 'See `IWriteTranslationDomain`'
+ languages = {}
+ for key in self._catalogs.keys():
+ languages[key] = None
+ return languages.keys()
+
+
+ def getAvailableLanguages(self):
+ 'See `IWriteTranslationDomain`'
+ return list(self._catalogs.keys())
+
+
+ def addMessage(self, msgid, msg, language, mod_time=None):
+ 'See `IWriteTranslationDomain`'
+ if not self._catalogs.has_key(language):
+ if language not in self.getAllLanguages():
+ self.addLanguage(language)
+
+ catalog_name = self._catalogs[language][0]
+ catalog = self[catalog_name]
+ catalog.setMessage(msgid, msg, mod_time)
+
+
+ def updateMessage(self, msgid, msg, language, mod_time=None):
+ 'See `IWriteTranslationDomain`'
+ catalog_name = self._catalogs[language][0]
+ catalog = self[catalog_name]
+ catalog.setMessage(msgid, msg, mod_time)
+
+
+ def deleteMessage(self, msgid, language):
+ 'See `IWriteTranslationDomain`'
+ catalog_name = self._catalogs[language][0]
+ catalog = self[catalog_name]
+ catalog.deleteMessage(msgid)
+
+
+ def addLanguage(self, language):
+ 'See `IWriteTranslationDomain`'
+ catalog = zope.component.createObject(u'zope.app.MessageCatalog',
+ language)
+ catalog.domain = self.domain
+ self[language] = catalog
+
+
+ def deleteLanguage(self, language):
+ 'See `IWriteTranslationDomain`'
+ # Delete all catalogs from the data storage
+ for name in self._catalogs[language]:
+ if self.has_key(name):
+ del self[name]
+ # Now delete the specifc catalog registry for this language
+ del self._catalogs[language]
+
+
+ def getMessagesMapping(self, languages, foreign_messages):
+ 'See `ISyncTranslationDomain`'
+ mapping = {}
+ # Get all relevant local messages
+ local_messages = []
+ for language in languages:
+ for name in self._catalogs.get(language, []):
+ local_messages += self[name].getMessages()
+
+
+ for fmsg in foreign_messages:
+ ident = (fmsg['msgid'], fmsg['language'])
+ mapping[ident] = (fmsg, self.getMessage(*ident))
+
+ for lmsg in local_messages:
+ ident = (lmsg['msgid'], lmsg['language'])
+ if ident not in mapping.keys():
+ mapping[ident] = (None, lmsg)
+
+ return mapping
+
+
+ def synchronize(self, messages_mapping):
+ 'See `ISyncTranslationDomain`'
+
+ for value in messages_mapping.values():
+ fmsg = value[0]
+ lmsg = value[1]
+ if fmsg is None:
+ self.deleteMessage(lmsg['msgid'], lmsg['language'])
+ elif lmsg is None:
+ self.addMessage(fmsg['msgid'],
+ fmsg['msgstr'], fmsg['language'],
+ fmsg['mod_time'])
+ elif fmsg['mod_time'] > lmsg['mod_time']:
+ self.updateMessage(fmsg['msgid'],
+ fmsg['msgstr'], fmsg['language'],
+ fmsg['mod_time'])
+
+
+def setDomainOnActivation(domain, event):
+ """Set the permission id upon registration activation.
+
+ Let's see how this notifier can be used. First we need to create an event
+ using the permission instance and a registration stub:
+
+ >>> class Registration:
+ ... def __init__(self, obj, name):
+ ... self.component = obj
+ ... self.name = name
+
+ >>> domain1 = TranslationDomain()
+ >>> domain1.domain
+ '<domain not activated>'
+
+ >>> import zope.component.interfaces
+ >>> event = zope.component.interfaces.Registered(
+ ... Registration(domain1, 'domain1'))
+
+ Now we pass the event into this function, and the id of the domain should
+ be set to 'domain1'.
+
+ >>> setDomainOnActivation(domain1, event)
+ >>> domain1.domain
+ 'domain1'
+ """
+ domain.domain = event.object.name
+
+
+def unsetDomainOnDeactivation(domain, event):
+ """Unset the permission id up registration deactivation.
+
+ Let's see how this notifier can be used. First we need to create an event
+ using the permission instance and a registration stub:
+
+ >>> class Registration:
+ ... def __init__(self, obj, name):
+ ... self.component = obj
+ ... self.name = name
+
+ >>> domain1 = TranslationDomain()
+ >>> domain1.domain = 'domain1'
+
+ >>> import zope.component.interfaces
+ >>> event = zope.component.interfaces.Unregistered(
+ ... Registration(domain1, 'domain1'))
+
+ Now we pass the event into this function, and the id of the role should be
+ set to '<domain not activated>'.
+
+ >>> unsetDomainOnDeactivation(domain1, event)
+ >>> domain1.domain
+ '<domain not activated>'
+ """
+ domain.domain = '<domain not activated>'
More information about the Checkins
mailing list