opental-checkins
[Top][All Lists]
Advanced

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

[OpenTAL-checkins] opental/PlacelessTranslationService GettextMess...


From: Fernando Lalo Martins
Subject: [OpenTAL-checkins] opental/PlacelessTranslationService GettextMess...
Date: Fri, 26 Sep 2003 11:24:53 -0400

CVSROOT:        /cvsroot/opental
Module name:    opental
Branch:         
Changes by:     Fernando Lalo Martins <address@hidden>  03/09/26 11:24:53

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

Log message:
        merged Sidnei's branch

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

Patches:
Index: opental/PlacelessTranslationService/GettextMessageCatalog.py
diff -u opental/PlacelessTranslationService/GettextMessageCatalog.py:1.14 
opental/PlacelessTranslationService/GettextMessageCatalog.py:1.15
--- opental/PlacelessTranslationService/GettextMessageCatalog.py:1.14   Tue Aug 
 5 13:03:13 2003
+++ opental/PlacelessTranslationService/GettextMessageCatalog.py        Fri Sep 
26 11:24:53 2003
@@ -15,9 +15,9 @@
 #    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. 
+"""A simple implementation of a Message Catalog.
 
-$Id: GettextMessageCatalog.py,v 1.14 2003/08/05 17:03:13 lalo Exp $
+$Id: GettextMessageCatalog.py,v 1.15 2003/09/26 15:24:53 lalo Exp $
 """
 
 from gettext import GNUTranslations
@@ -27,7 +27,9 @@
 from Persistence import Persistent
 from Acquisition import Implicit
 from App.Management import Tabs
-from PlacelessTranslationService import log
+import re
+from PlacelessTranslationService import log, Registry
+
 try:
     True
 except NameError:
@@ -61,6 +63,19 @@
 
 permission = 'View management screens'
 
+translationRegistry = Registry()
+registerTranslation = translationRegistry.register
+
+def getMessage(catalog, id, orig_text=None):
+    """
+    """
+    msg = catalog.gettext(id)
+    if msg is id:
+        raise KeyError
+    if type(msg) is StringType:
+        msg = unicode(msg, catalog._charset)
+    return msg
+
 class GettextMessageCatalog(Persistent, Implicit, Traversable, Tabs):
     """
     Message catalog that wraps a .mo file in the filesystem
@@ -75,12 +90,14 @@
         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.__translation_object = None
         self._prepareTranslations()
-    
+
     def _prepareTranslations(self):
         """ """
-        if self.__translation_object is None:
+        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()
@@ -94,9 +111,11 @@
             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
-            self.__translation_object = tro
-            self._missing = self._path_to_file[:-1] + 'issing'
-            if not os.access(self._missing, os.W_OK):
+            translationRegistry[self.id] = self._v_tro = tro
+            missingFileName = self._path_to_file[:-1] + 'issing'
+            if os.access(missingFileName, os.W_OK):
+                self._missing = MissingIds(missingFileName, 
self._v_tro._charset)
+            else:
                 self._missing = None
             if self.name:
                 self.title = '%s language (%s) for %s' % (self._language, 
self.name, self._domain)
@@ -108,35 +127,31 @@
 
     def reload(self, REQUEST=None):
         "Forcibly re-read the file"
-        self.__translation_object = None
+        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())
+            if not REQUEST.form.has_key('noredir'):
+                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.__translation_object._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()
+        self._missing.log(id, orig_text)
 
     def getMessage(self, id, orig_text=None, testing=False):
         """
         """
         self._prepareTranslations()
-        msg = self.__translation_object.gettext(id)
-        if msg is id:
+        try:
+            msg = getMessage(self._v_tro)
+        except KeyError:
             if not testing:
                 self._log_missing(id, orig_text)
-            raise KeyError
-        if type(msg) is StringType:
-            msg = unicode(msg, self.__translation_object._charset)
+            raise
         return msg
 
     queryMessage__roles__=None # Public
@@ -154,17 +169,17 @@
         """
         """
         return self._language
-        
+
     def getLanguageName(self):
         """
         """
         return self.name or self._language
-        
+
     def getOtherLanguages(self):
         """
         """
         return self._other_languages
-        
+
     def getDomain(self):
         """
         """
@@ -183,7 +198,8 @@
     def getInfo(self, name):
         """
         """
-        return self.__translation_object._info.get(name, None)
+        self._prepareTranslations()
+        return self._v_tro._info.get(name, None)
 
     Title__roles__ = __roles__
     def Title(self):
@@ -191,7 +207,7 @@
 
     ############################################################
     # Zope/OFS integration
-    
+
     def manage_afterAdd(self, item, container): pass
     def manage_beforeDelete(self, item, container): pass
     def manage_afterClone(self, item): pass
@@ -216,7 +232,7 @@
     displayInfo__roles__ = __roles__
     def displayInfo(self):
         self._prepareTranslations()
-        info = self.__translation_object._info
+        info = self._v_tro._info
         keys = info.keys()
         keys.sort()
         return [{'name': k, 'value': info[k]} for k in keys] + [
@@ -224,3 +240,33 @@
             ]
     #
     ############################################################
+
+class MissingIds(Persistent):
+    def __init__(self, fileName, charset):
+        self._fileName = fileName
+        self._charset = charset
+        self._ids = {}
+        self._pattern = re.compile('msgid "(.*)"$')
+        self.parseFile()
+        self._v_file = None
+
+    def parseFile(self):
+        file = codecs.open(self._fileName, 'r', self._charset)
+        for line in file.xreadlines():
+            match = self._pattern.search(line)
+            if match:
+                msgid = match.group(1)
+                self._ids[msgid] = 1
+        file.close()
+
+    def log(self, msgid, orig_text):
+        if not self._ids.has_key(msgid):
+            if getattr(self, '_v_file', None) is None:
+              self._v_file = codecs.open(self._fileName, 'a', self._charset)
+            if orig_text:
+                orig_text = orig_text_line_joiner.join(orig_text.split('\n'))
+                self._v_file.write(orig_text_template % {'text': orig_text})
+            self._v_file.write(missing_template % {'id':msgid.replace('"', 
r'\"')})
+            self._v_file.flush()
+            self._ids[msgid]=1
+
Index: opental/PlacelessTranslationService/PlacelessTranslationService.py
diff -u opental/PlacelessTranslationService/PlacelessTranslationService.py:1.26 
opental/PlacelessTranslationService/PlacelessTranslationService.py:1.27
--- opental/PlacelessTranslationService/PlacelessTranslationService.py:1.26     
Tue Aug  5 13:03:13 2003
+++ opental/PlacelessTranslationService/PlacelessTranslationService.py  Fri Sep 
26 11:24:53 2003
@@ -17,7 +17,7 @@
 #    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 2003/08/05 17:03:13 lalo Exp $
+$Id: PlacelessTranslationService.py,v 1.27 2003/09/26 15:24:53 lalo Exp $
 """
 
 import sys, re, zLOG, Globals, fnmatch
@@ -67,6 +67,17 @@
 # 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'
@@ -88,8 +99,8 @@
         # domain.  So far, we've required the domain argument to .translate()
         self._domain = default_domain
         # _catalogs maps (language, domain) to identifiers
-        self._catalogs = {}
-        self._fb_catalogs = {}
+        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:
@@ -98,9 +109,9 @@
 
     def _registerMessageCatalog(self, catalog):
         domain = catalog.getDomain()
-        self._catalogs.setdefault((catalog.getLanguage(), domain), 
[]).append(catalog.getIdentifier())
+        catalogRegistry.setdefault((catalog.getLanguage(), domain), 
[]).append(catalog.getIdentifier())
         for lang in catalog.getOtherLanguages():
-            self._fb_catalogs.setdefault((lang, domain), 
[]).append(catalog.getIdentifier())
+            fbcatalogRegistry.setdefault((lang, domain), 
[]).append(catalog.getIdentifier())
         self._p_changed = 1
 
     def _unregister_inner(self, catalog, clist):
@@ -113,8 +124,8 @@
                 del clist[key]
 
     def _unregisterMessageCatalog(self, catalog):
-        self._unregister_inner(catalog, self._catalogs)
-        self._unregister_inner(catalog, self._fb_catalogs)
+        self._unregister_inner(catalog, catalogRegistry)
+        self._unregister_inner(catalog, fbcatalogRegistry)
         self._p_changed = 1
 
     def _load_dir(self, basepath):
@@ -175,7 +186,7 @@
 
 
     def getLanguageName(self, code):
-        for (ccode, cdomain), cnames in self._catalogs.items():
+        for (ccode, cdomain), cnames in catalogRegistry.items():
             if ccode == code:
                 for cname in cnames:
                     cat = self._getOb(cname)
@@ -187,24 +198,25 @@
         """Get available languages"""
         if domain is None:
             # no domain, so user wants 'em all
-            langs = self._catalogs.keys()
+            langs = catalogRegistry.keys()
             # uniquify
             d = {}
             for l in langs:
                 d[l[0]] = 1
             l = d.keys()
         else:
-            l = [k[0] for k in self._catalogs.keys() if k[1] == domain]
+            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,  
+    def translate(self, domain, msgid, mapping=None, context=None,
                   target_language=None, default=None):
         """
         """
+        from GettextMessageCatalog import translationRegistry, getMessage
 
         if not msgid:
             # refuse to translate an empty msgid
@@ -215,23 +227,23 @@
             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 = self._catalogs.get((target_language, domain), ()) or \
-                        self._fb_catalogs.get((target_language, domain), ())
+        catalog_names = catalogRegistry.get((target_language, domain), ()) or \
+                        fbcatalogRegistry.get((target_language, domain), ())
         if not catalog_names:
             for language in self._fallbacks:
-                catalog_names = self._catalogs.get((language, domain),  ())
+                catalog_names = catalogRegistry.get((language, domain),  ())
                 if catalog_names:
                     break
-        
+
         for name in catalog_names:
-            catalog = self._getOb(name)
+            catalog = translationRegistry[name]
             try:
-                text = catalog.getMessage(msgid, default)
+                text = getMessage(catalog, msgid, default)
             except KeyError:
                 # it's not in this catalog, try the next one
                 continue
@@ -260,8 +272,8 @@
         if context is None:
             raise TypeError, 'No destination language'
         else:
-            langs = [m[0] for m in self._catalogs.keys() if m[1] == domain] + \
-                    [m[0] for m in self._fb_catalogs.keys() if m[1] == domain]
+            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)
@@ -278,7 +290,7 @@
         """Insert the data passed from mapping into the text"""
 
         # If the mapping does not exist, make a "raw translation" without
-        # interpolation. 
+        # interpolation.
         if mapping is None or type(text) not in (StringType, UnicodeType):
             # silly wabbit!
             return text
Index: opental/PlacelessTranslationService/__init__.py
diff -u opental/PlacelessTranslationService/__init__.py:1.14 
opental/PlacelessTranslationService/__init__.py:1.15
--- opental/PlacelessTranslationService/__init__.py:1.14        Tue Aug  5 
13:03:13 2003
+++ opental/PlacelessTranslationService/__init__.py     Fri Sep 26 11:24:53 2003
@@ -16,7 +16,7 @@
 #    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 2003/08/05 17:03:13 lalo Exp $
+$Id: __init__.py,v 1.15 2003/09/26 15:24:53 lalo Exp $
 '''.strip()
 
 from OFS.Application import get_products
@@ -73,8 +73,8 @@
         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)
+    # 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',




reply via email to

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