15 |
# You should have received a copy of the GNU General Public License |
# You should have received a copy of the GNU General Public License |
16 |
# along with this program; if not, write to the Free Software |
# along with this program; if not, write to the Free Software |
17 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA |
18 |
"""A simple implementation of a Message Catalog. |
"""A simple implementation of a Message Catalog. |
19 |
|
|
20 |
$Id$ |
$Id$ |
21 |
""" |
""" |
27 |
from Persistence import Persistent |
from Persistence import Persistent |
28 |
from Acquisition import Implicit |
from Acquisition import Implicit |
29 |
from App.Management import Tabs |
from App.Management import Tabs |
30 |
from PlacelessTranslationService import log |
from PlacelessTranslationService import log, Registry |
31 |
try: |
try: |
32 |
True |
True |
33 |
except NameError: |
except NameError: |
61 |
|
|
62 |
permission = 'View management screens' |
permission = 'View management screens' |
63 |
|
|
64 |
|
translationRegistry = Registry() |
65 |
|
registerTranslation = translationRegistry.register |
66 |
|
|
67 |
class GettextMessageCatalog(Persistent, Implicit, Traversable, Tabs): |
class GettextMessageCatalog(Persistent, Implicit, Traversable, Tabs): |
68 |
""" |
""" |
69 |
Message catalog that wraps a .mo file in the filesystem |
Message catalog that wraps a .mo file in the filesystem |
78 |
self._path_to_file = path_to_file |
self._path_to_file = path_to_file |
79 |
self.id = os.path.split(self._path_to_file)[-1] |
self.id = os.path.split(self._path_to_file)[-1] |
80 |
#self.id = self._path_to_file.replace('/', '::') |
#self.id = self._path_to_file.replace('/', '::') |
|
self.__translation_object = None |
|
81 |
self._prepareTranslations() |
self._prepareTranslations() |
82 |
|
|
83 |
def _prepareTranslations(self): |
def _prepareTranslations(self): |
84 |
""" """ |
""" """ |
85 |
if self.__translation_object is None: |
tro = None |
86 |
|
if getattr(self, '_v_tro', None) is None: |
87 |
|
self._v_tro = tro = translationRegistry.get(self.id, None) |
88 |
|
if tro is None: |
89 |
file = open(self._path_to_file, 'rb') |
file = open(self._path_to_file, 'rb') |
90 |
tro = GNUTranslations(file) |
tro = GNUTranslations(file) |
91 |
file.close() |
file.close() |
99 |
self.preferred_encodings = tro._info.get('preferred-encodings', '').split() |
self.preferred_encodings = tro._info.get('preferred-encodings', '').split() |
100 |
self.name = unicode(tro._info.get('language-name', ''), tro._charset) |
self.name = unicode(tro._info.get('language-name', ''), tro._charset) |
101 |
self.default_zope_data_encoding = tro._charset |
self.default_zope_data_encoding = tro._charset |
102 |
self.__translation_object = tro |
translationRegistry[self.id] = self._v_tro = tro |
103 |
self._missing = self._path_to_file[:-1] + 'issing' |
self._missing = self._path_to_file[:-1] + 'issing' |
104 |
if not os.access(self._missing, os.W_OK): |
if not os.access(self._missing, os.W_OK): |
105 |
self._missing = None |
self._missing = None |
113 |
|
|
114 |
def reload(self, REQUEST=None): |
def reload(self, REQUEST=None): |
115 |
"Forcibly re-read the file" |
"Forcibly re-read the file" |
116 |
self.__translation_object = None |
if self.id in translationRegistry.keys(): |
117 |
|
del translationRegistry[self.id] |
118 |
|
if hasattr(self, '_v_tro'): |
119 |
|
del self._v_tro |
120 |
self._prepareTranslations() |
self._prepareTranslations() |
121 |
log('reloading %s: %s' % (self.id, self.title)) |
log('reloading %s: %s' % (self.id, self.title)) |
122 |
if hasattr(REQUEST, 'RESPONSE'): |
if hasattr(REQUEST, 'RESPONSE'): |
127 |
return |
return |
128 |
if getattr(self, '_v_missing', None) is None: |
if getattr(self, '_v_missing', None) is None: |
129 |
self._v_missing = codecs.open(self._missing, 'a', |
self._v_missing = codecs.open(self._missing, 'a', |
130 |
self.__translation_object._charset) |
self._v_tro._charset) |
131 |
if orig_text: |
if orig_text: |
132 |
orig_text = orig_text_line_joiner.join(orig_text.split('\n')) |
orig_text = orig_text_line_joiner.join(orig_text.split('\n')) |
133 |
self._v_missing.write(orig_text_template % {'text': orig_text}) |
self._v_missing.write(orig_text_template % {'text': orig_text}) |
138 |
""" |
""" |
139 |
""" |
""" |
140 |
self._prepareTranslations() |
self._prepareTranslations() |
141 |
msg = self.__translation_object.gettext(id) |
msg = self._v_tro.gettext(id) |
142 |
if msg is id: |
if msg is id: |
143 |
if not testing: |
if not testing: |
144 |
self._log_missing(id, orig_text) |
self._log_missing(id, orig_text) |
145 |
raise KeyError |
raise KeyError |
146 |
if type(msg) is StringType: |
if type(msg) is StringType: |
147 |
msg = unicode(msg, self.__translation_object._charset) |
msg = unicode(msg, self._v_tro._charset) |
148 |
return msg |
return msg |
149 |
|
|
150 |
queryMessage__roles__=None # Public |
queryMessage__roles__=None # Public |
162 |
""" |
""" |
163 |
""" |
""" |
164 |
return self._language |
return self._language |
165 |
|
|
166 |
def getLanguageName(self): |
def getLanguageName(self): |
167 |
""" |
""" |
168 |
""" |
""" |
169 |
return self.name or self._language |
return self.name or self._language |
170 |
|
|
171 |
def getOtherLanguages(self): |
def getOtherLanguages(self): |
172 |
""" |
""" |
173 |
""" |
""" |
174 |
return self._other_languages |
return self._other_languages |
175 |
|
|
176 |
def getDomain(self): |
def getDomain(self): |
177 |
""" |
""" |
178 |
""" |
""" |
191 |
def getInfo(self, name): |
def getInfo(self, name): |
192 |
""" |
""" |
193 |
""" |
""" |
194 |
return self.__translation_object._info.get(name, None) |
self._prepareTranslations() |
195 |
|
return self._v_tro._info.get(name, None) |
196 |
|
|
197 |
Title__roles__ = __roles__ |
Title__roles__ = __roles__ |
198 |
def Title(self): |
def Title(self): |
200 |
|
|
201 |
############################################################ |
############################################################ |
202 |
# Zope/OFS integration |
# Zope/OFS integration |
203 |
|
|
204 |
def manage_afterAdd(self, item, container): pass |
def manage_afterAdd(self, item, container): pass |
205 |
def manage_beforeDelete(self, item, container): pass |
def manage_beforeDelete(self, item, container): pass |
206 |
def manage_afterClone(self, item): pass |
def manage_afterClone(self, item): pass |
225 |
displayInfo__roles__ = __roles__ |
displayInfo__roles__ = __roles__ |
226 |
def displayInfo(self): |
def displayInfo(self): |
227 |
self._prepareTranslations() |
self._prepareTranslations() |
228 |
info = self.__translation_object._info |
info = self._v_tro._info |
229 |
keys = info.keys() |
keys = info.keys() |
230 |
keys.sort() |
keys.sort() |
231 |
return [{'name': k, 'value': info[k]} for k in keys] + [ |
return [{'name': k, 'value': info[k]} for k in keys] + [ |