Mercurial > babel > old > mirror
annotate babel/messages/catalog.py @ 357:9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
author | aronacher |
---|---|
date | Tue, 17 Jun 2008 20:30:02 +0000 |
parents | ed20c467d223 |
children | 36408f068138 |
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 # |
337 | 3 # Copyright (C) 2007-2008 Edgewall Software |
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
|
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 |
151
12e5f21dfcda
Respect charset specified in PO headers in `read_po()`. Fixes #17.
cmlenz
parents:
133
diff
changeset
|
16 from cgi import parse_header |
69 | 17 from datetime import datetime |
167
533baef258bb
Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents:
165
diff
changeset
|
18 from difflib import get_close_matches |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
19 from email import message_from_string |
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
|
20 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
|
21 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
|
22 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
|
23 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
|
24 from sets import Set as set |
69 | 25 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
|
26 |
69 | 27 from babel import __version__ as VERSION |
66 | 28 from babel.core import Locale |
133
9d58665d134c
Use `dates.format_datetime` for dates in PO(T) header, as `datetime.strftime` produces wrong results on windows.
cmlenz
parents:
123
diff
changeset
|
29 from babel.dates import format_datetime |
69 | 30 from babel.messages.plurals import PLURALS |
356 | 31 from babel.util import odict, distinct, LOCALTZ, UTC, FixedOffsetTimezone |
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
|
32 |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
33 __all__ = ['Message', 'Catalog', 'TranslationError'] |
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
|
34 __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
|
35 |
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 |
356 | 37 PYTHON_FORMAT = re.compile(r'''(?x) |
38 \% | |
39 (?:\(([\w]*)\))? | |
40 ( | |
41 [-#0\ +]?(?:\*|[\d]+)? | |
42 (?:\.(?:\*|[\d]+))? | |
43 [hlL]? | |
44 ) | |
45 ([diouxXeEfFgGcrs%]) | |
46 ''') | |
47 | |
48 | |
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
|
49 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
|
50 """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
|
51 |
151
12e5f21dfcda
Respect charset specified in PO headers in `read_po()`. Fixes #17.
cmlenz
parents:
133
diff
changeset
|
52 def __init__(self, id, string=u'', locations=(), flags=(), auto_comments=(), |
337 | 53 user_comments=(), previous_id=(), lineno=None, context=None): |
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
|
54 """Create the message object. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
55 |
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
|
56 :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
|
57 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
|
58 :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
|
59 ``(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
|
60 :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
|
61 :param flags: a set or sequence of flags |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
62 :param auto_comments: a sequence of automatic comments for the message |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
63 :param user_comments: a sequence of user comments for the message |
205 | 64 :param previous_id: the previous message ID, or a ``(singular, plural)`` |
65 tuple for pluralizable messages | |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
66 :param lineno: the line number on which the msgid line was found in the |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
67 PO file, if any |
337 | 68 :param context: the message context |
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
|
69 """ |
109 | 70 self.id = id #: The message ID |
70 | 71 if not string and self.pluralizable: |
72 string = (u'', u'') | |
109 | 73 self.string = string #: The message translation |
231 | 74 self.locations = list(distinct(locations)) |
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 self.flags = set(flags) |
69 | 76 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
|
77 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
|
78 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
|
79 self.flags.discard('python-format') |
229 | 80 self.auto_comments = list(distinct(auto_comments)) |
81 self.user_comments = list(distinct(user_comments)) | |
205 | 82 if isinstance(previous_id, basestring): |
83 self.previous_id = [previous_id] | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
84 else: |
205 | 85 self.previous_id = list(previous_id) |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
86 self.lineno = lineno |
337 | 87 self.context = context |
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
|
88 |
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 def __repr__(self): |
198
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
90 return '<%s %r (flags: %r)>' % (type(self).__name__, self.id, |
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
91 list(self.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
|
92 |
250
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
93 def __cmp__(self, obj): |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
94 """Compare Messages, taking into account plural ids""" |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
95 if isinstance(obj, Message): |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
96 plural = self.pluralizable |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
97 obj_plural = obj.pluralizable |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
98 if plural and obj_plural: |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
99 return cmp(self.id[0], obj.id[0]) |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
100 elif plural: |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
101 return cmp(self.id[0], obj.id) |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
102 elif obj_plural: |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
103 return cmp(self.id, obj.id[0]) |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
104 return cmp(self.id, obj.id) |
194f927d8c5a
add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents:
231
diff
changeset
|
105 |
315
654b632e5482
Merging catalogs would sometimes mix translations from different runs.
cmlenz
parents:
314
diff
changeset
|
106 def clone(self): |
654b632e5482
Merging catalogs would sometimes mix translations from different runs.
cmlenz
parents:
314
diff
changeset
|
107 return Message(self.id, self.string, self.locations, self.flags, |
654b632e5482
Merging catalogs would sometimes mix translations from different runs.
cmlenz
parents:
314
diff
changeset
|
108 self.auto_comments, self.user_comments, |
337 | 109 self.previous_id, self.lineno, self.context) |
315
654b632e5482
Merging catalogs would sometimes mix translations from different runs.
cmlenz
parents:
314
diff
changeset
|
110 |
357
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
111 def check(self, catalog=None): |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
112 """Run various validation checks on the message. Some validations |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
113 are only performed if the catalog is provided. This method returns |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
114 a sequence of `TranslationError` objects. |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
115 |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
116 :rtype: ``iterator`` |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
117 :param catalog: A catalog instance that is passed to the checkers |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
118 :see: `Catalog.check` for a way to perform checks for all messages |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
119 in a catalog. |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
120 """ |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
121 from babel.messages.checkers import checkers |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
122 errors = [] |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
123 for checker in checkers: |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
124 try: |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
125 checker(catalog, self) |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
126 except TranslationError, e: |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
127 errors.append(e) |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
128 return errors |
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
129 |
69 | 130 def fuzzy(self): |
131 return 'fuzzy' in self.flags | |
132 fuzzy = property(fuzzy, doc="""\ | |
133 Whether the translation is fuzzy. | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
134 |
69 | 135 >>> Message('foo').fuzzy |
136 False | |
177
47f6c31e9a24
Changed the `__repr__` output to include the flags(it can be changed back, but it was usefull to implement the fuzzy header parsing).
palgarvio
parents:
167
diff
changeset
|
137 >>> msg = Message('foo', 'foo', flags=['fuzzy']) |
47f6c31e9a24
Changed the `__repr__` output to include the flags(it can be changed back, but it was usefull to implement the fuzzy header parsing).
palgarvio
parents:
167
diff
changeset
|
138 >>> msg.fuzzy |
69 | 139 True |
177
47f6c31e9a24
Changed the `__repr__` output to include the flags(it can be changed back, but it was usefull to implement the fuzzy header parsing).
palgarvio
parents:
167
diff
changeset
|
140 >>> msg |
198
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
141 <Message 'foo' (flags: ['fuzzy'])> |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
142 |
69 | 143 :type: `bool` |
144 """) | |
145 | |
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
|
146 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
|
147 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
|
148 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
|
149 Whether the message is plurizable. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
150 |
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
|
151 >>> 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
|
152 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
|
153 >>> 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
|
154 True |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
155 |
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
|
156 :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
|
157 """) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
158 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
159 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
|
160 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
|
161 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
|
162 ids = [ids] |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
163 return bool(filter(None, [PYTHON_FORMAT.search(id) for id in ids])) |
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
|
164 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
|
165 Whether the message contains Python-style parameters. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
166 |
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
|
167 >>> 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
|
168 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
|
169 >>> 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
|
170 True |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
171 |
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
|
172 :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
|
173 """) |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
174 |
107
4b42e23644e5
`Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents:
106
diff
changeset
|
175 |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
176 class TranslationError(Exception): |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
177 """Exception thrown by translation checkers when invalid message |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
178 translations are encountered.""" |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
179 |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
180 |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
181 DEFAULT_HEADER = u"""\ |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
182 # Translations template for PROJECT. |
122 | 183 # Copyright (C) YEAR ORGANIZATION |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
184 # This file is distributed under the same license as the PROJECT project. |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
185 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
186 #""" |
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
|
187 |
198
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
188 |
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
|
189 class Catalog(object): |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
190 """Representation of a message catalog.""" |
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
|
191 |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
192 def __init__(self, locale=None, domain=None, header_comment=DEFAULT_HEADER, |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
193 project=None, version=None, copyright_holder=None, |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
194 msgid_bugs_address=None, creation_date=None, |
208
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
195 revision_date=None, last_translator=None, language_team=None, |
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
196 charset='utf-8', fuzzy=True): |
66 | 197 """Initialize the catalog object. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
198 |
66 | 199 :param locale: the locale identifier or `Locale` object, or `None` |
200 if the catalog is not bound to a locale (which basically | |
201 means it's a template) | |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
202 :param domain: the message domain |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
203 :param header_comment: the header comment as string, or `None` for the |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
204 default header |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
205 :param project: the project's name |
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
206 :param version: the project's version |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
207 :param copyright_holder: the copyright holder of the catalog |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
208 :param msgid_bugs_address: the email address or URL to submit bug |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
209 reports to |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
210 :param creation_date: the date the catalog was created |
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
211 :param revision_date: the date the catalog was revised |
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
212 :param last_translator: the name and email of the last translator |
208
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
213 :param language_team: the name and email of the language team |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
214 :param charset: the encoding to use in the output |
177
47f6c31e9a24
Changed the `__repr__` output to include the flags(it can be changed back, but it was usefull to implement the fuzzy header parsing).
palgarvio
parents:
167
diff
changeset
|
215 :param fuzzy: the fuzzy bit on the catalog header |
66 | 216 """ |
109 | 217 self.domain = domain #: The message domain |
66 | 218 if locale: |
219 locale = Locale.parse(locale) | |
109 | 220 self.locale = locale #: The locale or `None` |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
221 self._header_comment = header_comment |
69 | 222 self._messages = odict() |
223 | |
109 | 224 self.project = project or 'PROJECT' #: The project name |
225 self.version = version or 'VERSION' #: The project version | |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
226 self.copyright_holder = copyright_holder or 'ORGANIZATION' |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
227 self.msgid_bugs_address = msgid_bugs_address or 'EMAIL@ADDRESS' |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
228 |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
229 self.last_translator = last_translator or 'FULL NAME <EMAIL@ADDRESS>' |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
230 """Name and email address of the last translator.""" |
208
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
231 self.language_team = language_team or 'LANGUAGE <LL@li.org>' |
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
232 """Name and email address of the language team.""" |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
233 |
97
debd9ac3bb4d
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
89
diff
changeset
|
234 self.charset = charset or 'utf-8' |
86
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
235 |
69 | 236 if creation_date is None: |
99 | 237 creation_date = datetime.now(LOCALTZ) |
97
debd9ac3bb4d
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
89
diff
changeset
|
238 elif isinstance(creation_date, datetime) and not creation_date.tzinfo: |
99 | 239 creation_date = creation_date.replace(tzinfo=LOCALTZ) |
109 | 240 self.creation_date = creation_date #: Creation date of the template |
69 | 241 if revision_date is None: |
99 | 242 revision_date = datetime.now(LOCALTZ) |
97
debd9ac3bb4d
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
89
diff
changeset
|
243 elif isinstance(revision_date, datetime) and not revision_date.tzinfo: |
99 | 244 revision_date = revision_date.replace(tzinfo=LOCALTZ) |
109 | 245 self.revision_date = revision_date #: Last revision date of the catalog |
183
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
246 self.fuzzy = fuzzy #: Catalog header fuzzy bit (`True` or `False`) |
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
247 |
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
248 self.obsolete = odict() #: Dictionary of obsolete messages |
335
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
249 self._num_plurals = None |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
250 self._plural_expr = None |
69 | 251 |
109 | 252 def _get_header_comment(self): |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
253 comment = self._header_comment |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
254 comment = comment.replace('PROJECT', self.project) \ |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
255 .replace('VERSION', self.version) \ |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
256 .replace('YEAR', self.revision_date.strftime('%Y')) \ |
122 | 257 .replace('ORGANIZATION', self.copyright_holder) |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
258 if self.locale: |
109 | 259 comment = comment.replace('Translations template', '%s translations' |
260 % self.locale.english_name) | |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
261 return comment |
122 | 262 |
109 | 263 def _set_header_comment(self, string): |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
264 self._header_comment = string |
109 | 265 |
266 header_comment = property(_get_header_comment, _set_header_comment, doc="""\ | |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
267 The header comment for the catalog. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
268 |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
269 >>> catalog = Catalog(project='Foobar', version='1.0', |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
270 ... copyright_holder='Foo Company') |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
271 >>> print catalog.header_comment #doctest: +ELLIPSIS |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
272 # Translations template for Foobar. |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
273 # Copyright (C) ... Foo Company |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
274 # This file is distributed under the same license as the Foobar project. |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
275 # FIRST AUTHOR <EMAIL@ADDRESS>, .... |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
276 # |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
277 |
122 | 278 The header can also be set from a string. Any known upper-case variables |
279 will be replaced when the header is retrieved again: | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
280 |
122 | 281 >>> catalog = Catalog(project='Foobar', version='1.0', |
282 ... copyright_holder='Foo Company') | |
283 >>> catalog.header_comment = '''\\ | |
284 ... # The POT for my really cool PROJECT project. | |
285 ... # Copyright (C) 1990-2003 ORGANIZATION | |
286 ... # This file is distributed under the same license as the PROJECT | |
287 ... # project. | |
288 ... #''' | |
289 >>> print catalog.header_comment | |
290 # The POT for my really cool Foobar project. | |
291 # Copyright (C) 1990-2003 Foo Company | |
292 # This file is distributed under the same license as the Foobar | |
293 # project. | |
294 # | |
295 | |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
296 :type: `unicode` |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
297 """) |
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
298 |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
299 def _get_mime_headers(self): |
69 | 300 headers = [] |
301 headers.append(('Project-Id-Version', | |
302 '%s %s' % (self.project, self.version))) | |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
303 headers.append(('Report-Msgid-Bugs-To', self.msgid_bugs_address)) |
69 | 304 headers.append(('POT-Creation-Date', |
133
9d58665d134c
Use `dates.format_datetime` for dates in PO(T) header, as `datetime.strftime` produces wrong results on windows.
cmlenz
parents:
123
diff
changeset
|
305 format_datetime(self.creation_date, 'yyyy-MM-dd HH:mmZ', |
9d58665d134c
Use `dates.format_datetime` for dates in PO(T) header, as `datetime.strftime` produces wrong results on windows.
cmlenz
parents:
123
diff
changeset
|
306 locale='en'))) |
69 | 307 if self.locale is None: |
308 headers.append(('PO-Revision-Date', 'YEAR-MO-DA HO:MI+ZONE')) | |
309 headers.append(('Last-Translator', 'FULL NAME <EMAIL@ADDRESS>')) | |
310 headers.append(('Language-Team', 'LANGUAGE <LL@li.org>')) | |
311 else: | |
312 headers.append(('PO-Revision-Date', | |
133
9d58665d134c
Use `dates.format_datetime` for dates in PO(T) header, as `datetime.strftime` produces wrong results on windows.
cmlenz
parents:
123
diff
changeset
|
313 format_datetime(self.revision_date, |
9d58665d134c
Use `dates.format_datetime` for dates in PO(T) header, as `datetime.strftime` produces wrong results on windows.
cmlenz
parents:
123
diff
changeset
|
314 'yyyy-MM-dd HH:mmZ', locale='en'))) |
69 | 315 headers.append(('Last-Translator', self.last_translator)) |
208
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
316 headers.append(('Language-Team', |
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
317 self.language_team.replace('LANGUAGE', |
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
318 str(self.locale)))) |
86
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
319 headers.append(('Plural-Forms', self.plural_forms)) |
69 | 320 headers.append(('MIME-Version', '1.0')) |
70 | 321 headers.append(('Content-Type', |
322 'text/plain; charset=%s' % self.charset)) | |
69 | 323 headers.append(('Content-Transfer-Encoding', '8bit')) |
107
4b42e23644e5
`Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents:
106
diff
changeset
|
324 headers.append(('Generated-By', 'Babel %s\n' % VERSION)) |
69 | 325 return headers |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
326 |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
327 def _set_mime_headers(self, headers): |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
328 for name, value in headers: |
293 | 329 if name.lower() == 'content-type': |
212
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
330 mimetype, params = parse_header(value) |
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
331 if 'charset' in params: |
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
332 self.charset = params['charset'].lower() |
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
333 break |
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
334 for name, value in headers: |
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
335 name = name.lower().decode(self.charset) |
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
336 value = value.decode(self.charset) |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
337 if name == 'project-id-version': |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
338 parts = value.split(' ') |
212
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
339 self.project = u' '.join(parts[:-1]) |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
340 self.version = parts[-1] |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
341 elif name == 'report-msgid-bugs-to': |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
342 self.msgid_bugs_address = value |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
343 elif name == 'last-translator': |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
344 self.last_translator = value |
208
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
345 elif name == 'language-team': |
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
346 self.language_team = value |
335
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
347 elif name == 'plural-forms': |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
348 _, params = parse_header(' ;' + value) |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
349 self._num_plurals = int(params.get('nplurals', 2)) |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
350 self._plural_expr = params.get('plural', '(n != 1)') |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
351 elif name == 'pot-creation-date': |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
352 # FIXME: this should use dates.parse_datetime as soon as that |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
353 # is ready |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
354 value, tzoffset, _ = re.split('[+-](\d{4})$', value, 1) |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
355 tt = time.strptime(value, '%Y-%m-%d %H:%M') |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
356 ts = time.mktime(tt) |
122 | 357 tzoffset = FixedOffsetTimezone(int(tzoffset[:2]) * 60 + |
358 int(tzoffset[2:])) | |
123 | 359 dt = datetime.fromtimestamp(ts) |
360 self.creation_date = dt.replace(tzinfo=tzoffset) | |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
361 |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
362 mime_headers = property(_get_mime_headers, _set_mime_headers, doc="""\ |
69 | 363 The MIME headers of the catalog, used for the special ``msgid ""`` entry. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
364 |
69 | 365 The behavior of this property changes slightly depending on whether a locale |
366 is set or not, the latter indicating that the catalog is actually a template | |
367 for actual translations. | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
368 |
69 | 369 Here's an example of the output for such a catalog template: |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
370 |
97
debd9ac3bb4d
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
89
diff
changeset
|
371 >>> created = datetime(1990, 4, 1, 15, 30, tzinfo=UTC) |
69 | 372 >>> catalog = Catalog(project='Foobar', version='1.0', |
97
debd9ac3bb4d
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
89
diff
changeset
|
373 ... creation_date=created) |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
374 >>> for name, value in catalog.mime_headers: |
69 | 375 ... print '%s: %s' % (name, value) |
376 Project-Id-Version: Foobar 1.0 | |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
377 Report-Msgid-Bugs-To: EMAIL@ADDRESS |
69 | 378 POT-Creation-Date: 1990-04-01 15:30+0000 |
379 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE | |
380 Last-Translator: FULL NAME <EMAIL@ADDRESS> | |
381 Language-Team: LANGUAGE <LL@li.org> | |
382 MIME-Version: 1.0 | |
383 Content-Type: text/plain; charset=utf-8 | |
384 Content-Transfer-Encoding: 8bit | |
385 Generated-By: Babel ... | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
386 |
69 | 387 And here's an example of the output when the locale is set: |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
388 |
97
debd9ac3bb4d
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
89
diff
changeset
|
389 >>> revised = datetime(1990, 8, 3, 12, 0, tzinfo=UTC) |
69 | 390 >>> catalog = Catalog(locale='de_DE', project='Foobar', version='1.0', |
97
debd9ac3bb4d
Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents:
89
diff
changeset
|
391 ... creation_date=created, revision_date=revised, |
208
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
392 ... last_translator='John Doe <jd@example.com>', |
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
393 ... language_team='de_DE <de@example.com>') |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
394 >>> for name, value in catalog.mime_headers: |
69 | 395 ... print '%s: %s' % (name, value) |
396 Project-Id-Version: Foobar 1.0 | |
80
8e2e9d549693
Fixed the plurals header on `Catalog` which should only be written if it's not a catalog template.
palgarvio
parents:
72
diff
changeset
|
397 Report-Msgid-Bugs-To: EMAIL@ADDRESS |
69 | 398 POT-Creation-Date: 1990-04-01 15:30+0000 |
399 PO-Revision-Date: 1990-08-03 12:00+0000 | |
400 Last-Translator: John Doe <jd@example.com> | |
208
6cd31048eb5c
Preserve language-team header in catalogs on update. Closes #35 again.
cmlenz
parents:
205
diff
changeset
|
401 Language-Team: de_DE <de@example.com> |
86
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
402 Plural-Forms: nplurals=2; plural=(n != 1) |
69 | 403 MIME-Version: 1.0 |
404 Content-Type: text/plain; charset=utf-8 | |
405 Content-Transfer-Encoding: 8bit | |
406 Generated-By: Babel ... | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
407 |
69 | 408 :type: `list` |
409 """) | |
410 | |
70 | 411 def num_plurals(self): |
335
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
412 if not self._num_plurals: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
413 num = 2 |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
414 if self.locale: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
415 if str(self.locale) in PLURALS: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
416 num = PLURALS[str(self.locale)][0] |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
417 elif self.locale.language in PLURALS: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
418 num = PLURALS[self.locale.language][0] |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
419 self._num_plurals = num |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
420 return self._num_plurals |
86
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
421 num_plurals = property(num_plurals, doc="""\ |
335
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
422 The number of plurals used by the catalog or locale. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
423 |
105
abd3a594dab4
Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents:
99
diff
changeset
|
424 >>> Catalog(locale='en').num_plurals |
abd3a594dab4
Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents:
99
diff
changeset
|
425 2 |
335
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
426 >>> Catalog(locale='ga').num_plurals |
105
abd3a594dab4
Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents:
99
diff
changeset
|
427 3 |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
428 |
105
abd3a594dab4
Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents:
99
diff
changeset
|
429 :type: `int` |
86
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
430 """) |
70 | 431 |
335
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
432 def plural_expr(self): |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
433 if not self._plural_expr: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
434 expr = '(n != 1)' |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
435 if self.locale: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
436 if str(self.locale) in PLURALS: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
437 expr = PLURALS[str(self.locale)][1] |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
438 elif self.locale.language in PLURALS: |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
439 expr = PLURALS[self.locale.language][1] |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
440 self._plural_expr = expr |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
441 return self._plural_expr |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
442 plural_expr = property(plural_expr, doc="""\ |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
443 The plural expression used by the catalog or locale. |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
444 |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
445 >>> Catalog(locale='en').plural_expr |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
446 '(n != 1)' |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
447 >>> Catalog(locale='ga').plural_expr |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
448 '(n==1 ? 0 : n==2 ? 1 : 2)' |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
449 |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
450 :type: `basestring` |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
451 """) |
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
452 |
69 | 453 def plural_forms(self): |
335
355a977c92aa
Change Catalog class to retain the plural forms set in the MIME headers.
cmlenz
parents:
315
diff
changeset
|
454 return 'nplurals=%s; plural=%s' % (self.num_plurals, self.plural_expr) |
69 | 455 plural_forms = property(plural_forms, doc="""\ |
456 Return the plural forms declaration for the locale. | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
457 |
105
abd3a594dab4
Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents:
99
diff
changeset
|
458 >>> Catalog(locale='en').plural_forms |
69 | 459 'nplurals=2; plural=(n != 1)' |
460 >>> Catalog(locale='pt_BR').plural_forms | |
461 'nplurals=2; plural=(n > 1)' | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
462 |
69 | 463 :type: `str` |
464 """) | |
465 | |
466 def __contains__(self, id): | |
467 """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
|
468 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
|
469 |
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
|
470 def __len__(self): |
86
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
471 """The number of messages in the catalog. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
472 |
86
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
473 This does not include the special ``msgid ""`` entry. |
8a703ecdba91
Some cosmetic changes for the new translator comments support.
cmlenz
parents:
82
diff
changeset
|
474 """ |
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
|
475 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
|
476 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
477 def __iter__(self): |
66 | 478 """Iterates through all the entries in the catalog, in the order they |
479 were added, yielding a `Message` object for every entry. | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
480 |
66 | 481 :rtype: ``iterator`` |
482 """ | |
69 | 483 buf = [] |
106
2a00e352c986
Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents:
105
diff
changeset
|
484 for name, value in self.mime_headers: |
69 | 485 buf.append('%s: %s' % (name, value)) |
200
2f0161df6a38
Correctly handle non-ASCII chars in the catalog MIME headers.
cmlenz
parents:
198
diff
changeset
|
486 flags = set() |
177
47f6c31e9a24
Changed the `__repr__` output to include the flags(it can be changed back, but it was usefull to implement the fuzzy header parsing).
palgarvio
parents:
167
diff
changeset
|
487 if self.fuzzy: |
200
2f0161df6a38
Correctly handle non-ASCII chars in the catalog MIME headers.
cmlenz
parents:
198
diff
changeset
|
488 flags |= set(['fuzzy']) |
212
2c00a52bc073
When parsing catalog headers, look for the content-type first, to be able to use a specified encoding on all other headers.
cmlenz
parents:
208
diff
changeset
|
489 yield Message(u'', '\n'.join(buf), flags=flags) |
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
|
490 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
|
491 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
|
492 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
493 def __repr__(self): |
66 | 494 locale = '' |
495 if self.locale: | |
496 locale = ' %s' % self.locale | |
497 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
|
498 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
499 def __delitem__(self, id): |
66 | 500 """Delete the message with the specified ID.""" |
352 | 501 self.delete(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
|
502 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
503 def __getitem__(self, id): |
66 | 504 """Return the message with the specified ID. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
505 |
66 | 506 :param id: the message ID |
352 | 507 :return: the message with the specified ID, or `None` if no such |
508 message is in the catalog | |
69 | 509 :rtype: `Message` |
66 | 510 """ |
352 | 511 return self.get(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
|
512 |
068952b4d4c0
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
513 def __setitem__(self, id, message): |
66 | 514 """Add or update the message with the specified ID. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
515 |
66 | 516 >>> catalog = Catalog() |
517 >>> catalog[u'foo'] = Message(u'foo') | |
518 >>> catalog[u'foo'] | |
198
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
519 <Message u'foo' (flags: [])> |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
520 |
66 | 521 If a message with that ID is already in the catalog, it is updated |
522 to include the locations and flags of the new message. | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
523 |
66 | 524 >>> catalog = Catalog() |
525 >>> catalog[u'foo'] = Message(u'foo', locations=[('main.py', 1)]) | |
526 >>> catalog[u'foo'].locations | |
527 [('main.py', 1)] | |
528 >>> catalog[u'foo'] = Message(u'foo', locations=[('utils.py', 5)]) | |
529 >>> catalog[u'foo'].locations | |
530 [('main.py', 1), ('utils.py', 5)] | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
531 |
66 | 532 :param id: the message ID |
533 :param message: the `Message` object | |
534 """ | |
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
|
535 assert isinstance(message, Message), 'expected a Message object' |
352 | 536 key = self._key_for(id, message.context) |
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
|
537 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
|
538 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
|
539 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
|
540 # 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
|
541 current.id = message.id |
72
f5a6bf38df89
Fix for mixed singular/plural messages, follow-up to [70].
cmlenz
parents:
71
diff
changeset
|
542 current.string = message.string |
231 | 543 current.locations = list(distinct(current.locations + |
544 message.locations)) | |
230
aaf36f409166
Follow-up to [239]: also combine duplicate comments when writing PO files.
cmlenz
parents:
229
diff
changeset
|
545 current.auto_comments = list(distinct(current.auto_comments + |
aaf36f409166
Follow-up to [239]: also combine duplicate comments when writing PO files.
cmlenz
parents:
229
diff
changeset
|
546 message.auto_comments)) |
aaf36f409166
Follow-up to [239]: also combine duplicate comments when writing PO files.
cmlenz
parents:
229
diff
changeset
|
547 current.user_comments = list(distinct(current.user_comments + |
aaf36f409166
Follow-up to [239]: also combine duplicate comments when writing PO files.
cmlenz
parents:
229
diff
changeset
|
548 message.user_comments)) |
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
|
549 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
|
550 message = current |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
551 elif id == '': |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
552 # special treatment for the header message |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
553 headers = message_from_string(message.string.encode(self.charset)) |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
554 self.mime_headers = headers.items() |
122 | 555 self.header_comment = '\n'.join(['# %s' % comment for comment |
556 in message.user_comments]) | |
198
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
557 self.fuzzy = message.fuzzy |
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
|
558 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
|
559 if isinstance(id, (list, tuple)): |
279
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
560 assert isinstance(message.string, (list, tuple)), \ |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
561 'Expected sequence but got %s' % type(message.string) |
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
|
562 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
|
563 |
107
4b42e23644e5
`Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents:
106
diff
changeset
|
564 def add(self, id, string=None, locations=(), flags=(), auto_comments=(), |
337 | 565 user_comments=(), previous_id=(), lineno=None, context=None): |
66 | 566 """Add or update the message with the specified ID. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
567 |
66 | 568 >>> catalog = Catalog() |
569 >>> catalog.add(u'foo') | |
570 >>> catalog[u'foo'] | |
198
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
571 <Message u'foo' (flags: [])> |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
572 |
66 | 573 This method simply constructs a `Message` object with the given |
574 arguments and invokes `__setitem__` with that object. | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
575 |
66 | 576 :param id: the message ID, or a ``(singular, plural)`` tuple for |
577 pluralizable messages | |
578 :param string: the translated message string, or a | |
579 ``(singular, plural)`` tuple for pluralizable messages | |
580 :param locations: a sequence of ``(filenname, lineno)`` tuples | |
581 :param flags: a set or sequence of flags | |
108
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
582 :param auto_comments: a sequence of automatic comments |
8ea225f33f28
Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents:
107
diff
changeset
|
583 :param user_comments: a sequence of user comments |
205 | 584 :param previous_id: the previous message ID, or a ``(singular, plural)`` |
585 tuple for pluralizable messages | |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
586 :param lineno: the line number on which the msgid line was found in the |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
587 PO file, if any |
337 | 588 :param context: the message context |
66 | 589 """ |
107
4b42e23644e5
`Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents:
106
diff
changeset
|
590 self[id] = Message(id, string, list(locations), flags, auto_comments, |
337 | 591 user_comments, previous_id, lineno=lineno, |
592 context=context) | |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
593 |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
594 def check(self): |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
595 """Run various validation checks on the translations in the catalog. |
228 | 596 |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
597 For every message which fails validation, this method yield a |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
598 ``(message, errors)`` tuple, where ``message`` is the `Message` object |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
599 and ``errors`` is a sequence of `TranslationError` objects. |
228 | 600 |
222
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
601 :rtype: ``iterator`` |
bd8b1301b27e
Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents:
212
diff
changeset
|
602 """ |
354
249aab27c4b3
The builtin checkers don't require setuptools any longer, validate_format and python_format from the checkers module are merged into one now.
aronacher
parents:
353
diff
changeset
|
603 for message in self._messages.values(): |
357
9acf6b5baa22
Refactored the checker system. It's now possible to partially validate translations on a per-message level.
aronacher
parents:
356
diff
changeset
|
604 errors = message.check(catalog=self) |
354
249aab27c4b3
The builtin checkers don't require setuptools any longer, validate_format and python_format from the checkers module are merged into one now.
aronacher
parents:
353
diff
changeset
|
605 if errors: |
249aab27c4b3
The builtin checkers don't require setuptools any longer, validate_format and python_format from the checkers module are merged into one now.
aronacher
parents:
353
diff
changeset
|
606 yield message, errors |
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
|
607 |
352 | 608 def get(self, id, context=None): |
609 """Return the message with the specified ID and context. | |
610 | |
611 :param id: the message ID | |
612 :param context: the message context, or ``None`` for no context | |
613 :return: the message with the specified ID, or `None` if no such | |
614 message is in the catalog | |
615 :rtype: `Message` | |
616 """ | |
617 return self._messages.get(self._key_for(id, context)) | |
618 | |
619 def delete(self, id, context=None): | |
620 """Delete the message with the specified ID and context. | |
621 | |
622 :param id: the message ID | |
623 :param context: the message context, or ``None`` for no context | |
624 """ | |
625 key = self._key_for(id, context) | |
626 if key in self._messages: | |
627 del self._messages[key] | |
628 | |
205 | 629 def update(self, template, no_fuzzy_matching=False): |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
630 """Update the catalog based on the given template catalog. |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
631 |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
632 >>> from babel.messages import Catalog |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
633 >>> template = Catalog() |
190 | 634 >>> template.add('green', locations=[('main.py', 99)]) |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
635 >>> template.add('blue', locations=[('main.py', 100)]) |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
636 >>> template.add(('salad', 'salads'), locations=[('util.py', 42)]) |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
637 >>> catalog = Catalog(locale='de_DE') |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
638 >>> catalog.add('blue', u'blau', locations=[('main.py', 98)]) |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
639 >>> catalog.add('head', u'Kopf', locations=[('util.py', 33)]) |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
640 >>> catalog.add(('salad', 'salads'), (u'Salat', u'Salate'), |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
641 ... locations=[('util.py', 38)]) |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
642 |
183
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
643 >>> catalog.update(template) |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
644 >>> len(catalog) |
190 | 645 3 |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
646 |
190 | 647 >>> msg1 = catalog['green'] |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
648 >>> msg1.string |
190 | 649 >>> msg1.locations |
650 [('main.py', 99)] | |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
651 |
190 | 652 >>> msg2 = catalog['blue'] |
653 >>> msg2.string | |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
654 u'blau' |
190 | 655 >>> msg2.locations |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
656 [('main.py', 100)] |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
657 |
190 | 658 >>> msg3 = catalog['salad'] |
659 >>> msg3.string | |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
660 (u'Salat', u'Salate') |
190 | 661 >>> msg3.locations |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
662 [('util.py', 42)] |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
663 |
183
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
664 Messages that are in the catalog but not in the template are removed |
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
665 from the main collection, but can still be accessed via the `obsolete` |
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
666 member: |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
667 |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
668 >>> 'head' in catalog |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
669 False |
183
e927dffc9ab4
The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents:
177
diff
changeset
|
670 >>> catalog.obsolete.values() |
198
982d7e704fdc
Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents:
190
diff
changeset
|
671 [<Message 'head' (flags: [])>] |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
672 |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
673 :param template: the reference catalog, usually read from a POT file |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
674 :param no_fuzzy_matching: whether to use fuzzy matching of message IDs |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
675 """ |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
676 messages = self._messages |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
677 remaining = messages.copy() |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
678 self._messages = odict() |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
679 |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
680 # Prepare for fuzzy matching |
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
681 fuzzy_candidates = [] |
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
682 if not no_fuzzy_matching: |
352 | 683 fuzzy_candidates = dict([ |
684 (self._key_for(msgid), messages[msgid].context) | |
685 for msgid in messages if msgid and messages[msgid].string | |
686 ]) | |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
687 fuzzy_matches = set() |
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
688 |
279
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
689 def _merge(message, oldkey, newkey): |
315
654b632e5482
Merging catalogs would sometimes mix translations from different runs.
cmlenz
parents:
314
diff
changeset
|
690 message = message.clone() |
279
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
691 fuzzy = False |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
692 if oldkey != newkey: |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
693 fuzzy = True |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
694 fuzzy_matches.add(oldkey) |
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
695 oldmsg = messages.get(oldkey) |
279
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
696 if isinstance(oldmsg.id, basestring): |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
697 message.previous_id = [oldmsg.id] |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
698 else: |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
699 message.previous_id = list(oldmsg.id) |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
700 else: |
339
6811369cb912
Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents:
337
diff
changeset
|
701 oldmsg = remaining.pop(oldkey, None) |
279
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
702 message.string = oldmsg.string |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
703 if isinstance(message.id, (list, tuple)): |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
704 if not isinstance(message.string, (list, tuple)): |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
705 fuzzy = True |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
706 message.string = tuple( |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
707 [message.string] + ([u''] * (len(message.id) - 1)) |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
708 ) |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
709 elif len(message.string) != len(message.id): |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
710 fuzzy = True |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
711 message.string = tuple(message.string[:len(oldmsg.string)]) |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
712 elif isinstance(message.string, (list, tuple)): |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
713 fuzzy = True |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
714 message.string = message.string[0] |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
715 message.flags |= oldmsg.flags |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
716 if fuzzy: |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
717 message.flags |= set([u'fuzzy']) |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
718 self[message.id] = message |
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
719 |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
720 for message in template: |
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
721 if message.id: |
352 | 722 key = self._key_for(message.id, message.context) |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
723 if key in messages: |
279
3308e9971fab
Fix for updating catalog messages that changed from gettext to ngettext or vice versa.
cmlenz
parents:
252
diff
changeset
|
724 _merge(message, key, key) |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
725 else: |
202
d3c272492053
Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents:
200
diff
changeset
|
726 if no_fuzzy_matching is False: |
167
533baef258bb
Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents:
165
diff
changeset
|
727 # do some fuzzy matching with difflib |
352 | 728 if isinstance(key, tuple): |
729 matchkey = key[0] # just the msgid, no context | |
730 else: | |
731 matchkey = key | |
732 matches = get_close_matches(matchkey.lower().strip(), | |
733 fuzzy_candidates.keys(), 1) | |
167
533baef258bb
Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents:
165
diff
changeset
|
734 if matches: |
352 | 735 newkey = matches[0] |
736 newctxt = fuzzy_candidates[newkey] | |
737 if newctxt is not None: | |
738 newkey = newkey, newctxt | |
739 _merge(message, newkey, key) | |
190 | 740 continue |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
741 |
167
533baef258bb
Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents:
165
diff
changeset
|
742 self[message.id] = message |
533baef258bb
Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents:
165
diff
changeset
|
743 |
314
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
744 self.obsolete = odict() |
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
745 for msgid in remaining: |
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
746 if no_fuzzy_matching or msgid not in fuzzy_matches: |
5c0bda4f20b1
Fix catalog updating with fuzzy matches. Closes #82.
cmlenz
parents:
293
diff
changeset
|
747 self.obsolete[msgid] = remaining[msgid] |
165
eafaa302dde1
Added preliminary catalog updating/merging functionality.
cmlenz
parents:
151
diff
changeset
|
748 |
352 | 749 def _key_for(self, id, context=None): |
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
|
750 """The key for a message is just the singular ID even for pluralizable |
352 | 751 messages, but is a ``(msgid, msgctxt)`` tuple for context-specific |
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
|
752 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
|
753 """ |
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
|
754 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
|
755 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
|
756 key = id[0] |
352 | 757 if context is not None: |
758 key = (key, context) | |
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
|
759 return key |