Mercurial > babel > old > mirror
annotate babel/messages/catalog.py @ 71:b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
author | cmlenz |
---|---|
date | Fri, 08 Jun 2007 16:16:08 +0000 |
parents | 620fdd25657a |
children | f5a6bf38df89 |
rev | line source |
---|---|
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
2 # |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
3 # Copyright (C) 2007 Edgewall Software |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
4 # All rights reserved. |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
5 # |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
6 # This software is licensed as described in the file COPYING, which |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
7 # you should have received as part of this distribution. The terms |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
8 # are also available at http://babel.edgewall.org/wiki/License. |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
9 # |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
10 # This software consists of voluntary contributions made by many |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
11 # individuals. For the exact contribution history, see the revision |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
12 # history and logs, available at http://babel.edgewall.org/log/. |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
13 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
14 """Data structures for message catalogs.""" |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
15 |
69 | 16 from datetime import datetime |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
17 import re |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
18 try: |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
19 set |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
20 except NameError: |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
21 from sets import Set as set |
69 | 22 import time |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
23 |
69 | 24 from babel import __version__ as VERSION |
66 | 25 from babel.core import Locale |
69 | 26 from babel.messages.plurals import PLURALS |
27 from babel.util import odict, UTC | |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
28 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
29 __all__ = ['Message', 'Catalog'] |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
30 __docformat__ = 'restructuredtext en' |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
31 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
32 PYTHON_FORMAT = re.compile(r'\%(\([\w]+\))?[diouxXeEfFgGcrs]').search |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
33 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
34 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
35 class Message(object): |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
36 """Representation of a single message in a catalog.""" |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
37 |
70 | 38 def __init__(self, id, string='', locations=(), flags=()): |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
39 """Create the message object. |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
40 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
41 :param id: the message ID, or a ``(singular, plural)`` tuple for |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
42 pluralizable messages |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
43 :param string: the translated message string, or a |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
44 ``(singular, plural)`` tuple for pluralizable messages |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
45 :param locations: a sequence of ``(filenname, lineno)`` tuples |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
46 :param flags: a set or sequence of flags |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
47 """ |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
48 self.id = id |
70 | 49 if not string and self.pluralizable: |
50 string = (u'', u'') | |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
51 self.string = string |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
52 self.locations = locations |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
53 self.flags = set(flags) |
69 | 54 if id and self.python_format: |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
55 self.flags.add('python-format') |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
56 else: |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
57 self.flags.discard('python-format') |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
58 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
59 def __repr__(self): |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
60 return '<%s %r>' % (type(self).__name__, self.id) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
61 |
69 | 62 def fuzzy(self): |
63 return 'fuzzy' in self.flags | |
64 fuzzy = property(fuzzy, doc="""\ | |
65 Whether the translation is fuzzy. | |
66 | |
67 >>> Message('foo').fuzzy | |
68 False | |
69 >>> Message('foo', 'foo', flags=['fuzzy']).fuzzy | |
70 True | |
71 | |
72 :type: `bool` | |
73 """) | |
74 | |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
75 def pluralizable(self): |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
76 return isinstance(self.id, (list, tuple)) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
77 pluralizable = property(pluralizable, doc="""\ |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
78 Whether the message is plurizable. |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
79 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
80 >>> Message('foo').pluralizable |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
81 False |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
82 >>> Message(('foo', 'bar')).pluralizable |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
83 True |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
84 |
63
a60ecd4a4954
Move `Translations` and `LazyProxy` to new `babel.support` module, which should contain any convenience code that is useful for applications using Babel/I18n, but not used by Babel itself.
cmlenz
parents:
58
diff
changeset
|
85 :type: `bool` |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
86 """) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
87 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
88 def python_format(self): |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
89 ids = self.id |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
90 if not isinstance(ids, (list, tuple)): |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
91 ids = [ids] |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
92 return bool(filter(None, [PYTHON_FORMAT(id) for id in ids])) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
93 python_format = property(python_format, doc="""\ |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
94 Whether the message contains Python-style parameters. |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
95 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
96 >>> Message('foo %(name)s bar').python_format |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
97 True |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
98 >>> Message(('foo %(name)s', 'foo %(name)s')).python_format |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
99 True |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
100 |
63
a60ecd4a4954
Move `Translations` and `LazyProxy` to new `babel.support` module, which should contain any convenience code that is useful for applications using Babel/I18n, but not used by Babel itself.
cmlenz
parents:
58
diff
changeset
|
101 :type: `bool` |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
102 """) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
103 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
104 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
105 class Catalog(object): |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
106 """Representation a message catalog.""" |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
107 |
69 | 108 def __init__(self, locale=None, domain=None, project=None, version=None, |
70 | 109 creation_date=None, revision_date=None, last_translator=None, |
110 charset='utf-8'): | |
66 | 111 """Initialize the catalog object. |
112 | |
113 :param domain: the message domain | |
114 :param locale: the locale identifier or `Locale` object, or `None` | |
115 if the catalog is not bound to a locale (which basically | |
116 means it's a template) | |
117 """ | |
118 self.domain = domain #: the message domain | |
119 if locale: | |
120 locale = Locale.parse(locale) | |
121 self.locale = locale #: the locale or `None` | |
69 | 122 self._messages = odict() |
123 | |
124 self.project = project or 'PROJECT' #: the project name | |
125 self.version = version or 'VERSION' #: the project version | |
126 | |
127 if creation_date is None: | |
128 creation_date = time.localtime() | |
129 elif isinstance(creation_date, datetime): | |
130 if creation_date.tzinfo is None: | |
131 creation_date = creation_date.replace(tzinfo=UTC) | |
132 creation_date = creation_date.timetuple() | |
133 self.creation_date = creation_date #: creation date of the template | |
134 if revision_date is None: | |
135 revision_date = time.localtime() | |
136 elif isinstance(revision_date, datetime): | |
137 if revision_date.tzinfo is None: | |
138 revision_date = revision_date.replace(tzinfo=UTC) | |
139 revision_date = revision_date.timetuple() | |
140 self.revision_date = revision_date #: last revision date of the catalog | |
141 self.last_translator = last_translator #: last translator name + email | |
70 | 142 self.charset = charset or 'utf-8' |
69 | 143 |
144 def headers(self): | |
145 headers = [] | |
146 headers.append(('Project-Id-Version', | |
147 '%s %s' % (self.project, self.version))) | |
148 headers.append(('POT-Creation-Date', | |
149 time.strftime('%Y-%m-%d %H:%M%z', self.creation_date))) | |
150 if self.locale is None: | |
151 headers.append(('PO-Revision-Date', 'YEAR-MO-DA HO:MI+ZONE')) | |
152 headers.append(('Last-Translator', 'FULL NAME <EMAIL@ADDRESS>')) | |
153 headers.append(('Language-Team', 'LANGUAGE <LL@li.org>')) | |
154 else: | |
155 headers.append(('PO-Revision-Date', | |
156 time.strftime('%Y-%m-%d %H:%M%z', self.revision_date))) | |
157 headers.append(('Last-Translator', self.last_translator)) | |
158 headers.append(('Language-Team', '%s <LL@li.org>' % self.locale)) | |
159 headers.append(('Plural-Forms', self.plural_forms)) | |
160 headers.append(('MIME-Version', '1.0')) | |
70 | 161 headers.append(('Content-Type', |
162 'text/plain; charset=%s' % self.charset)) | |
69 | 163 headers.append(('Content-Transfer-Encoding', '8bit')) |
164 headers.append(('Generated-By', 'Babel %s' % VERSION)) | |
165 return headers | |
166 headers = property(headers, doc="""\ | |
167 The MIME headers of the catalog, used for the special ``msgid ""`` entry. | |
168 | |
169 The behavior of this property changes slightly depending on whether a locale | |
170 is set or not, the latter indicating that the catalog is actually a template | |
171 for actual translations. | |
172 | |
173 Here's an example of the output for such a catalog template: | |
174 | |
175 >>> catalog = Catalog(project='Foobar', version='1.0', | |
176 ... creation_date=datetime(1990, 4, 1, 15, 30)) | |
177 >>> for name, value in catalog.headers: | |
178 ... print '%s: %s' % (name, value) | |
179 Project-Id-Version: Foobar 1.0 | |
180 POT-Creation-Date: 1990-04-01 15:30+0000 | |
181 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE | |
182 Last-Translator: FULL NAME <EMAIL@ADDRESS> | |
183 Language-Team: LANGUAGE <LL@li.org> | |
184 Plural-Forms: nplurals=INTEGER; plural=EXPRESSION | |
185 MIME-Version: 1.0 | |
186 Content-Type: text/plain; charset=utf-8 | |
187 Content-Transfer-Encoding: 8bit | |
188 Generated-By: Babel ... | |
189 | |
190 And here's an example of the output when the locale is set: | |
191 | |
192 >>> catalog = Catalog(locale='de_DE', project='Foobar', version='1.0', | |
193 ... creation_date=datetime(1990, 4, 1, 15, 30), | |
194 ... revision_date=datetime(1990, 8, 3, 12, 0), | |
195 ... last_translator='John Doe <jd@example.com>') | |
196 >>> for name, value in catalog.headers: | |
197 ... print '%s: %s' % (name, value) | |
198 Project-Id-Version: Foobar 1.0 | |
199 POT-Creation-Date: 1990-04-01 15:30+0000 | |
200 PO-Revision-Date: 1990-08-03 12:00+0000 | |
201 Last-Translator: John Doe <jd@example.com> | |
202 Language-Team: de_DE <LL@li.org> | |
203 Plural-Forms: nplurals=2; plural=(n != 1) | |
204 MIME-Version: 1.0 | |
205 Content-Type: text/plain; charset=utf-8 | |
206 Content-Transfer-Encoding: 8bit | |
207 Generated-By: Babel ... | |
208 | |
209 :type: `list` | |
210 """) | |
211 | |
70 | 212 def num_plurals(self): |
213 num = 2 | |
214 if self.locale: | |
215 if str(self.locale) in PLURALS: | |
216 num = PLURALS[str(self.locale)][0] | |
217 elif self.locale.language in PLURALS: | |
218 num = PLURALS[self.locale.language][0] | |
219 return num | |
220 num_plurals = property(num_plurals) | |
221 | |
69 | 222 def plural_forms(self): |
223 num, expr = ('INTEGER', 'EXPRESSION') | |
224 if self.locale: | |
225 if str(self.locale) in PLURALS: | |
226 num, expr = PLURALS[str(self.locale)] | |
227 elif self.locale.language in PLURALS: | |
228 num, expr = PLURALS[self.locale.language] | |
229 return 'nplurals=%s; plural=%s' % (num, expr) | |
230 plural_forms = property(plural_forms, doc="""\ | |
231 Return the plural forms declaration for the locale. | |
232 | |
233 >>> Catalog(locale='en_US').plural_forms | |
234 'nplurals=2; plural=(n != 1)' | |
235 >>> Catalog(locale='pt_BR').plural_forms | |
236 'nplurals=2; plural=(n > 1)' | |
237 | |
238 :type: `str` | |
239 """) | |
240 | |
241 def __contains__(self, id): | |
242 """Return whether the catalog has a message with the specified ID.""" | |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
243 return self._key_for(id) in self._messages |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
244 |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
245 def __len__(self): |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
246 return len(self._messages) |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
247 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
248 def __iter__(self): |
66 | 249 """Iterates through all the entries in the catalog, in the order they |
250 were added, yielding a `Message` object for every entry. | |
251 | |
252 :rtype: ``iterator`` | |
253 """ | |
69 | 254 buf = [] |
255 for name, value in self.headers: | |
256 buf.append('%s: %s' % (name, value)) | |
257 yield Message('', '\n'.join(buf), flags=set(['fuzzy'])) | |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
258 for key in self._messages: |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
259 yield self._messages[key] |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
260 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
261 def __repr__(self): |
66 | 262 locale = '' |
263 if self.locale: | |
264 locale = ' %s' % self.locale | |
265 return '<%s %r%s>' % (type(self).__name__, self.domain, locale) | |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
266 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
267 def __delitem__(self, id): |
66 | 268 """Delete the message with the specified ID.""" |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
269 key = self._key_for(id) |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
270 if key in self._messages: |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
271 del self._messages[key] |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
272 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
273 def __getitem__(self, id): |
66 | 274 """Return the message with the specified ID. |
275 | |
276 :param id: the message ID | |
277 :return: the message with the specified ID, or `None` if no such message | |
278 is in the catalog | |
69 | 279 :rtype: `Message` |
66 | 280 """ |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
281 return self._messages.get(self._key_for(id)) |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
282 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
283 def __setitem__(self, id, message): |
66 | 284 """Add or update the message with the specified ID. |
285 | |
286 >>> catalog = Catalog() | |
287 >>> catalog[u'foo'] = Message(u'foo') | |
288 >>> catalog[u'foo'] | |
289 <Message u'foo'> | |
290 | |
291 If a message with that ID is already in the catalog, it is updated | |
292 to include the locations and flags of the new message. | |
293 | |
294 >>> catalog = Catalog() | |
295 >>> catalog[u'foo'] = Message(u'foo', locations=[('main.py', 1)]) | |
296 >>> catalog[u'foo'].locations | |
297 [('main.py', 1)] | |
298 >>> catalog[u'foo'] = Message(u'foo', locations=[('utils.py', 5)]) | |
299 >>> catalog[u'foo'].locations | |
300 [('main.py', 1), ('utils.py', 5)] | |
301 | |
302 :param id: the message ID | |
303 :param message: the `Message` object | |
304 """ | |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
305 assert isinstance(message, Message), 'expected a Message object' |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
306 key = self._key_for(id) |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
307 current = self._messages.get(key) |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
308 if current: |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
309 if message.pluralizable and not current.pluralizable: |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
310 # The new message adds pluralization |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
311 current.id = message.id |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
312 current.locations.extend(message.locations) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
313 current.flags |= message.flags |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
314 message = current |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
315 else: |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
316 if isinstance(id, (list, tuple)): |
70 | 317 assert isinstance(message.string, (list, tuple)) |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
318 self._messages[key] = message |
58
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
319 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
320 def add(self, id, string=None, locations=(), flags=()): |
66 | 321 """Add or update the message with the specified ID. |
322 | |
323 >>> catalog = Catalog() | |
324 >>> catalog.add(u'foo') | |
325 >>> catalog[u'foo'] | |
326 <Message u'foo'> | |
327 | |
328 This method simply constructs a `Message` object with the given | |
329 arguments and invokes `__setitem__` with that object. | |
330 | |
331 :param id: the message ID, or a ``(singular, plural)`` tuple for | |
332 pluralizable messages | |
333 :param string: the translated message string, or a | |
334 ``(singular, plural)`` tuple for pluralizable messages | |
335 :param locations: a sequence of ``(filenname, lineno)`` tuples | |
336 :param flags: a set or sequence of flags | |
337 """ | |
71
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
338 self[id] = Message(id, string, list(locations), flags) |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
339 |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
340 def _key_for(self, id): |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
341 """The key for a message is just the singular ID even for pluralizable |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
342 messages. |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
343 """ |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
344 key = id |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
345 if isinstance(key, (list, tuple)): |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
346 key = id[0] |
b260ffa01a2d
Message catalogs can have multiple messages with the same ID, where some of them have plural strings, and others don't. Still the same message.
cmlenz
parents:
70
diff
changeset
|
347 return key |