Mercurial > babel > old > mirror
comparison babel/messages/catalog.py @ 108:8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
author | cmlenz |
---|---|
date | Thu, 14 Jun 2007 09:49:00 +0000 |
parents | 4b42e23644e5 |
children | 7a5a7bf39d3d |
comparison
equal
deleted
inserted
replaced
107:4b42e23644e5 | 108:8ea225f33f28 |
---|---|
12 # history and logs, available at http://babel.edgewall.org/log/. | 12 # history and logs, available at http://babel.edgewall.org/log/. |
13 | 13 |
14 """Data structures for message catalogs.""" | 14 """Data structures for message catalogs.""" |
15 | 15 |
16 from datetime import datetime | 16 from datetime import datetime |
17 from email import message_from_string | |
17 import re | 18 import re |
18 try: | 19 try: |
19 set | 20 set |
20 except NameError: | 21 except NameError: |
21 from sets import Set as set | 22 from sets import Set as set |
22 import time | 23 import time |
23 | 24 |
24 from babel import __version__ as VERSION | 25 from babel import __version__ as VERSION |
25 from babel.core import Locale | 26 from babel.core import Locale |
26 from babel.messages.plurals import PLURALS | 27 from babel.messages.plurals import PLURALS |
27 from babel.util import odict, LOCALTZ, UTC | 28 from babel.util import odict, LOCALTZ, UTC, FixedOffsetTimezone |
28 | 29 |
29 __all__ = ['Message', 'Catalog'] | 30 __all__ = ['Message', 'Catalog'] |
30 __docformat__ = 'restructuredtext en' | 31 __docformat__ = 'restructuredtext en' |
31 | 32 |
32 PYTHON_FORMAT = re.compile(r'\%(\([\w]+\))?[diouxXeEfFgGcrs]').search | 33 PYTHON_FORMAT = re.compile(r'\%(\([\w]+\))?[diouxXeEfFgGcrs]').search |
43 pluralizable messages | 44 pluralizable messages |
44 :param string: the translated message string, or a | 45 :param string: the translated message string, or a |
45 ``(singular, plural)`` tuple for pluralizable messages | 46 ``(singular, plural)`` tuple for pluralizable messages |
46 :param locations: a sequence of ``(filenname, lineno)`` tuples | 47 :param locations: a sequence of ``(filenname, lineno)`` tuples |
47 :param flags: a set or sequence of flags | 48 :param flags: a set or sequence of flags |
48 :param comments: a sequence of translator comments for the message | 49 :param auto_comments: a sequence of automatic comments for the message |
50 :param user_comments: a sequence of user comments for the message | |
49 """ | 51 """ |
50 self.id = id | 52 self.id = id |
51 if not string and self.pluralizable: | 53 if not string and self.pluralizable: |
52 string = (u'', u'') | 54 string = (u'', u'') |
53 self.string = string | 55 self.string = string |
147 | 149 |
148 self.project = project or 'PROJECT' #: the project name | 150 self.project = project or 'PROJECT' #: the project name |
149 self.version = version or 'VERSION' #: the project version | 151 self.version = version or 'VERSION' #: the project version |
150 self.copyright_holder = copyright_holder or 'ORGANIZATION' | 152 self.copyright_holder = copyright_holder or 'ORGANIZATION' |
151 self.msgid_bugs_address = msgid_bugs_address or 'EMAIL@ADDRESS' | 153 self.msgid_bugs_address = msgid_bugs_address or 'EMAIL@ADDRESS' |
152 self.last_translator = last_translator #: last translator name + email | 154 |
155 self.last_translator = last_translator or 'FULL NAME <EMAIL@ADDRESS>' | |
156 """Name and email address of the last translator.""" | |
157 | |
153 self.charset = charset or 'utf-8' | 158 self.charset = charset or 'utf-8' |
154 | 159 |
155 if creation_date is None: | 160 if creation_date is None: |
156 creation_date = datetime.now(LOCALTZ) | 161 creation_date = datetime.now(LOCALTZ) |
157 elif isinstance(creation_date, datetime) and not creation_date.tzinfo: | 162 elif isinstance(creation_date, datetime) and not creation_date.tzinfo: |
184 # Translations template for Foobar. | 189 # Translations template for Foobar. |
185 # Copyright (C) 2007 Foo Company | 190 # Copyright (C) 2007 Foo Company |
186 # This file is distributed under the same license as the Foobar project. | 191 # This file is distributed under the same license as the Foobar project. |
187 # FIRST AUTHOR <EMAIL@ADDRESS>, 2007. | 192 # FIRST AUTHOR <EMAIL@ADDRESS>, 2007. |
188 # | 193 # |
189 | 194 |
190 :type: `unicode` | 195 :type: `unicode` |
191 """) | 196 """) |
192 | 197 |
193 def mime_headers(self): | 198 def _get_mime_headers(self): |
194 headers = [] | 199 headers = [] |
195 headers.append(('Project-Id-Version', | 200 headers.append(('Project-Id-Version', |
196 '%s %s' % (self.project, self.version))) | 201 '%s %s' % (self.project, self.version))) |
197 headers.append(('Report-Msgid-Bugs-To', self.msgid_bugs_address)) | 202 headers.append(('Report-Msgid-Bugs-To', self.msgid_bugs_address)) |
198 headers.append(('POT-Creation-Date', | 203 headers.append(('POT-Creation-Date', |
211 headers.append(('Content-Type', | 216 headers.append(('Content-Type', |
212 'text/plain; charset=%s' % self.charset)) | 217 'text/plain; charset=%s' % self.charset)) |
213 headers.append(('Content-Transfer-Encoding', '8bit')) | 218 headers.append(('Content-Transfer-Encoding', '8bit')) |
214 headers.append(('Generated-By', 'Babel %s\n' % VERSION)) | 219 headers.append(('Generated-By', 'Babel %s\n' % VERSION)) |
215 return headers | 220 return headers |
216 mime_headers = property(mime_headers, doc="""\ | 221 |
222 def _set_mime_headers(self, headers): | |
223 for name, value in headers: | |
224 name = name.lower() | |
225 if name == 'project-id-version': | |
226 parts = value.split(' ') | |
227 self.project = ' '.join(parts[:-1]) | |
228 self.version = parts[-1] | |
229 elif name == 'report-msgid-bugs-to': | |
230 self.msgid_bugs_address = value | |
231 elif name == 'last-translator': | |
232 self.last_translator = value | |
233 elif name == 'pot-creation-date': | |
234 # FIXME: this should use dates.parse_datetime as soon as that | |
235 # is ready | |
236 value, tzoffset, _ = re.split('[+-](\d{4})$', value, 1) | |
237 tt = time.strptime(value, '%Y-%m-%d %H:%M') | |
238 ts = time.mktime(tt) | |
239 tzoffset = FixedOffsetTimezone(int(tzoffset)) | |
240 self.creation_date = datetime.fromtimestamp(ts, tzoffset) | |
241 | |
242 mime_headers = property(_get_mime_headers, _set_mime_headers, doc="""\ | |
217 The MIME headers of the catalog, used for the special ``msgid ""`` entry. | 243 The MIME headers of the catalog, used for the special ``msgid ""`` entry. |
218 | 244 |
219 The behavior of this property changes slightly depending on whether a locale | 245 The behavior of this property changes slightly depending on whether a locale |
220 is set or not, the latter indicating that the catalog is actually a template | 246 is set or not, the latter indicating that the catalog is actually a template |
221 for actual translations. | 247 for actual translations. |
378 current.locations.extend(message.locations) | 404 current.locations.extend(message.locations) |
379 current.auto_comments.extend(message.auto_comments) | 405 current.auto_comments.extend(message.auto_comments) |
380 current.user_comments.extend(message.user_comments) | 406 current.user_comments.extend(message.user_comments) |
381 current.flags |= message.flags | 407 current.flags |= message.flags |
382 message = current | 408 message = current |
409 elif id == '': | |
410 # special treatment for the header message | |
411 headers = message_from_string(message.string.encode(self.charset)) | |
412 self.mime_headers = headers.items() | |
383 else: | 413 else: |
384 if isinstance(id, (list, tuple)): | 414 if isinstance(id, (list, tuple)): |
385 assert isinstance(message.string, (list, tuple)) | 415 assert isinstance(message.string, (list, tuple)) |
386 self._messages[key] = message | 416 self._messages[key] = message |
387 | 417 |
401 pluralizable messages | 431 pluralizable messages |
402 :param string: the translated message string, or a | 432 :param string: the translated message string, or a |
403 ``(singular, plural)`` tuple for pluralizable messages | 433 ``(singular, plural)`` tuple for pluralizable messages |
404 :param locations: a sequence of ``(filenname, lineno)`` tuples | 434 :param locations: a sequence of ``(filenname, lineno)`` tuples |
405 :param flags: a set or sequence of flags | 435 :param flags: a set or sequence of flags |
406 :param comments: a list of translator comments | 436 :param auto_comments: a sequence of automatic comments |
437 :param user_comments: a sequence of user comments | |
407 """ | 438 """ |
408 self[id] = Message(id, string, list(locations), flags, auto_comments, | 439 self[id] = Message(id, string, list(locations), flags, auto_comments, |
409 user_comments) | 440 user_comments) |
410 | 441 |
411 def _key_for(self, id): | 442 def _key_for(self, id): |