[Top][All Lists]
[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',
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [OpenTAL-checkins] opental/PlacelessTranslationService GettextMess...,
Fernando Lalo Martins <=