opental-checkins
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[OpenTAL-checkins] CVSROOT: /cvsroot/opental


From: Sidnei da Silva
Subject: [OpenTAL-checkins] CVSROOT: /cvsroot/opental
Date: Sun, 14 Sep 2003 20:07:42 -0400

Module name:    opental
Branch:         no_more_readconflict
Changes by:     Sidnei da Silva <address@hidden>        03/09/14 20:07:41
Reply-to: address@hidden

CVSROOT:        /cvsroot/opental
Module name:    opental
Branch:         no_more_readconflict
Changes by:     Sidnei da Silva <address@hidden>        03/09/14 20:07:41

Modified files:
        PlacelessTranslationService: GettextMessageCatalog.py 
                                     PlacelessTranslationService.py 
                                     __init__.py 

Log message:
        A try at getting rid of ReadConflictErrors and other __setstate__ 
oddities

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/PlacelessTranslationService/GettextMessageCatalog.py.diff?only_with_tag=no_more_readconflict&tr1=1.14&tr2=1.14.2.1&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/PlacelessTranslationService/PlacelessTranslationService.py.diff?only_with_tag=no_more_readconflict&tr1=1.26&tr2=1.26.2.1&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/PlacelessTranslationService/__init__.py.diff?only_with_tag=no_more_readconflict&tr1=1.14&tr2=1.14.2.1&r1=text&r2=text

Patches:
Index: opental/PlacelessTranslationService/GettextMessageCatalog.py
diff -u /dev/null 
opental/PlacelessTranslationService/GettextMessageCatalog.py:1.14.2.1
--- /dev/null   Sun Sep 14 20:07:41 2003
+++ opental/PlacelessTranslationService/GettextMessageCatalog.py        Sun Sep 
14 20:07:41 2003
@@ -0,0 +1,235 @@
+##############################################################################
+#    Copyright (C) 2001, 2002, 2003 Lalo Martins <address@hidden>,
+#                  Zope Corporation and Contributors
+
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+"""A simple implementation of a Message Catalog.
+
+$Id: GettextMessageCatalog.py,v 1.14.2.1 2003/09/15 00:07:41 dreamcatcher Exp $
+"""
+
+from gettext import GNUTranslations
+import os, types, codecs
+from types import DictType, StringType, UnicodeType
+from OFS.Traversable import Traversable
+from Persistence import Persistent
+from Acquisition import Implicit
+from App.Management import Tabs
+from PlacelessTranslationService import log, Registry
+try:
+    True
+except NameError:
+    True=1
+    False=0
+
+try:
+    from Products.OpenPT.OpenPTFile import OpenPTFile as ptFile
+except ImportError:
+    from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+    from Globals import package_home
+    def ptFile(id, *filename):
+        if type(filename[0]) is types.DictType:
+            filename = list(filename)
+            filename[0] = package_home(filename[0])
+        filename = os.path.join(*filename)
+        if not os.path.splitext(filename)[1]:
+            filename = filename + '.pt'
+        return PageTemplateFile(filename, '', __name__=id)
+
+# template to use to write missing entries to .missing
+missing_template = u"""msgid "%(id)s"
+msgstr ""
+"""
+
+orig_text_template = u"""
+#. %(text)s
+"""
+
+orig_text_line_joiner = u"\n#. "
+
+permission = 'View management screens'
+
+translationRegistry = Registry()
+registerTranslation = translationRegistry.register
+
+class GettextMessageCatalog(Persistent, Implicit, Traversable, Tabs):
+    """
+    Message catalog that wraps a .mo file in the filesystem
+    """
+    meta_type = title = 'Gettext Message Catalog'
+    icon = 'misc_/PlacelessTranslationService/GettextMessageCatalog.png'
+    __roles__=('Manager',)
+    title__roles__=__roles__
+
+    def __init__(self, path_to_file):
+        """Initialize the message catalog"""
+        self._path_to_file = path_to_file
+        self.id = os.path.split(self._path_to_file)[-1]
+        #self.id = self._path_to_file.replace('/', '::')
+        self._prepareTranslations()
+
+    def _prepareTranslations(self):
+        """ """
+        tro = None
+        if getattr(self, '_v_tro', None) is None:
+            self._v_tro = tro = translationRegistry.get(self.id, None)
+        if tro is None:
+            file = open(self._path_to_file, 'rb')
+            tro = GNUTranslations(file)
+            file.close()
+            self._language = (tro._info.get('language-code', None) # new way
+                           or tro._info.get('language', None)) # old way
+            self._domain = tro._info.get('domain', None)
+            if self._language is None or self._domain is None:
+                raise ValueError, 'potfile has no metadata'
+            self._language = self._language.lower().replace('_', '-')
+            self._other_languages = tro._info.get('x-is-fallback-for', 
'').split()
+            self.preferred_encodings = tro._info.get('preferred-encodings', 
'').split()
+            self.name = unicode(tro._info.get('language-name', ''), 
tro._charset)
+            self.default_zope_data_encoding = tro._charset
+            translationRegistry[self.id] = self._v_tro = tro
+            self._missing = self._path_to_file[:-1] + 'issing'
+            if not os.access(self._missing, os.W_OK):
+                self._missing = None
+            if self.name:
+                self.title = '%s language (%s) for %s' % (self._language, 
self.name, self._domain)
+            else:
+                self.title = '%s language for %s' % (self._language, 
self._domain)
+
+    def filtered_manage_options(self, REQUEST=None):
+        return self.manage_options
+
+    def reload(self, REQUEST=None):
+        "Forcibly re-read the file"
+        if self.id in translationRegistry.keys():
+            del translationRegistry[self.id]
+        if hasattr(self, '_v_tro'):
+            del self._v_tro
+        self._prepareTranslations()
+        log('reloading %s: %s' % (self.id, self.title))
+        if hasattr(REQUEST, 'RESPONSE'):
+            REQUEST.RESPONSE.redirect(self.absolute_url())
+
+    def _log_missing(self, id, orig_text):
+        if self._missing is None:
+            return
+        if getattr(self, '_v_missing', None) is None:
+            self._v_missing = codecs.open(self._missing, 'a',
+                                          self._v_tro._charset)
+        if orig_text:
+            orig_text = orig_text_line_joiner.join(orig_text.split('\n'))
+            self._v_missing.write(orig_text_template % {'text': orig_text})
+        self._v_missing.write(missing_template % {'id':id.replace('"', r'\"')})
+        self._v_missing.flush()
+
+    def getMessage(self, id, orig_text=None, testing=False):
+        """
+        """
+        self._prepareTranslations()
+        msg = self._v_tro.gettext(id)
+        if msg is id:
+            if not testing:
+                self._log_missing(id, orig_text)
+            raise KeyError
+        if type(msg) is StringType:
+            msg = unicode(msg, self._v_tro._charset)
+        return msg
+
+    queryMessage__roles__=None # Public
+    def queryMessage(self, id, default=None):
+        """
+        """
+        try:
+            return self.getMessage(id, default, testing=True)
+        except KeyError:
+            if default is None:
+                default = id
+            return default
+
+    def getLanguage(self):
+        """
+        """
+        return self._language
+
+    def getLanguageName(self):
+        """
+        """
+        return self.name or self._language
+
+    def getOtherLanguages(self):
+        """
+        """
+        return self._other_languages
+
+    def getDomain(self):
+        """
+        """
+        return self._domain
+
+    def getIdentifier(self):
+        """
+        """
+        return self.id
+
+    def getId(self):
+        """
+        """
+        return self.id
+
+    def getInfo(self, name):
+        """
+        """
+        self._prepareTranslations()
+        return self._v_tro._info.get(name, None)
+
+    Title__roles__ = __roles__
+    def Title(self):
+        return self.title
+
+    ############################################################
+    # Zope/OFS integration
+
+    def manage_afterAdd(self, item, container): pass
+    def manage_beforeDelete(self, item, container): pass
+    def manage_afterClone(self, item): pass
+
+    manage_options = (
+        {'label':'Info', 'action':''},
+        {'label':'Test', 'action':'zmi_test'},
+        )
+
+    index_html = ptFile('index_html', globals(), 'www', 'catalog_info')
+
+    zmi_test = ptFile('zmi_test', globals(), 'www', 'catalog_test')
+
+    file_exists__roles__ = __roles__
+    def file_exists(self):
+        try:
+            file = open(self._path_to_file, 'rb')
+        except:
+            return False
+        return True
+
+    displayInfo__roles__ = __roles__
+    def displayInfo(self):
+        self._prepareTranslations()
+        info = self._v_tro._info
+        keys = info.keys()
+        keys.sort()
+        return [{'name': k, 'value': info[k]} for k in keys] + [
+            {'name': 'full path', 'value': self._path_to_file},
+            ]
+    #
+    ############################################################
Index: opental/PlacelessTranslationService/PlacelessTranslationService.py
diff -u /dev/null 
opental/PlacelessTranslationService/PlacelessTranslationService.py:1.26.2.1
--- /dev/null   Sun Sep 14 20:07:41 2003
+++ opental/PlacelessTranslationService/PlacelessTranslationService.py  Sun Sep 
14 20:07:41 2003
@@ -0,0 +1,347 @@
+##############################################################################
+#    Copyright (C) 2001, 2002, 2003 Lalo Martins <address@hidden>,
+#                  Zope Corporation and Contributors
+
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+"""Placeless Translation Service for providing I18n to file-based code.
+
+$Id: PlacelessTranslationService.py,v 1.26.2.1 2003/09/15 00:07:41 
dreamcatcher Exp $
+"""
+
+import sys, re, zLOG, Globals, fnmatch
+from AccessControl import ClassSecurityInfo
+from OFS.Folder import Folder
+from types import DictType, StringType, UnicodeType
+from Negotiator import negotiator
+from Domain import Domain
+import os
+try:
+    from pax import XML
+except:
+    def XML(v):
+        return str(v)
+try:
+    True
+except NameError:
+    True=1
+    False=0
+_marker = []
+
+
+def log(msg, severity=zLOG.INFO, detail='', error=None):
+    if type(msg) is UnicodeType:
+        msg = msg.encode(sys.getdefaultencoding(), 'replace')
+    if type(detail) is UnicodeType:
+        detail = detail.encode(sys.getdefaultencoding(), 'replace')
+    zLOG.LOG('PlacelessTranslationService', severity, msg, detail, error)
+
+def map_get(map, name):
+    return map.get(name)
+
+# Setting up some regular expressions for finding interpolation variables in
+# the text.
+NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
+_interp_regex = re.compile(r'(?<!\$)(\$(?:%(n)s|{%(n)s}))' %({'n': NAME_RE}))
+_get_var_regex = re.compile(r'%(n)s' %({'n': NAME_RE}))
+
+
+# The configure.zcml file should specify a list of fallback languages for the
+# site.  If a particular catalog for a negotiated language is not available,
+# then the zcml specified order should be tried.  If that fails, then as a
+# last resort the languages in the following list are tried.  If these fail
+# too, then the msgid is returned.
+#
+# Note that these fallbacks are used only to find a catalog.  If a particular
+# message in a catalog is not translated, tough luck, you get the msgid.
+LANGUAGE_FALLBACKS = list(os.environ.get('LANGUAGE_FALLBACKS', 'en').split(' 
'))
+
+from UserDict import UserDict
+
+class Registry(UserDict):
+
+    def register(self, name, value):
+        self[name] = value
+
+catalogRegistry = Registry()
+registerCatalog = catalogRegistry.register
+fbcatalogRegistry = Registry()
+registerFBCatalog = fbcatalogRegistry.register
+
+class PlacelessTranslationService(Folder):
+    meta_type = title = 'Placeless Translation Service'
+    icon = 'misc_/PlacelessTranslationService/PlacelessTranslationService.png'
+    # major, minor, patchlevel, internal
+    # internal is always 0 on releases; if you hack this internally, increment 
it
+    _class_version = (0, 5, 0, 1)
+    all_meta_types = ()
+
+    security = ClassSecurityInfo()
+    security.declarePublic('negotiate')
+    security.declarePublic('translate')
+    security.declarePublic('getLanguages')
+    security.declarePublic('getLanguageName')
+
+    def __init__(self, default_domain='global', fallbacks=None):
+        self._instance_version = self._class_version
+        # XXX We haven't specified that ITranslationServices have a default
+        # domain.  So far, we've required the domain argument to .translate()
+        self._domain = default_domain
+        # _catalogs maps (language, domain) to identifiers
+        catalogRegistry = {}
+        fbcatalogRegistry = {}
+        # What languages to fallback to, if there is no catalog for the
+        # requested language (no fallback on individual messages)
+        if fallbacks is None:
+            fallbacks = LANGUAGE_FALLBACKS
+        self._fallbacks = fallbacks
+
+    def _registerMessageCatalog(self, catalog):
+        domain = catalog.getDomain()
+        catalogRegistry.setdefault((catalog.getLanguage(), domain), 
[]).append(catalog.getIdentifier())
+        for lang in catalog.getOtherLanguages():
+            fbcatalogRegistry.setdefault((lang, domain), 
[]).append(catalog.getIdentifier())
+        self._p_changed = 1
+
+    def _unregister_inner(self, catalog, clist):
+        for key, combo in clist.items():
+            try:
+                combo.remove(catalog.getIdentifier())
+            except ValueError:
+                continue
+            if not combo: # removed the last catalog for a language/domain 
combination
+                del clist[key]
+
+    def _unregisterMessageCatalog(self, catalog):
+        self._unregister_inner(catalog, catalogRegistry)
+        self._unregister_inner(catalog, fbcatalogRegistry)
+        self._p_changed = 1
+
+    def _load_dir(self, basepath):
+        from GettextMessageCatalog import GettextMessageCatalog
+        log('looking into ' + basepath, zLOG.BLATHER)
+        if not os.path.isdir(basepath):
+            log('it does not exist', zLOG.BLATHER)
+            return
+        names = fnmatch.filter(os.listdir(basepath), '*.mo')
+        if not names:
+            log('nothing found', zLOG.BLATHER)
+            return
+        for name in names:
+            ob = self._getOb(name, _marker)
+            try:
+                if ob is _marker:
+                    
self.addCatalog(GettextMessageCatalog(os.path.join(basepath, name)))
+                else:
+                    self.reloadCatalog(ob)
+            except ValueError:
+                log('Message Catalog has no metadata', zLOG.PROBLEM, name, 
sys.exc_info())
+            except:
+                log('Message Catalog has errors', zLOG.PROBLEM, name, 
sys.exc_info())
+        log('Initialized:', detail = repr(names) + (' from %s\n' % basepath))
+
+    def manage_renameObject(self, id, new_id, REQUEST=None):
+        "wrap manage_renameObject to deal with registration"
+        catalog = self._getOb(id)
+        self._unregisterMessageCatalog(catalog)
+        Folder.manage_renameObject(self, id, new_id, REQUEST=None)
+        self._registerMessageCatalog(catalog)
+
+    def _delObject(self, id, dp=1):
+        catalog = self._getOb(id)
+        Folder._delObject(self, id, dp)
+        self._unregisterMessageCatalog(catalog)
+
+    def reloadCatalog(self, catalog):
+        # trigger an exception if we don't know anything about it
+        self._getOb(catalog.id)
+        self._unregisterMessageCatalog(catalog)
+        catalog.reload()
+        self._registerMessageCatalog(catalog)
+
+    def addCatalog(self, catalog):
+        try:
+            self._delObject(catalog.id)
+        except:
+            pass
+        self._setObject(catalog.id, catalog, set_owner=False)
+        log('adding %s: %s' % (catalog.id, catalog.title))
+        self._registerMessageCatalog(catalog)
+
+    def setLanguageFallbacks(self, fallbacks=None):
+        if fallbacks is None:
+            fallbacks = LANGUAGE_FALLBACKS
+        self._fallbacks = fallbacks
+
+
+    def getLanguageName(self, code):
+        for (ccode, cdomain), cnames in catalogRegistry.items():
+            if ccode == code:
+                for cname in cnames:
+                    cat = self._getOb(cname)
+                    if cat.name:
+                        return cat.name
+
+
+    def getLanguages(self, domain=None):
+        """Get available languages"""
+        if domain is None:
+            # no domain, so user wants 'em all
+            langs = catalogRegistry.keys()
+            # uniquify
+            d = {}
+            for l in langs:
+                d[l[0]] = 1
+            l = d.keys()
+        else:
+            l = [k[0] for k in catalogRegistry.keys() if k[1] == domain]
+        l.sort()
+        return l
+
+    def negotiate(self, langs, context):
+        return negotiator.getLanguage(langs, context)
+
+    def translate(self, domain, msgid, mapping=None, context=None,
+                  target_language=None, default=None):
+        """
+        """
+
+        if not msgid:
+            # refuse to translate an empty msgid
+            return default
+
+        # ZPT passes the object as context.  That's wrong according to spec.
+        try:
+            context = context.REQUEST
+        except AttributeError:
+            pass
+
+        if target_language is None:
+            target_language = self.negotiate_language(context, domain)
+
+        # Get the translation. Use the specified fallbacks if this fails
+        catalog_names = catalogRegistry.get((target_language, domain), ()) or \
+                        fbcatalogRegistry.get((target_language, domain), ())
+        if not catalog_names:
+            for language in self._fallbacks:
+                catalog_names = catalogRegistry.get((language, domain),  ())
+                if catalog_names:
+                    break
+
+        for name in catalog_names:
+            catalog = self._getOb(name)
+            try:
+                text = catalog.getMessage(msgid, default)
+            except KeyError:
+                # it's not in this catalog, try the next one
+                continue
+            # found! negotiate output encodings now
+            if hasattr(context, 'pt_output_encoding'):
+                # OpenPT
+                if catalog.preferred_encodings:
+                    context.pt_output_encoding.restrict(catalog, 
catalog.preferred_encodings)
+            else:
+                # ZPT probably
+                # ask HTTPResponse to encode it for us
+                text = context.RESPONSE._encode_unicode(text)
+            break
+        else:
+            # Did the fallback fail?  Sigh, use the default.
+            # OpenTAL provides a default text.
+            # TAL doesn't but will use the default
+            # if None is returned
+            text = default
+
+        # Now we need to do the interpolation
+        text = self.interpolate(text, mapping)
+        return text
+
+    def negotiate_language(self, context, domain):
+        if context is None:
+            raise TypeError, 'No destination language'
+        else:
+            langs = [m[0] for m in catalogRegistry.keys() if m[1] == domain] + 
\
+                    [m[0] for m in fbcatalogRegistry.keys() if m[1] == domain]
+            for fallback in self._fallbacks:
+                if fallback not in langs:
+                    langs.append(fallback)
+            target_language = self.negotiate(langs, context)
+        return target_language
+
+    def getDomain(self, domain):
+        """
+        """
+        return Domain(domain, self)
+
+    def interpolate(self, text, mapping):
+     try:
+        """Insert the data passed from mapping into the text"""
+
+        # If the mapping does not exist, make a "raw translation" without
+        # interpolation.
+        if mapping is None or type(text) not in (StringType, UnicodeType):
+            # silly wabbit!
+            return text
+
+        get = map_get
+        try:
+            mapping.get('')
+        except AttributeError:
+            get = getattr
+
+        # Find all the spots we want to substitute
+        to_replace = _interp_regex.findall(text)
+
+        # ZPT (string) or OpenPT (unicode)?
+        if type(text) is StringType:
+            conv = str
+        else:
+            conv = XML
+
+        # Now substitute with the variables in mapping
+        for string in to_replace:
+            var = _get_var_regex.findall(string)[0]
+            value = get(mapping, var)
+            try:
+                value = value()
+            except (TypeError, AttributeError):
+                pass
+            if value is None:
+                value = string
+            if type(value) not in (StringType, UnicodeType):
+                # FIXME: we shouldn't do this. We should instead
+                # return a list. But i'm not sure about how to use
+                # the regex to split the text.
+                value = conv(value)
+            text = text.replace(string, value)
+
+        return text
+     except:
+        import traceback
+        traceback.print_exc()
+
+    def manage_main(self, REQUEST, *a, **kw):
+        "Wrap Folder's manage_main to render international characters"
+        # ugh, API cruft
+        if REQUEST is self and a:
+            REQUEST = a[0]
+            a = a[1:]
+        r = Folder.manage_main(self, self, REQUEST, *a, **kw)
+        if type(r) is UnicodeType:
+            r = r.encode('utf-8')
+        REQUEST.RESPONSE.setHeader('Content-type', 'text/html; charset=utf-8')
+        return r
+
+    #
+    ############################################################
Index: opental/PlacelessTranslationService/__init__.py
diff -u /dev/null opental/PlacelessTranslationService/__init__.py:1.14.2.1
--- /dev/null   Sun Sep 14 20:07:41 2003
+++ opental/PlacelessTranslationService/__init__.py     Sun Sep 14 20:07:41 2003
@@ -0,0 +1,111 @@
+##############################################################################
+#    Copyright (C) 2001, 2002, 2003 Lalo Martins <address@hidden>,
+#                  and Contributors
+
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
+__version__ = '''
+$Id: __init__.py,v 1.14.2.1 2003/09/15 00:07:41 dreamcatcher Exp $
+'''.strip()
+
+from OFS.Application import get_products
+from AccessControl import ModuleSecurityInfo, allow_module, allow_class, 
allow_type
+from PlacelessTranslationService import PlacelessTranslationService, log
+from Products.PageTemplates.GlobalTranslationService import 
setGlobalTranslationService
+import os, fnmatch, zLOG, sys, Zope, Globals
+
+# in python 2.1 fnmatch doesn't have the filter function
+if not hasattr(fnmatch, 'filter'):
+    def fnfilter(names, pattern):
+        return [name for name in names if fnmatch.fnmatch(name, pattern)]
+    fnmatch.filter = fnfilter
+
+# patch flaky ZPT - this must be removed once someone fixes it
+# I'm leaving this enabled even for OpenPT, because it somehow manages
+# to make zope a bit faster...
+import PatchStringIO
+
+# this is for packages that need to initialize stuff after we're done
+notify_initialized = []
+
+# id to use in the Control Panel
+cp_id = 'TranslationService'
+
+# icon
+misc_ = {
+    'PlacelessTranslationService.png':
+    Globals.ImageFile('www/PlacelessTranslationService.png', globals()),
+    'GettextMessageCatalog.png':
+    Globals.ImageFile('www/GettextMessageCatalog.png', globals()),
+    }
+
+# import permissions
+security = ModuleSecurityInfo('Products.PlacelessTranslationService')
+security.declarePublic('negotiate')
+security.declarePublic('translate')
+security.declarePublic('getLanguages')
+security.declarePublic('getLanguageName')
+
+def make_translation_service(cp):
+    from Products import PlacelessTranslationService as pkg
+    # default (gettext) translation service
+    translation_service = PlacelessTranslationService('default')
+    translation_service.id = cp_id
+    cp._setObject(cp_id, translation_service)
+
+def initialize(context):
+    from Products import PlacelessTranslationService as pkg
+
+    # hook into the Control Panel
+    cp = context._ProductContext__app.Control_Panel # argh
+    if cp_id not in cp.objectIds():
+        make_translation_service(cp)
+    pkg.translation_service = getattr(cp, cp_id)
+
+    # don't touch - this is the last version
+    # that didn't have the attribute (0.4)
+    instance_version = getattr(translation_service, '_instance_version', (0, 
4, 0, 0))
+    if instance_version < PlacelessTranslationService._class_version:
+        log('outdated translation service found, recreating',
+            detail = '(found %s.%s.%s.%s)\n' % instance_version)
+        cp._delObject(cp_id)
+        make_translation_service(cp)
+        pkg.translation_service = getattr(cp, cp_id)
+    ts_unwrapped = translation_service.aq_base
+
+    # set ZPT's translation service
+    setGlobalTranslationService(translation_service)
+
+    pkg.translate = translation_service.translate
+    pkg.getLanguages = translation_service.getLanguages
+    pkg.getLanguageName = translation_service.getLanguageName
+    pkg.negotiate = translation_service.negotiate
+
+    log('products: %r' % get_products(), zLOG.BLATHER)
+    # sweep products
+    for prod in get_products():
+        # prod is a tuple in the form:
+        #(priority, dir_name, index, base_dir) for each Product directory
+        ts_unwrapped._load_dir(os.path.join(prod[3], prod[1], 'i18n'))
+
+    # sweep the i18n directory for local catalogs
+    ts_unwrapped._load_dir(os.path.join(INSTANCE_HOME, 'i18n'))
+
+    # didn't found any catalogs
+    if not ts_unwrapped.objectIds():
+        log('no translations found!', zLOG.PROBLEM)
+
+    # notify anyone who needs it
+    for function in notify_initialized:
+        function()




reply via email to

[Prev in Thread] Current Thread [Next in Thread]