Skip to content

Commit

Permalink
Merge r27091 from trunk: Fix collector issue 260
Browse files Browse the repository at this point in the history
  • Loading branch information
philikon committed Aug 13, 2004
1 parent b788b3c commit e6abdee
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 8 deletions.
11 changes: 3 additions & 8 deletions configure.zcml
Expand Up @@ -49,21 +49,16 @@

<!-- Setup Message Catalogs -->
<content class=".messagecatalog.MessageCatalog">
<factory id="zope.app.MessageCatalog" />
<implements
interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />

<require permission="zope.View"
interface="zope.i18n.interfaces.IMessageCatalog" />

<require permission="zope.ManageServices"
attributes="setMessage getMessageIds" />
<implements
interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
</content>

<factory
component="zope.app.i18n.messagecatalog.MessageCatalog"
id="zope.app.MessageCatalog"
/>


<!-- Setup Export and Import Filters -->
<adapter
Expand Down
237 changes: 237 additions & 0 deletions translationdomain.py
@@ -0,0 +1,237 @@
##############################################################################
#
# 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$
"""
import re
from BTrees.OOBTree import OOBTree
from zope.interface import implements

from zope.app import zapi
from zope.app.container.btree import BTreeContainer
from zope.app.i18n.interfaces import ILocalTranslationDomain
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.app.container.contained import Contained
from zope.app.component.localservice import getNextService
from zope.component.servicenames import Utilities
from zope.app.utility import UtilityRegistration


class TranslationDomain(BTreeContainer, SimpleTranslationDomain, Contained):

implements(ILocalTranslationDomain)

def __init__(self):
super(TranslationDomain, self).__init__()
self._catalogs = OOBTree()
self.domain = None

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 ITranslationService"""
if target_language is None and context is not None:
avail_langs = self.getAvailableLanguages()
# Let's negotiate the language to translate to. :)
negotiator = zapi.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.
utils = getNextService(self, Utilities)
domain = utils.queryUtility(ITranslationDomain, self.domain)
if domain is not None:
return domain.translate(msgid, mapping, context,
target_language, default=default)
else:
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 IWriteTranslationService'
for name in self._catalogs.get(language, []):
try:
return self[name].getFullMessage(msgid)
except:
pass
return None

def getAllLanguages(self):
'See IWriteTranslationService'
languages = {}
for key in self._catalogs.keys():
languages[key] = None
return languages.keys()


def getAvailableLanguages(self):
'See IWriteTranslationService'
return list(self._catalogs.keys())


def addMessage(self, msgid, msg, language, mod_time=None):
'See IWriteTranslationService'
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 IWriteTranslationService'
catalog_name = self._catalogs[language][0]
catalog = self[catalog_name]
catalog.setMessage(msgid, msg, mod_time)


def deleteMessage(self, msgid, language):
'See IWriteTranslationService'
catalog_name = self._catalogs[language][0]
catalog = self[catalog_name]
catalog.deleteMessage(msgid)


def addLanguage(self, language):
'See IWriteTranslationService'
catalog = zapi.createObject(None, u'zope.app.MessageCatalog',
language)
self[language] = catalog


def deleteLanguage(self, language):
'See IWriteTranslationService'
# 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 ISyncTranslationService'
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 ISyncTranslationService'

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'])



class DomainRegistration(UtilityRegistration):
"""Domain Registration
We have a custom registration here, since we want active registrations to
set the domain of the TranslationDomain.
"""
def activated(self):
domain = self.getComponent()
domain.domain = self.name

def deactivated(self):
domain = self.getComponent()
domain.domain = '<domain not activated>'

0 comments on commit e6abdee

Please sign in to comment.