1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
|
# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
# pylint: disable-msg=E0211,E0213
from lazr.enum import (
EnumeratedType,
Item,
)
from zope.interface import (
Attribute,
Interface,
)
from zope.schema import (
Bool,
Choice,
Int,
List,
Object,
Text,
)
from lp import _
from lp.translations.interfaces.pomsgid import IPOMsgID
__metaclass__ = type
__all__ = [
'IPOTMsgSet',
'POTMsgSetInIncompatibleTemplatesError',
'TranslationCreditsType',
]
class TranslationCreditsType(EnumeratedType):
"""Identify a POTMsgSet as translation credits."""
NOT_CREDITS = Item("""
Not a translation credits message
This is a standard msgid and not translation credits.
""")
GNOME = Item("""
Gnome credits message
How they do them in Gnome.
""")
KDE_EMAILS = Item("""
KDE emails credits message
How they do them in KDE for translator emails.
""")
KDE_NAMES = Item("""
KDE names credits message
How they do them in KDE for translator names.
""")
class POTMsgSetInIncompatibleTemplatesError(Exception):
"""Raised when a POTMsgSet appears in multiple incompatible templates.
Two PO templates are incompatible if one uses English strings for msgids,
and another doesn't (i.e. it uses English translation instead).
"""
class IPOTMsgSet(Interface):
"""A collection of message IDs."""
id = Int(
title=_("The identifier of this POTMsgSet."),
readonly=True, required=True)
context = Text(
title=u"String used to disambiguate messages with identical msgids.")
msgid_singular = Object(
title=_("The singular msgid for this message."),
description=_("""
A message ID along with the context uniquely identifies the
template message.
"""), readonly=True, required=True, schema=IPOMsgID)
msgid_plural = Object(
title=u"The plural msgid for this message.",
description=(u"Provides a plural msgid for the message. "
u"If it's not a plural form message, this value"
u"should be None."),
required=True,
readonly=True,
schema=IPOMsgID)
commenttext = Attribute("The manual comments this set has.")
filereferences = Attribute("The files where this set appears.")
sourcecomment = Attribute("The source code comments this set has.")
flagscomment = Attribute("The flags this set has.")
flags = Attribute("List of flags that apply to this message.")
singular_text = Text(
title=_("The singular text for this message."), readonly=True)
plural_text = Text(
title=_("The plural text for this message or None."), readonly=True)
uses_english_msgids = Bool(
title=_("Uses English strings as msgids"), readonly=True,
description=_("""
Some formats, such as Mozilla's XPI, use symbolic msgids where
gettext uses the original English strings to identify messages.
"""))
credits_message_ids = List(
title=_("List of possible msgids for translation credits"),
readonly=True,
description=_("""
This class attribute is intended to be used to construct database
queries that search for credits messages.
"""))
def clone():
"""Return a new copy of this POTMsgSet."""
def getCurrentTranslationMessageOrDummy(pofile):
"""Return the current `TranslationMessage`, or a dummy.
:param pofile: PO template you want a translation message for.
:return: The current translation for `self` in `pofile`, if
there is one. Otherwise, a `DummyTranslationMessage` for
`self` in `pofile`.
"""
def getOtherTranslation(language, side):
"""Returns the TranslationMessage that is current on the other side.
:param language: The language in which to find the message.
:param side: The side from which this message is seen.
"""
def getSharedTranslation(language, side):
"""Returns a shared TranslationMessage.
:param language: The language in which to find the message.
:param side: The side from which this message is seen.
"""
def getLocalTranslationMessages(potemplate, language,
include_dismissed=False,
include_unreviewed=True):
"""Return all local unused translation messages for the POTMsgSet.
Unused are those which are not current or imported, and local are
those which are directly attached to this POTMsgSet.
:param language: language we want translations for.
:param include_dismissed: Also return those translation messages
that have a creation date older than the review date of the current
message (== have been dismissed).
:param include_unreviewed: Also return those translation messages
that have a creation date newer than the review date of the current
message (== that are unreviewed). This is the default.
"""
def getExternallyUsedTranslationMessages(language):
"""Find externally used translations for the same message.
This is used to find suggestions for translating this
`POTMsgSet` that are actually used (i.e. current or imported) in
other templates.
The suggestions are read-only; they come from the slave store.
:param language: language we want translations for.
"""
def getExternallySuggestedTranslationMessages(language):
"""Find externally suggested translations for the same message.
This is used to find suggestions for translating this
`POTMsgSet` that were entered in another context, but for the
same English text, and are not in actual use.
The suggestions are read-only; they come from the slave store.
:param language: language we want translations for.
"""
def getExternallySuggestedOrUsedTranslationMessages(
suggested_languages=(), used_languages=()):
"""Find externally suggested/used translations for the same message.
This returns a mapping: language -> namedtuple (suggested, used)
containing the results of
self.getExternallySuggestedTranslationMessages and
self.getExternallyUsedTranslationMessages for each language.
:param suggested_languages: languages we want suggestions for.
:param used_languages: languges we want used messages for.
"""
def hasTranslationChangedInLaunchpad(potemplate, language):
"""Whether an imported translation differs from the current one.
:param potemplate: potemplate we are asking about.
:param language: language for which translations we are asking about.
There has to be an imported translation: if there isn't, this is
not a 'changed' translation, just a 'new' translation in Launchpad.
"""
def isTranslationNewerThan(pofile, timestamp):
"""Whether a current translation is newer than the `timestamp`.
:param pofile: translation file for which translations we are asking
about.
:param timestamp: a timestamp we are comparing to.
Returns True if there is a current and newer translation, and False
otherwise.
"""
def validateTranslations(translations):
"""Validate `translations` against gettext.
:param translations: A dict mapping plural forms to translated
strings.
:raises GettextValidationError: if there is a problem with the
translations.
"""
def submitSuggestion(pofile, submitter, new_translations,
from_import=False):
"""Submit a suggested translation for this message.
If an identical message is already present, it will be returned
(and it is not changed). Otherwise, a new one is created and
returned. Suggestions for translation credits messages are
ignored, and None is returned in that case.
Setting from_import to true will prevent karma assignment and
set the origin of the created message to SCM instead of
ROSETTAWEB.
"""
def dismissAllSuggestions(pofile, reviewer, lock_timestamp):
"""Dismiss all suggestions for the given pofile.
:param pofile: a `POFile` to dismiss suggestions from.
:param reviewer: the person that is doing the dismissal.
:param lock_timestamp: the timestamp when we checked the values we
want to update.
If a translation conflict is detected, TranslationConflict is raised.
"""
def getCurrentTranslation(potemplate, language, side):
"""Get a current translation message.
:param potemplate: An `IPOTemplate` to look up a translation for.
If it's None, ignore diverged translations.
:param language: translation should be to this `ILanguage`.
:param side: translation side to look at. (A `TranslationSide` value)
"""
def setCurrentTranslation(pofile, submitter, translations, origin,
share_with_other_side=False,
lock_timestamp=None):
"""Set the message's translation in Ubuntu, or upstream, or both.
:param pofile: `POFile` you're setting translations in. Other
`POFiles` that share translations with this one may also be
affected.
:param submitter: `Person` who is setting these translations.
:param translations: a dict mapping plural-form numbers to the
translated string for that form.
:param origin: A `RosettaTranslationOrigin`.
:param share_with_other_side: When sharing this translation,
share it with the other `TranslationSide` as well.
:param lock_timestamp: Timestamp of the original translation state
that this change is based on.
"""
def resetCurrentTranslation(pofile, lock_timestamp=None,
share_with_other_side=False):
"""Turn the current translation back into a suggestion.
This deactivates the message's current translation. The message
becomes untranslated or, if it was diverged, reverts to its
shared translation.
The previously current translation becomes visible as a new
suggestion again, as do all suggestions that came after it.
:param pofile: The `POFile` to make the change in.
:param lock_timestamp: Timestamp of the original translation state
that this change is based on.
:param share_with_other_side: Make the same change on the other
translation side.
"""
def clearCurrentTranslation(pofile, submitter, origin,
share_with_other_side=False,
lock_timestamp=None):
"""Set the current message in `pofile` to be untranslated.
If the current message is shared, this will also clear it in
other translations that share the same message.
:param pofile: The translation file that should have its current
translation for this `POTMsgSet` cleared. If the message is
shared, this may not be the only translation file that will
be affected.
:param submitter: The person responsible for clearing the message.
:param origin: `RosettaTranslationOrigin`.
:param share_with_other_side: If the current message is also
current on the other side (i.e. the Ubuntu side if working
upstream, or vice versa) then should it be cleared there as
well?
:param lock_timestamp: Timestamp of the original translation state
that this change is based on.
"""
hide_translations_from_anonymous = Attribute(
"""Whether the translations for this message should be hidden.
Messages that are likely to contain email addresses
are shown only to logged-in users, and not to anonymous users.
""")
is_translation_credit = Attribute(
"""Whether this is a message set for crediting translators.""")
translation_credits_type = Choice(
title=u"The type of translation credit of this message.",
required=True,
vocabulary=TranslationCreditsType)
def makeHTMLID(suffix=None):
"""Unique name for this `POTMsgSet` for use in HTML element ids.
The name is an underscore-separated sequence of:
* the string 'msgset'
* unpadded, numerical `id`
* optional caller-supplied suffix.
:param suffix: an optional suffix to be appended. Must be suitable
for use in HTML element ids.
"""
def updatePluralForm(plural_form_text):
"""Update plural form text for this message.
:param plural_form_text: Unicode string representing the plural form
we want to store or None to unset current plural form.
"""
def getSequence(potemplate):
"""Return the sequence number for this potmsgset in potemplate.
:param potemplate: `IPOTemplate` where the sequence number applies.
"""
def setSequence(potemplate, sequence):
"""Set the sequence number for this potmsgset in potemplate.
:param potemplate: `IPOTemplate` where the sequence number applies.
:param sequence: The sequence number of this `IPOTMsgSet` in the given
`IPOTemplate`.
"""
def setTranslationCreditsToTranslated(pofile):
"""Set the current translation for this translation credits message.
Sets a fixed dummy string as the current translation, if this is a
translation credits message, so that these get counted as
'translated', too.
Credits messages that already have a translation, imported messages
and normal messages are left untouched.
:param pofile: the POFile to set this translation in.
"""
def getAllTranslationMessages():
"""Retrieve all `TranslationMessage`s for this `POTMsgSet`."""
def getAllTranslationTemplateItems():
"""Retrieve all `TranslationTemplateItem`s for this `POTMsgSet`."""
|