[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