Merge lp:~jcsackett/launchpad/deprecate-official_rosetta into lp:launchpad
- deprecate-official_rosetta
- Merge into devel
Status: | Merged |
---|---|
Approved by: | j.c.sackett |
Approved revision: | no longer in the source branch. |
Merged at revision: | 11520 |
Proposed branch: | lp:~jcsackett/launchpad/deprecate-official_rosetta |
Merge into: | lp:launchpad |
Diff against target: |
3172 lines (+649/-426) 51 files modified
lib/lp/app/enums.py (+6/-1) lib/lp/registry/browser/distribution.py (+2/-1) lib/lp/registry/browser/pillar.py (+11/-8) lib/lp/registry/browser/tests/pillar-views.txt (+4/-3) lib/lp/registry/browser/tests/productseries-views.txt (+6/-4) lib/lp/registry/doc/distribution.txt (+125/-114) lib/lp/registry/doc/product.txt (+62/-44) lib/lp/registry/doc/project.txt (+24/-15) lib/lp/registry/model/projectgroup.py (+4/-1) lib/lp/testing/factory.py (+7/-4) lib/lp/translations/browser/potemplate.py (+4/-2) lib/lp/translations/browser/product.py (+11/-8) lib/lp/translations/browser/tests/language-views.txt (+4/-1) lib/lp/translations/browser/tests/test_breadcrumbs.py (+3/-2) lib/lp/translations/doc/potmsgset.txt (+59/-33) lib/lp/translations/doc/translationimportqueue.txt (+54/-25) lib/lp/translations/doc/translationmessage-destroy.txt (+10/-5) lib/lp/translations/doc/translations-export-to-branch.txt (+10/-6) lib/lp/translations/doc/translationsoverview.txt (+14/-6) lib/lp/translations/model/potemplate.py (+11/-10) lib/lp/translations/model/potmsgset.py (+8/-7) lib/lp/translations/model/translationsoverview.py (+6/-3) lib/lp/translations/model/translationsperson.py (+4/-0) lib/lp/translations/scripts/translations_to_branch.py (+3/-0) lib/lp/translations/stories/buildfarm/xx-build-summary.txt (+8/-4) lib/lp/translations/stories/importqueue/xx-entry-details.txt (+9/-5) lib/lp/translations/stories/productseries/xx-productseries-export-to-branch.txt (+9/-6) lib/lp/translations/stories/productseries/xx-productseries-translations.txt (+5/-3) lib/lp/translations/stories/standalone/custom-language-codes.txt (+5/-3) lib/lp/translations/stories/standalone/xx-potemplate-index.txt (+28/-12) lib/lp/translations/stories/standalone/xx-product-export.txt (+9/-5) lib/lp/translations/stories/standalone/xx-product-translations.txt (+0/-1) lib/lp/translations/stories/standalone/xx-template-description-escaping.txt (+3/-1) lib/lp/translations/stories/translationfocus/xx-product-translationfocus.txt (+5/-3) lib/lp/translations/stories/translationgroups/xx-change-translation-policy.txt (+5/-1) lib/lp/translations/templates/product-portlet-not-using-launchpad.pt (+1/-1) lib/lp/translations/templates/productseries-translations.pt (+1/-1) lib/lp/translations/tests/test_autoapproval.py (+9/-8) lib/lp/translations/tests/test_empty_messages.py (+13/-11) lib/lp/translations/tests/test_hastranslationtemplates.py (+5/-4) lib/lp/translations/tests/test_pofile.py (+17/-14) lib/lp/translations/tests/test_potemplate.py (+3/-2) lib/lp/translations/tests/test_potmsgset.py (+11/-8) lib/lp/translations/tests/test_productserieslanguage.py (+9/-4) lib/lp/translations/tests/test_shared_potemplate.py (+3/-2) lib/lp/translations/tests/test_suggestions.py (+10/-4) lib/lp/translations/tests/test_translatablemessage.py (+9/-7) lib/lp/translations/tests/test_translatedlanguage.py (+5/-2) lib/lp/translations/tests/test_translations_to_review.py (+6/-3) lib/lp/translations/windmill/tests/test_documentation_links.py (+2/-1) lib/lp/translations/windmill/tests/test_import_queue.py (+7/-7) |
To merge this branch: | bzr merge lp:~jcsackett/launchpad/deprecate-official_rosetta |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Leonard Richardson (community) | Approve | ||
Review via email: mp+34229@code.launchpad.net |
Commit message
Replaces use of official_rosetta with translations_usage where possible, so the richer data provided by the enum can be used to drive decisions.
Description of the change
= Summary =
Replaces, where possible, usage of official_rosetta with the translations_usage property.
== Proposed fix ==
Where code uses official_rosetta, use translations_usage instead so that we can take advantage of richer data.
== Pre-implementation notes ==
Spoke with Curtis Hovey (sinzui) and Brad Crittenden (bac).
== Implementation details ==
As in Proposed fix.
SQL queries using official_rosetta have been left alone until data migration occurs.
== Tests ==
No new tests written.
To fully test the refactor:
bin/test -m lib.lp.registry
bin/test -m lib.lp.translations
== Demo and Q/A ==
In Launchpad.dev, nothing should crash when reviewing translations or performing translation related actions.
= Launchpad lint =
This touched enough old files that the lint output is huge. I will fix all valid lint errors before committing, but I didn't want to pollute the diff too much nor make this MP a wall of text.
Preview Diff
1 | === modified file 'lib/lp/app/enums.py' |
2 | --- lib/lp/app/enums.py 2010-08-20 20:31:18 +0000 |
3 | +++ lib/lp/app/enums.py 2010-09-09 15:34:46 +0000 |
4 | @@ -1,11 +1,12 @@ |
5 | # Copyright 2010 Canonical Ltd. This software is licensed under the |
6 | # GNU Affero General Public License version 3 (see the file LICENSE). |
7 | |
8 | -"""Enumerations used in the lp/app modules.""" |
9 | +"""Enumerations and related utilities used in the lp/app modules.""" |
10 | |
11 | __metaclass__ = type |
12 | __all__ = [ |
13 | 'ServiceUsage', |
14 | + 'service_uses_launchpad', |
15 | ] |
16 | |
17 | from lazr.enum import ( |
18 | @@ -45,3 +46,7 @@ |
19 | |
20 | The pillar does not use this type of service in Launchpad or externally. |
21 | """) |
22 | + |
23 | + |
24 | +def service_uses_launchpad(usage_enum): |
25 | + return usage_enum == ServiceUsage.LAUNCHPAD |
26 | |
27 | === modified file 'lib/lp/registry/browser/distribution.py' |
28 | --- lib/lp/registry/browser/distribution.py 2010-09-03 03:12:39 +0000 |
29 | +++ lib/lp/registry/browser/distribution.py 2010-09-09 15:34:46 +0000 |
30 | @@ -74,6 +74,7 @@ |
31 | from canonical.launchpad.webapp.breadcrumb import Breadcrumb |
32 | from canonical.launchpad.webapp.interfaces import ILaunchBag |
33 | from canonical.widgets.image import ImageChangeWidget |
34 | +from lp.app.enums import service_uses_launchpad |
35 | from lp.answers.browser.faqtarget import FAQTargetNavigationMixin |
36 | from lp.answers.browser.questiontarget import ( |
37 | QuestionTargetFacetMixin, |
38 | @@ -135,7 +136,7 @@ |
39 | if self.context.codehosting_usage == ServiceUsage.LAUNCHPAD: |
40 | url = canonical_url(self.context, rootsite='code') |
41 | uses.append(href_template % (url, 'Branches')) |
42 | - if self.context.official_rosetta: |
43 | + if service_uses_launchpad(self.context.translations_usage): |
44 | url = canonical_url(self.context, rootsite='translations') |
45 | uses.append(href_template % (url, 'Translations')) |
46 | |
47 | |
48 | === modified file 'lib/lp/registry/browser/pillar.py' |
49 | --- lib/lp/registry/browser/pillar.py 2010-09-03 03:12:39 +0000 |
50 | +++ lib/lp/registry/browser/pillar.py 2010-09-09 15:34:46 +0000 |
51 | @@ -30,7 +30,10 @@ |
52 | nearest, |
53 | ) |
54 | from canonical.launchpad.webapp.tales import MenuAPI |
55 | -from lp.app.enums import ServiceUsage |
56 | +from lp.app.enums import ( |
57 | + ServiceUsage, |
58 | + service_uses_launchpad, |
59 | + ) |
60 | from lp.app.interfaces.launchpad import IServiceUsage |
61 | from lp.registry.browser.structuralsubscription import ( |
62 | StructuralSubscriptionMenuMixin, |
63 | @@ -72,7 +75,7 @@ |
64 | def help_translate(self): |
65 | return Link( |
66 | '', 'Help translate', site='translations', icon='translations', |
67 | - enabled=self.pillar.official_rosetta) |
68 | + enabled=service_uses_launchpad(self.pillar.translations_usage)) |
69 | |
70 | def submit_code(self): |
71 | if self.pillar.codehosting_usage in [ |
72 | @@ -104,7 +107,7 @@ |
73 | self.official_malone = False |
74 | self.official_answers = False |
75 | self.official_blueprints = False |
76 | - self.official_rosetta = False |
77 | + self.translations_usage = ServiceUsage.UNKNOWN |
78 | self.codehosting_usage = ServiceUsage.UNKNOWN |
79 | pillar = nearest(self.context, IPillar) |
80 | if IProjectGroup.providedBy(pillar): |
81 | @@ -121,7 +124,7 @@ |
82 | self.codehosting_usage = distribution.codehosting_usage |
83 | elif IDistributionSourcePackage.providedBy(self.context): |
84 | self.official_blueprints = False |
85 | - self.official_rosetta = False |
86 | + self.translations_usage = ServiceUsage.UNKNOWN |
87 | else: |
88 | # The context is used by all apps. |
89 | pass |
90 | @@ -136,8 +139,7 @@ |
91 | self.official_answers = True |
92 | if pillar.official_blueprints: |
93 | self.official_blueprints = True |
94 | - if pillar.official_rosetta: |
95 | - self.official_rosetta = True |
96 | + self.translations_usage = IServiceUsage(pillar).translations_usage |
97 | self.codehosting_usage = IServiceUsage(pillar).codehosting_usage |
98 | |
99 | @property |
100 | @@ -145,8 +147,9 @@ |
101 | """This `IPillar` uses Launchpad.""" |
102 | return ( |
103 | self.official_malone or self.official_answers |
104 | - or self.official_blueprints or self.official_rosetta |
105 | - or self.codehosting_usage == ServiceUsage.LAUNCHPAD) |
106 | + or self.official_blueprints |
107 | + or service_uses_launchpad(self.translations_usage) |
108 | + or service_uses_launchpad(self.codehosting_usage)) |
109 | |
110 | @property |
111 | def enabled_links(self): |
112 | |
113 | === modified file 'lib/lp/registry/browser/tests/pillar-views.txt' |
114 | --- lib/lp/registry/browser/tests/pillar-views.txt 2010-08-27 17:45:57 +0000 |
115 | +++ lib/lp/registry/browser/tests/pillar-views.txt 2010-09-09 15:34:46 +0000 |
116 | @@ -35,8 +35,8 @@ |
117 | True |
118 | >>> view.official_answers |
119 | True |
120 | - >>> view.official_rosetta |
121 | - False |
122 | + >>> view.translations_usage.name |
123 | + 'UNKNOWN' |
124 | >>> view.official_blueprints |
125 | False |
126 | >>> view.codehosting_usage.name |
127 | @@ -230,9 +230,10 @@ |
128 | set the links. Despite the fact that the distribution uses blueprints, |
129 | and translations those links are not enabled for DistributionSourcePackages. |
130 | |
131 | + >>> from lp.app.enums import ServiceUsage |
132 | >>> login_person(distribution.owner) |
133 | >>> distribution.official_blueprints = True |
134 | - >>> distribution.official_rosetta = True |
135 | + >>> distribution.translations_usage = ServiceUsage.LAUNCHPAD |
136 | >>> package = factory.makeDistributionSourcePackage( |
137 | ... sourcepackagename="box", |
138 | ... distribution=distribution) |
139 | |
140 | === modified file 'lib/lp/registry/browser/tests/productseries-views.txt' |
141 | --- lib/lp/registry/browser/tests/productseries-views.txt 2010-09-03 06:06:40 +0000 |
142 | +++ lib/lp/registry/browser/tests/productseries-views.txt 2010-09-09 15:34:46 +0000 |
143 | @@ -23,11 +23,12 @@ |
144 | The ProductSeries involvement view uses the ProductSeriesInvolvedMenu when |
145 | rendering links: |
146 | |
147 | + >>> from lp.app.enums import ServiceUsage |
148 | >>> login_person(product.owner) |
149 | >>> product.official_answers = True |
150 | >>> product.official_blueprints = True |
151 | >>> product.official_malone = True |
152 | - >>> product.official_rosetta = True |
153 | + >>> product.translations_usage = ServiceUsage.LAUNCHPAD |
154 | >>> view = create_view(series, '+get-involved') |
155 | |
156 | # official_answers is always false for product series. |
157 | @@ -37,10 +38,11 @@ |
158 | True |
159 | >>> print view.official_malone |
160 | True |
161 | - >>> print view.official_rosetta |
162 | - True |
163 | + >>> print view.translations_usage.name |
164 | + LAUNCHPAD |
165 | >>> print view.codehosting_usage.name |
166 | UNKNOWN |
167 | + |
168 | >>> for link in view.enabled_links: |
169 | ... print link.url |
170 | http://bugs.launchpad.dev/app/simple/+filebug |
171 | @@ -476,7 +478,7 @@ |
172 | A series cannot be deleted if it is has translation templates. |
173 | |
174 | >>> translated_series = factory.makeProductSeries(product=product) |
175 | - >>> product.official_rosetta = True |
176 | + >>> product.translations_usage = ServiceUsage.LAUNCHPAD |
177 | >>> po_template = factory.makePOTemplate( |
178 | ... name='gibberish', productseries=translated_series) |
179 | >>> translated_view = create_initialized_view( |
180 | |
181 | === modified file 'lib/lp/registry/doc/distribution.txt' |
182 | --- lib/lp/registry/doc/distribution.txt 2010-08-23 00:51:30 +0000 |
183 | +++ lib/lp/registry/doc/distribution.txt 2010-09-09 15:34:46 +0000 |
184 | @@ -1,4 +1,5 @@ |
185 | -= Distributions = |
186 | +Distributions |
187 | +============= |
188 | |
189 | From the DerivationOverview spec |
190 | <https://launchpad.canonical.com/DerivationOverview>: |
191 | @@ -143,7 +144,8 @@ |
192 | False |
193 | |
194 | |
195 | -== Distribution Sorting == |
196 | +Distribution Sorting |
197 | +-------------------- |
198 | |
199 | If you ask for all the distributions in the DistributionSet you should get |
200 | Ubuntu (and all flavours of it) first and the rest alphabetically: |
201 | @@ -164,7 +166,8 @@ |
202 | True |
203 | |
204 | |
205 | -=== Searching for DistributionSourcePackages === |
206 | +Searching for DistributionSourcePackages |
207 | +........................................ |
208 | |
209 | The distribution also allows you to look for source packages that match |
210 | a certain string through the magic of fti. For instance: |
211 | @@ -232,7 +235,8 @@ |
212 | DistributionSourcePackage: alsa-utils |
213 | |
214 | |
215 | -=== Searching for binary packages === |
216 | +Searching for binary packages |
217 | +............................. |
218 | |
219 | There are two useful functions for searching binary packages related |
220 | to the distribution, searchBinaryPackages() and searchBinaryPackagesFTI(). |
221 | @@ -291,7 +295,8 @@ |
222 | [u'mozilla-firefox'] |
223 | |
224 | |
225 | -=== Finding distroseriess and pockets from distribution names === |
226 | +Finding distroseriess and pockets from distribution names |
227 | +......................................................... |
228 | |
229 | A distribution knows what distroseriess it has. Those distroseriess have |
230 | pockets which have suffixes used by the archive publisher. Because we |
231 | @@ -336,26 +341,27 @@ |
232 | NotFoundError: 'hoary-bullshit' |
233 | |
234 | |
235 | -=== Upload related stuff === |
236 | +Upload related stuff |
237 | +.................... |
238 | |
239 | When uploading to a distribution we need to query its uploaders. Each |
240 | uploader record is in fact an ArchivePermission record that tells us |
241 | what component is uploadable to by what person or group of people. |
242 | |
243 | - >>> from operator import attrgetter |
244 | - >>> for permission in sorted( |
245 | - ... ubuntu.uploaders, key=attrgetter("id")): |
246 | - ... assert not permission.archive.is_ppa |
247 | - ... print permission.component.name |
248 | - ... print permission.person.displayname |
249 | - universe |
250 | - Ubuntu Team |
251 | - restricted |
252 | - Ubuntu Team |
253 | - main |
254 | - Ubuntu Team |
255 | - partner |
256 | - Canonical Partner Developers |
257 | + >>> from operator import attrgetter |
258 | + >>> for permission in sorted( |
259 | + ... ubuntu.uploaders, key=attrgetter("id")): |
260 | + ... assert not permission.archive.is_ppa |
261 | + ... print permission.component.name |
262 | + ... print permission.person.displayname |
263 | + universe |
264 | + Ubuntu Team |
265 | + restricted |
266 | + Ubuntu Team |
267 | + main |
268 | + Ubuntu Team |
269 | + partner |
270 | + Canonical Partner Developers |
271 | |
272 | When processing an upload we may want to find a file (E.g. if an |
273 | incomplete source is uploaded). |
274 | @@ -375,7 +381,8 @@ |
275 | AssertionError: searching in an explicitly empty space is pointless |
276 | |
277 | |
278 | -=== Launchpad Usage === |
279 | +Launchpad Usage |
280 | +............... |
281 | |
282 | A distribution can specify if it uses Malone, Rosetta, or Answers |
283 | officially. Ubuntu uses all of them: |
284 | @@ -385,8 +392,8 @@ |
285 | >>> ubuntu = getUtility(ILaunchpadCelebrities).ubuntu |
286 | >>> ubuntu.official_malone |
287 | True |
288 | - >>> ubuntu.official_rosetta |
289 | - True |
290 | + >>> ubuntu.translations_usage.name |
291 | + 'LAUNCHPAD' |
292 | >>> ubuntu.official_answers |
293 | True |
294 | >>> ubuntu.official_blueprints |
295 | @@ -397,12 +404,12 @@ |
296 | >>> print ubuntu.bug_tracking_usage.name |
297 | LAUNCHPAD |
298 | |
299 | -While the other attributes track the other official_ attributes. |
300 | +While the other attributes track the other official_ attributes. |
301 | |
302 | >>> print ubuntu.official_rosetta |
303 | True |
304 | >>> print ubuntu.translations_usage.name |
305 | - LAUNCHPAD |
306 | + LAUNCHPAD |
307 | >>> print ubuntu.official_answers |
308 | True |
309 | >>> print ubuntu.answers_usage.name |
310 | @@ -412,7 +419,8 @@ |
311 | >>> print ubuntu.blueprints_usage.name |
312 | LAUNCHPAD |
313 | |
314 | -If the official_ attributes are False, the usage enums don't know anything. |
315 | +If the official_ attributes are False and the enum hasn't been set, |
316 | +the usage enums don't know anything. |
317 | |
318 | >>> login_person(ubuntu.owner.teamowner) |
319 | >>> ubuntu.official_rosetta = False |
320 | @@ -422,37 +430,35 @@ |
321 | A distribution *cannot* specify that it uses codehosting. Currently there's |
322 | no way for a distribution to use codehosting. |
323 | |
324 | - >>> ubuntu.official_codehosting |
325 | - False |
326 | - >>> ubuntu.official_codehosting = True |
327 | - Traceback (most recent call last): |
328 | - ForbiddenAttribute: ('official_codehosting', ...) |
329 | - |
330 | + >>> from lp.app.enums import ServiceUsage |
331 | >>> print ubuntu.codehosting_usage.name |
332 | NOT_APPLICABLE |
333 | + >>> ubuntu.codehosting_usage = ServiceUsage.LAUNCHPAD |
334 | + Traceback (most recent call last): |
335 | + AttributeError: can't set attribute... |
336 | |
337 | While Debian uses none: |
338 | |
339 | >>> debian = getUtility(ILaunchpadCelebrities).debian |
340 | - >>> debian.official_malone |
341 | - False |
342 | - >>> debian.official_rosetta |
343 | - False |
344 | - >>> debian.official_answers |
345 | - False |
346 | - >>> debian.official_codehosting |
347 | - False |
348 | - >>> debian.official_blueprints |
349 | - False |
350 | + >>> print debian.bug_tracking_usage.name |
351 | + UNKNOWN |
352 | + >>> print debian.translations_usage.name |
353 | + UNKNOWN |
354 | + >>> print debian.answers_usage.name |
355 | + UNKNOWN |
356 | + >>> print debian.codehosting_usage.name |
357 | + NOT_APPLICABLE |
358 | + >>> print debian.blueprints_usage.name |
359 | + UNKNOWN |
360 | |
361 | Gentoo only uses Malone |
362 | |
363 | - >>> print gentoo.official_malone |
364 | - True |
365 | - >>> print gentoo.official_rosetta |
366 | - False |
367 | - >>> print gentoo.official_answers |
368 | - False |
369 | + >>> print gentoo.bug_tracking_usage.name |
370 | + LAUNCHPAD |
371 | + >>> print gentoo.translations_usage.name |
372 | + UNKNOWN |
373 | + >>> print gentoo.answers_usage.name |
374 | + UNKNOWN |
375 | |
376 | Launchpad admins and the distro owner can set these fields. |
377 | |
378 | @@ -464,9 +470,9 @@ |
379 | >>> debian.official_malone = True |
380 | >>> debian.official_malone |
381 | True |
382 | - >>> debian.official_rosetta = True |
383 | - >>> debian.official_rosetta |
384 | - True |
385 | + >>> debian.translations_usage = ServiceUsage.LAUNCHPAD |
386 | + >>> debian.translations_usage.name |
387 | + 'LAUNCHPAD' |
388 | |
389 | >>> debian_owner = factory.makePerson() |
390 | >>> debian.owner = debian_owner |
391 | @@ -484,12 +490,13 @@ |
392 | >>> debian.official_malone = True |
393 | Traceback (most recent call last): |
394 | Unauthorized: (..., 'official_malone', 'launchpad.Edit') |
395 | - >>> debian.official_rosetta = True |
396 | + >>> debian.translations_usage = ServiceUsage.LAUNCHPAD |
397 | Traceback (most recent call last): |
398 | - Unauthorized: (..., 'official_rosetta', 'launchpad.Edit') |
399 | - |
400 | - |
401 | -=== Specification Listings === |
402 | + Unauthorized: (..., 'translations_usage', 'launchpad.Edit') |
403 | + |
404 | + |
405 | +Specification Listings |
406 | +...................... |
407 | |
408 | We should be able to get lists of specifications in different states |
409 | related to a distro. |
410 | @@ -497,90 +504,93 @@ |
411 | Basically, we can filter by completeness, and by whether or not the spec is |
412 | informational. |
413 | |
414 | - >>> kubuntu = distroset.getByName("kubuntu") |
415 | + >>> kubuntu = distroset.getByName("kubuntu") |
416 | |
417 | - >>> from canonical.launchpad.interfaces import SpecificationFilter |
418 | + >>> from canonical.launchpad.interfaces import SpecificationFilter |
419 | |
420 | First, there should be one informational spec for kubuntu, but it is |
421 | complete so it will not show up unless we explicitly ask for complete specs: |
422 | |
423 | - >>> filter = [SpecificationFilter.INFORMATIONAL] |
424 | - >>> kubuntu.specifications(filter=filter).count() |
425 | - 0 |
426 | - >>> filter = [SpecificationFilter.INFORMATIONAL, |
427 | - ... SpecificationFilter.COMPLETE] |
428 | - >>> kubuntu.specifications(filter=filter).count() |
429 | - 1 |
430 | + >>> filter = [SpecificationFilter.INFORMATIONAL] |
431 | + >>> kubuntu.specifications(filter=filter).count() |
432 | + 0 |
433 | + >>> filter = [SpecificationFilter.INFORMATIONAL, |
434 | + ... SpecificationFilter.COMPLETE] |
435 | + >>> kubuntu.specifications(filter=filter).count() |
436 | + 1 |
437 | |
438 | |
439 | There are 2 completed specs for Kubuntu: |
440 | |
441 | - >>> filter = [SpecificationFilter.COMPLETE] |
442 | - >>> for spec in kubuntu.specifications(filter=filter): |
443 | - ... print spec.name, spec.is_complete |
444 | - thinclient-local-devices True |
445 | - usplash-on-hibernation True |
446 | + >>> filter = [SpecificationFilter.COMPLETE] |
447 | + >>> for spec in kubuntu.specifications(filter=filter): |
448 | + ... print spec.name, spec.is_complete |
449 | + thinclient-local-devices True |
450 | + usplash-on-hibernation True |
451 | |
452 | |
453 | And there are four incomplete specs: |
454 | |
455 | - >>> filter = [SpecificationFilter.INCOMPLETE] |
456 | - >>> for spec in kubuntu.specifications(filter=filter): |
457 | - ... print spec.name, spec.is_complete |
458 | - cluster-installation False |
459 | - revu False |
460 | - kde-desktopfile-langpacks False |
461 | - krunch-desktop-plan False |
462 | + >>> filter = [SpecificationFilter.INCOMPLETE] |
463 | + >>> for spec in kubuntu.specifications(filter=filter): |
464 | + ... print spec.name, spec.is_complete |
465 | + cluster-installation False |
466 | + revu False |
467 | + kde-desktopfile-langpacks False |
468 | + krunch-desktop-plan False |
469 | |
470 | |
471 | If we ask for all specs, we get them in the order of priority. |
472 | |
473 | - >>> filter = [SpecificationFilter.ALL] |
474 | - >>> for spec in kubuntu.specifications(filter=filter): |
475 | - ... print spec.priority.title, spec.name |
476 | - Essential cluster-installation |
477 | - High revu |
478 | - Medium thinclient-local-devices |
479 | - Low usplash-on-hibernation |
480 | - Undefined kde-desktopfile-langpacks |
481 | - Not krunch-desktop-plan |
482 | + >>> filter = [SpecificationFilter.ALL] |
483 | + >>> for spec in kubuntu.specifications(filter=filter): |
484 | + ... print spec.priority.title, spec.name |
485 | + Essential cluster-installation |
486 | + High revu |
487 | + Medium thinclient-local-devices |
488 | + Low usplash-on-hibernation |
489 | + Undefined kde-desktopfile-langpacks |
490 | + Not krunch-desktop-plan |
491 | |
492 | |
493 | And if we ask just for specs, we get the incomplete ones. |
494 | |
495 | - >>> for spec in kubuntu.specifications(): |
496 | - ... print spec.name, spec.is_complete |
497 | - cluster-installation False |
498 | - revu False |
499 | - kde-desktopfile-langpacks False |
500 | - krunch-desktop-plan False |
501 | + >>> for spec in kubuntu.specifications(): |
502 | + ... print spec.name, spec.is_complete |
503 | + cluster-installation False |
504 | + revu False |
505 | + kde-desktopfile-langpacks False |
506 | + krunch-desktop-plan False |
507 | |
508 | We can filter for specifications that contain specific text: |
509 | |
510 | - >>> for spec in kubuntu.specifications(filter=['package']): |
511 | - ... print spec.name |
512 | - revu |
513 | + >>> for spec in kubuntu.specifications(filter=['package']): |
514 | + ... print spec.name |
515 | + revu |
516 | |
517 | We can get only valid specs (those that are not obsolete or superseded): |
518 | |
519 | - >>> from canonical.launchpad.interfaces import SpecificationDefinitionStatus |
520 | - >>> login('mark@example.com') |
521 | - >>> for spec in kubuntu.specifications(): |
522 | - ... # Do this here, otherwise, the change will be flush before |
523 | - ... # updateLifecycleStatus() acts and an IntegrityError will be |
524 | - ... # raised. |
525 | - ... owner = spec.owner |
526 | - ... if spec.name in ['cluster-installation', 'revu']: |
527 | - ... spec.definition_status = SpecificationDefinitionStatus.OBSOLETE |
528 | - ... if spec.name in ['krunch-desktop-plan']: |
529 | - ... spec.definition_status = SpecificationDefinitionStatus.SUPERSEDED |
530 | - ... shim = spec.updateLifecycleStatus(owner) |
531 | - >>> for spec in kubuntu.valid_specifications: |
532 | - ... print spec.name |
533 | - kde-desktopfile-langpacks |
534 | - |
535 | - |
536 | -== Milestones == |
537 | + >>> from canonical.launchpad.interfaces import ( |
538 | + ... SpecificationDefinitionStatus, |
539 | + ... ) |
540 | + >>> login('mark@example.com') |
541 | + >>> for spec in kubuntu.specifications(): |
542 | + ... # Do this here, otherwise, the change will be flush before |
543 | + ... # updateLifecycleStatus() acts and an IntegrityError will be |
544 | + ... # raised. |
545 | + ... owner = spec.owner |
546 | + ... if spec.name in ['cluster-installation', 'revu']: |
547 | + ... spec.definition_status = SpecificationDefinitionStatus.OBSOLETE |
548 | + ... if spec.name in ['krunch-desktop-plan']: |
549 | + ... spec.definition_status = SpecificationDefinitionStatus.SUPERSEDED |
550 | + ... shim = spec.updateLifecycleStatus(owner) |
551 | + >>> for spec in kubuntu.valid_specifications: |
552 | + ... print spec.name |
553 | + kde-desktopfile-langpacks |
554 | + |
555 | + |
556 | +Milestones |
557 | +---------- |
558 | |
559 | We can use IDistribution.milestones to get all milestones associated with any |
560 | series of a distribution. |
561 | @@ -623,7 +633,8 @@ |
562 | [u'3.1', u'3.1-rc1', u'woody-rc1'] |
563 | |
564 | |
565 | -== Archives == |
566 | +Archives |
567 | +-------- |
568 | |
569 | A distribution archive (primary, partner, debug or copy) can be retrieved |
570 | by name using IDistribution.getArchive. |
571 | |
572 | === modified file 'lib/lp/registry/doc/product.txt' |
573 | --- lib/lp/registry/doc/product.txt 2010-08-25 15:48:05 +0000 |
574 | +++ lib/lp/registry/doc/product.txt 2010-09-09 15:34:46 +0000 |
575 | @@ -1,4 +1,5 @@ |
576 | -= Product = |
577 | +Product |
578 | +======= |
579 | |
580 | Launchpad keeps track of the "upstream" world as well as the "distro" world. |
581 | The anchorpiece of the "upstream" world is the Product, which is a piece of |
582 | @@ -162,7 +163,8 @@ |
583 | Obsolete Junk |
584 | |
585 | |
586 | -== Translatable Products == |
587 | +Translatable Products |
588 | +--------------------- |
589 | |
590 | IProductSet will also tell us which products can be translated: |
591 | |
592 | @@ -217,11 +219,11 @@ |
593 | The packaging table allows us to list source and distro source packages |
594 | related to a certain upstream: |
595 | |
596 | - >>> alsa = productset.getByName('alsa-utils') |
597 | - >>> [(sp.name, sp.distroseries.name) for sp in alsa.sourcepackages] |
598 | - [(u'alsa-utils', u'sid'), (u'alsa-utils', u'warty')] |
599 | - >>> [(sp.name, sp.distribution.name) for sp in alsa.distrosourcepackages] |
600 | - [(u'alsa-utils', u'debian'), (u'alsa-utils', u'ubuntu')] |
601 | + >>> alsa = productset.getByName('alsa-utils') |
602 | + >>> [(sp.name, sp.distroseries.name) for sp in alsa.sourcepackages] |
603 | + [(u'alsa-utils', u'sid'), (u'alsa-utils', u'warty')] |
604 | + >>> [(sp.name, sp.distribution.name) for sp in alsa.distrosourcepackages] |
605 | + [(u'alsa-utils', u'debian'), (u'alsa-utils', u'ubuntu')] |
606 | |
607 | The date_next_suggest_packaging attribute records the date when Launchpad can |
608 | resume suggesting Ubuntu packages that the project provides. A value of None |
609 | @@ -270,7 +272,8 @@ |
610 | >>> from canonical.launchpad.interfaces import IBugTrackerSet |
611 | |
612 | >>> login_person(firefox.owner) |
613 | - >>> gnome_bugzilla = getUtility(IBugTrackerSet).getByName('gnome-bugzilla') |
614 | + >>> bug_tracker_set = getUtility(IBugTrackerSet) |
615 | + >>> gnome_bugzilla = bug_tracker_set.getByName('gnome-bugzilla') |
616 | >>> firefox.project.bugtracker = gnome_bugzilla |
617 | >>> firefox.getExternalBugTracker() is None |
618 | True |
619 | @@ -307,7 +310,8 @@ |
620 | True |
621 | |
622 | |
623 | -== Answer Tracking == |
624 | +Answer Tracking |
625 | +--------------- |
626 | |
627 | Firefox uses the Answer Tracker as the official application to provide |
628 | answers to questions. |
629 | @@ -321,7 +325,8 @@ |
630 | False |
631 | |
632 | |
633 | -== Product Creation == |
634 | +Product Creation |
635 | +---------------- |
636 | |
637 | We can create new products with the createProduct() method: |
638 | |
639 | @@ -374,20 +379,21 @@ |
640 | True |
641 | |
642 | |
643 | -== Specification Listings == |
644 | +Specification Listings |
645 | +---------------------- |
646 | |
647 | We should be able to set whether or not a Product uses specifications |
648 | officially. It defaults to False. |
649 | |
650 | - >>> firefox = productset.getByName('firefox') |
651 | - >>> firefox.official_blueprints |
652 | - False |
653 | + >>> firefox = productset.getByName('firefox') |
654 | + >>> firefox.official_blueprints |
655 | + False |
656 | |
657 | We can change it to True. |
658 | |
659 | - >>> firefox.official_blueprints = True |
660 | - >>> firefox.official_blueprints |
661 | - True |
662 | + >>> firefox.official_blueprints = True |
663 | + >>> firefox.official_blueprints |
664 | + True |
665 | |
666 | We should be able to get lists of specifications in different states |
667 | related to a product. |
668 | @@ -395,39 +401,40 @@ |
669 | Basically, we can filter by completeness, and by whether or not the spec is |
670 | informational. |
671 | |
672 | - >>> firefox = productset.getByName('firefox') |
673 | - >>> from canonical.launchpad.interfaces import SpecificationFilter |
674 | + >>> firefox = productset.getByName('firefox') |
675 | + >>> from canonical.launchpad.interfaces import SpecificationFilter |
676 | |
677 | First, there should be only one informational spec for firefox: |
678 | |
679 | - >>> filter = [SpecificationFilter.INFORMATIONAL] |
680 | - >>> for spec in firefox.specifications(filter=filter): |
681 | - ... print spec.name |
682 | - extension-manager-upgrades |
683 | + >>> filter = [SpecificationFilter.INFORMATIONAL] |
684 | + >>> for spec in firefox.specifications(filter=filter): |
685 | + ... print spec.name |
686 | + extension-manager-upgrades |
687 | |
688 | |
689 | There are no completed specs for firefox: |
690 | |
691 | - >>> filter = [SpecificationFilter.COMPLETE] |
692 | - >>> for spec in firefox.specifications(filter=filter): |
693 | - ... print spec.name |
694 | + >>> filter = [SpecificationFilter.COMPLETE] |
695 | + >>> for spec in firefox.specifications(filter=filter): |
696 | + ... print spec.name |
697 | |
698 | |
699 | And there are five incomplete specs: |
700 | |
701 | - >>> filter = [SpecificationFilter.INCOMPLETE] |
702 | - >>> firefox.specifications(filter=filter).count() |
703 | - 5 |
704 | + >>> filter = [SpecificationFilter.INCOMPLETE] |
705 | + >>> firefox.specifications(filter=filter).count() |
706 | + 5 |
707 | |
708 | We can filter for specifications that contain specific text: |
709 | |
710 | - >>> for spec in firefox.specifications(filter=['new']): |
711 | - ... print spec.name |
712 | - canvas |
713 | - e4x |
714 | - |
715 | - |
716 | -== Milestones == |
717 | + >>> for spec in firefox.specifications(filter=['new']): |
718 | + ... print spec.name |
719 | + canvas |
720 | + e4x |
721 | + |
722 | + |
723 | +Milestones |
724 | +---------- |
725 | |
726 | We can use IProduct.milestones to get all milestones associated with any |
727 | ProductSeries of a product. |
728 | @@ -470,7 +477,8 @@ |
729 | [u'1.0.0', u'0.9.2', u'0.9.1', u'0.9', u'1.0', u'1.0-rc1'] |
730 | |
731 | |
732 | -== Release == |
733 | +Release |
734 | +------- |
735 | |
736 | All the releases for a Product can be retrieved through the releases property. |
737 | |
738 | @@ -489,7 +497,8 @@ |
739 | 0.9.1 |
740 | |
741 | |
742 | -== Products With Branches == |
743 | +Products With Branches |
744 | +---------------------- |
745 | |
746 | Products are considered to officially support Launchpad as a location |
747 | for their branches after a branch is set for the development focus |
748 | @@ -568,7 +577,8 @@ |
749 | landscape |
750 | |
751 | |
752 | -== Primary translatable == |
753 | +Primary translatable |
754 | +-------------------- |
755 | |
756 | Primary translatable series in a product should follow series where |
757 | development is focused on. To be able to do changes to facilitate |
758 | @@ -583,12 +593,18 @@ |
759 | >>> from lp.translations.interfaces.potemplate import IPOTemplateSet |
760 | >>> potemplate_set = getUtility(IPOTemplateSet) |
761 | |
762 | +We're going to be setting the ServiceUsage values for products, so we |
763 | +need those enums. |
764 | + |
765 | + >>> from lp.app.enums import ServiceUsage |
766 | + |
767 | Firefox has two series, but no translatable series either: |
768 | |
769 | >>> firefox = productset.getByName('firefox') |
770 | >>> for firefoxseries in firefox.series: |
771 | - ... print '%s %s' % (firefoxseries.displayname, |
772 | - ... list(firefoxseries.getCurrentTranslationTemplates())) |
773 | + ... print '%s %s' % ( |
774 | + ... firefoxseries.displayname, |
775 | + ... list(firefoxseries.getCurrentTranslationTemplates())) |
776 | 1.0 [] |
777 | trunk [] |
778 | >>> print firefox.primary_translatable |
779 | @@ -616,7 +632,7 @@ |
780 | And set that product as using translations officially. We need it so |
781 | translations are available. |
782 | |
783 | - >>> firefox.official_rosetta = True |
784 | + >>> firefox.translations_usage = ServiceUsage.LAUNCHPAD |
785 | |
786 | The primary_translatable now points at firefox 1.0: |
787 | |
788 | @@ -642,7 +658,8 @@ |
789 | 1.0 |
790 | |
791 | |
792 | -= Series list = |
793 | +Series list |
794 | +=========== |
795 | |
796 | The series for a product are returned as a sorted list, with the |
797 | exception that the current development focus is first. |
798 | @@ -697,7 +714,8 @@ |
799 | ... print series.name |
800 | trunk |
801 | |
802 | -= Changing ownership = |
803 | +Changing ownership |
804 | +================== |
805 | |
806 | If the owner of a project changes, all series and productreleases |
807 | owned by the old owner are transfered to the new owner. |
808 | |
809 | === modified file 'lib/lp/registry/doc/project.txt' |
810 | --- lib/lp/registry/doc/project.txt 2010-06-07 07:52:45 +0000 |
811 | +++ lib/lp/registry/doc/project.txt 2010-09-09 15:34:46 +0000 |
812 | @@ -1,4 +1,5 @@ |
813 | -= ProjectGroups = |
814 | +ProjectGroups |
815 | +============= |
816 | |
817 | A ProjectGroup is a group of Products, making it possible to for |
818 | example see all bugs in the ProjectGroup's Product, or make them share a |
819 | @@ -11,7 +12,8 @@ |
820 | >>> projectset = getUtility(IProjectGroupSet) |
821 | |
822 | |
823 | -== Creating new projects == |
824 | +Creating new projects |
825 | +--------------------- |
826 | |
827 | When creating a new project there are a bunch of things we need to provide. |
828 | While some of them (homepageurl, icon, logo and mugshot) are optional, others |
829 | @@ -28,7 +30,8 @@ |
830 | u'project-test' |
831 | |
832 | |
833 | -== Looking up existing projects == |
834 | +Looking up existing projects |
835 | +---------------------------- |
836 | |
837 | To fetch a project we use IProjectGroupSet.getByName() or |
838 | IProjectGroupSet.__getitem__. The former will, by default, return active and |
839 | @@ -98,7 +101,8 @@ |
840 | >>> print projectgroups.getByName('gnome', ignore_inactive=True) |
841 | None |
842 | |
843 | -== Products which are part of a project == |
844 | +Products which are part of a project |
845 | +------------------------------------ |
846 | |
847 | The products which are part of a given project are given by a project's |
848 | .products property. Note that only active products are included and they're |
849 | @@ -122,7 +126,8 @@ |
850 | >>> flush_database_updates() |
851 | |
852 | |
853 | -== Specification Listings == |
854 | +Specification Listings |
855 | +---------------------- |
856 | |
857 | We should be able to generate filtered lists of specs on a project. |
858 | |
859 | @@ -200,7 +205,8 @@ |
860 | e4x |
861 | |
862 | |
863 | -== Specification Listings for a ProjectGroupSeries == |
864 | +Specification Listings for a ProjectGroupSeries |
865 | +----------------------------------------------- |
866 | |
867 | An IProjectGroupSeries object can be retrieved by IProjectGroup.getSeries. |
868 | |
869 | @@ -314,7 +320,8 @@ |
870 | e4x |
871 | |
872 | |
873 | -== translatables == |
874 | +Translatables |
875 | +------------- |
876 | |
877 | A project would have IProduct objects that have resources to translate. This |
878 | method return us the ones that are translatable and officially using Rosetta |
879 | @@ -349,8 +356,8 @@ |
880 | |
881 | That is using Rosetta officially. |
882 | |
883 | - >>> evolution.official_rosetta |
884 | - True |
885 | + >>> print evolution.translations_usage.name |
886 | + LAUNCHPAD |
887 | |
888 | GNOME project has also another product, netapplet. |
889 | |
890 | @@ -361,8 +368,8 @@ |
891 | But it was not returned from 'translatables' method because it's not using |
892 | Rosetta officially. |
893 | |
894 | - >>> netapplet.official_rosetta |
895 | - False |
896 | + >>> print netapplet.translations_usage.name |
897 | + UNKNOWN |
898 | |
899 | And thus, it doesn't have any translatable series. |
900 | |
901 | @@ -376,7 +383,8 @@ |
902 | 1 |
903 | |
904 | |
905 | -== Milestones == |
906 | +Milestones |
907 | +---------- |
908 | |
909 | A project can have virtual milestones. If any of its products has milestones, |
910 | these milestones are also associated with the project. |
911 | @@ -398,7 +406,8 @@ |
912 | 1.1. active: True |
913 | 1.1 active: True |
914 | |
915 | -ProjectGroup.all_milestones is a list of all milestones associated with a project. |
916 | +ProjectGroup.all_milestones is a list of all milestones associated with a |
917 | +project. |
918 | |
919 | >>> milestones = gnome.all_milestones |
920 | >>> for milestone in milestones: |
921 | @@ -410,8 +419,8 @@ |
922 | 1.1. active: True |
923 | 1.1 active: True |
924 | |
925 | -ProjectGroup.getMilestone(name) returns the project milestone with the name `name' |
926 | -or None, if no milestone with this name exists. |
927 | +ProjectGroup.getMilestone(name) returns the project milestone with the name |
928 | +`name' or None, if no milestone with this name exists. |
929 | |
930 | >>> milestone = gnome.getMilestone('1.1') |
931 | >>> print milestone.name |
932 | |
933 | === modified file 'lib/lp/registry/model/projectgroup.py' |
934 | --- lib/lp/registry/model/projectgroup.py 2010-08-24 19:06:33 +0000 |
935 | +++ lib/lp/registry/model/projectgroup.py 2010-09-09 15:34:46 +0000 |
936 | @@ -202,6 +202,9 @@ |
937 | |
938 | def translatables(self): |
939 | """See `IProjectGroup`.""" |
940 | + # XXX j.c.sackett 2010-08-30 bug=627631 Once data migration has |
941 | + # happened for the usage enums, this sql needs to be updated to |
942 | + # check for the translations_usage, not official_rosetta. |
943 | return Product.select(''' |
944 | Product.project = %s AND |
945 | Product.official_rosetta = TRUE AND |
946 | @@ -271,7 +274,7 @@ |
947 | |
948 | # filter based on completion. see the implementation of |
949 | # Specification.is_complete() for more details |
950 | - completeness = Specification.completeness_clause |
951 | + completeness = Specification.completeness_clause |
952 | |
953 | if SpecificationFilter.COMPLETE in filter: |
954 | query += ' AND ( %s ) ' % completeness |
955 | |
956 | === modified file 'lib/lp/testing/factory.py' |
957 | --- lib/lp/testing/factory.py 2010-09-09 14:11:43 +0000 |
958 | +++ lib/lp/testing/factory.py 2010-09-09 15:34:46 +0000 |
959 | @@ -93,6 +93,7 @@ |
960 | IStoreSelector, |
961 | MAIN_STORE, |
962 | ) |
963 | +from lp.app.enums import ServiceUsage |
964 | from lp.archiveuploader.dscfile import DSCFile |
965 | from lp.archiveuploader.uploadpolicy import BuildDaemonUploadPolicy |
966 | from lp.blueprints.interfaces.specification import ( |
967 | @@ -838,7 +839,7 @@ |
968 | self, name=None, project=None, displayname=None, |
969 | licenses=None, owner=None, registrant=None, |
970 | title=None, summary=None, official_malone=None, |
971 | - official_rosetta=None, bug_supervisor=None): |
972 | + translations_usage=None, bug_supervisor=None): |
973 | """Create and return a new, arbitrary Product.""" |
974 | if owner is None: |
975 | owner = self.makePerson() |
976 | @@ -867,8 +868,9 @@ |
977 | registrant=registrant) |
978 | if official_malone is not None: |
979 | removeSecurityProxy(product).official_malone = official_malone |
980 | - if official_rosetta is not None: |
981 | - removeSecurityProxy(product).official_rosetta = official_rosetta |
982 | + if translations_usage is not None: |
983 | + naked_product = removeSecurityProxy(product) |
984 | + naked_product.translations_usage = translations_usage |
985 | if bug_supervisor is not None: |
986 | naked_product = removeSecurityProxy(product) |
987 | naked_product.bug_supervisor = bug_supervisor |
988 | @@ -2176,7 +2178,8 @@ |
989 | productseries = self.makeProductSeries(owner=owner) |
990 | # Make it use Translations, otherwise there's little point |
991 | # to us creating a template for it. |
992 | - removeSecurityProxy(productseries).product.official_rosetta = True |
993 | + naked_series = removeSecurityProxy(productseries) |
994 | + naked_series.product.translations_usage = ServiceUsage.LAUNCHPAD |
995 | templateset = getUtility(IPOTemplateSet) |
996 | subset = templateset.getSubset( |
997 | distroseries, sourcepackagename, productseries) |
998 | |
999 | === modified file 'lib/lp/translations/browser/potemplate.py' |
1000 | --- lib/lp/translations/browser/potemplate.py 2010-08-25 20:04:40 +0000 |
1001 | +++ lib/lp/translations/browser/potemplate.py 2010-09-09 15:34:46 +0000 |
1002 | @@ -61,6 +61,7 @@ |
1003 | from canonical.launchpad.webapp.launchpadform import ReturnToReferrerMixin |
1004 | from canonical.launchpad.webapp.menu import structured |
1005 | from canonical.lazr.utils import smartquote |
1006 | +from lp.app.enums import service_uses_launchpad |
1007 | from lp.app.errors import NotFoundError |
1008 | from lp.registry.browser.productseries import ProductSeriesFacets |
1009 | from lp.registry.browser.sourcepackage import SourcePackageFacets |
1010 | @@ -794,9 +795,10 @@ |
1011 | product_or_distro = potemplate.productseries.product |
1012 | else: |
1013 | product_or_distro = potemplate.distroseries.distribution |
1014 | - official_rosetta = product_or_distro.official_rosetta |
1015 | + translations_usage = product_or_distro.translations_usage |
1016 | |
1017 | - if official_rosetta and potemplate.iscurrent: |
1018 | + if (service_uses_launchpad(translations_usage) and |
1019 | + potemplate.iscurrent): |
1020 | # This template is available for translation. |
1021 | return potemplate |
1022 | elif check_permission('launchpad.Edit', potemplate): |
1023 | |
1024 | === modified file 'lib/lp/translations/browser/product.py' |
1025 | --- lib/lp/translations/browser/product.py 2010-08-24 10:45:57 +0000 |
1026 | +++ lib/lp/translations/browser/product.py 2010-09-09 15:34:46 +0000 |
1027 | @@ -19,6 +19,7 @@ |
1028 | ) |
1029 | from canonical.launchpad.webapp.authorization import check_permission |
1030 | from canonical.launchpad.webapp.menu import NavigationMenu |
1031 | +from lp.app.enums import service_uses_launchpad |
1032 | from lp.registry.browser.product import ProductEditView |
1033 | from lp.registry.interfaces.product import IProduct |
1034 | from lp.registry.interfaces.productseries import IProductSeries |
1035 | @@ -51,12 +52,14 @@ |
1036 | def translationdownload(self): |
1037 | text = 'Download' |
1038 | preferred_series = self.context.primary_translatable |
1039 | - enabled = (self.context.official_rosetta and |
1040 | - preferred_series is not None) |
1041 | + enabled = (service_uses_launchpad(self.context.translations_usage) |
1042 | + and preferred_series is not None) |
1043 | link = '' |
1044 | if enabled: |
1045 | link = canonical_url( |
1046 | - preferred_series, rootsite='translations', view_name='+export') |
1047 | + preferred_series, |
1048 | + rootsite='translations', |
1049 | + view_name='+export') |
1050 | text = 'Download "%s"' % preferred_series.name |
1051 | |
1052 | return Link(link, text, icon='download', enabled=enabled) |
1053 | @@ -90,19 +93,19 @@ |
1054 | @cachedproperty |
1055 | def uses_translations(self): |
1056 | """Whether this product has translatable templates.""" |
1057 | - return (self.context.official_rosetta and |
1058 | - self.primary_translatable is not None) |
1059 | + return (service_uses_launchpad(self.context.translations_usage) |
1060 | + and self.primary_translatable is not None) |
1061 | |
1062 | @cachedproperty |
1063 | def no_translations_available(self): |
1064 | """Has no translation templates but does support translations.""" |
1065 | - return (self.context.official_rosetta and |
1066 | - self.primary_translatable is None) |
1067 | + return (service_uses_launchpad(self.context.translations_usage) |
1068 | + and self.primary_translatable is None) |
1069 | |
1070 | @cachedproperty |
1071 | def show_page_content(self): |
1072 | """Whether the main content of the page should be shown.""" |
1073 | - return (self.context.official_rosetta or |
1074 | + return (service_uses_launchpad(self.context.translations_usage) or |
1075 | check_permission("launchpad.TranslationsAdmin", self.context)) |
1076 | |
1077 | @cachedproperty |
1078 | |
1079 | === modified file 'lib/lp/translations/browser/tests/language-views.txt' |
1080 | --- lib/lp/translations/browser/tests/language-views.txt 2010-07-16 16:51:52 +0000 |
1081 | +++ lib/lp/translations/browser/tests/language-views.txt 2010-09-09 15:34:46 +0000 |
1082 | @@ -143,7 +143,10 @@ |
1083 | |
1084 | Create a product, a template with one msgset and a pofile |
1085 | |
1086 | - >>> product = factory.makeProduct(official_rosetta=True) |
1087 | + >>> from lp.app.enums import ServiceUsage |
1088 | + |
1089 | + >>> product = factory.makeProduct( |
1090 | + ... translations_usage=ServiceUsage.LAUNCHPAD) |
1091 | >>> template = factory.makePOTemplate( |
1092 | ... productseries=product.getSeries('trunk')) |
1093 | >>> potmsgset = factory.makePOTMsgSet(template) |
1094 | |
1095 | === modified file 'lib/lp/translations/browser/tests/test_breadcrumbs.py' |
1096 | --- lib/lp/translations/browser/tests/test_breadcrumbs.py 2010-08-20 20:31:18 +0000 |
1097 | +++ lib/lp/translations/browser/tests/test_breadcrumbs.py 2010-09-09 15:34:46 +0000 |
1098 | @@ -6,6 +6,7 @@ |
1099 | from zope.component import getUtility |
1100 | |
1101 | from canonical.lazr.utils import smartquote |
1102 | +from lp.app.enums import ServiceUsage |
1103 | from lp.services.worlddata.interfaces.language import ILanguageSet |
1104 | from lp.testing.breadcrumbs import BaseBreadcrumbTestCase |
1105 | from lp.testing.factory import remove_security_proxy_and_shout_at_engineer |
1106 | @@ -152,7 +153,7 @@ |
1107 | def test_potemplate(self): |
1108 | product = self.factory.makeProduct( |
1109 | name='crumb-tester', displayname="Crumb Tester", |
1110 | - official_rosetta=True) |
1111 | + translations_usage=ServiceUsage.LAUNCHPAD) |
1112 | series = self.factory.makeProductSeries( |
1113 | name="test", product=product) |
1114 | potemplate = self.factory.makePOTemplate( |
1115 | @@ -176,7 +177,7 @@ |
1116 | def test_pofiletranslate(self): |
1117 | product = self.factory.makeProduct( |
1118 | name='crumb-tester', displayname="Crumb Tester", |
1119 | - official_rosetta=True) |
1120 | + translations_usage=ServiceUsage.LAUNCHPAD) |
1121 | series = self.factory.makeProductSeries(name="test", product=product) |
1122 | potemplate = self.factory.makePOTemplate(series, name="test-template") |
1123 | pofile = self.factory.makePOFile('eo', potemplate) |
1124 | |
1125 | === modified file 'lib/lp/translations/doc/potmsgset.txt' |
1126 | --- lib/lp/translations/doc/potmsgset.txt 2010-09-01 10:03:11 +0000 |
1127 | +++ lib/lp/translations/doc/potmsgset.txt 2010-09-09 15:34:46 +0000 |
1128 | @@ -1,4 +1,5 @@ |
1129 | -= POTMsgSet tests = |
1130 | +POTMsgSet tests |
1131 | +=============== |
1132 | |
1133 | POTMsgSet represents messages to translate that a POTemplate file has. |
1134 | |
1135 | @@ -17,7 +18,9 @@ |
1136 | ... ILanguageSet, IPersonSet, IProductSet) |
1137 | |
1138 | >>> potemplate = factory.makePOTemplate() |
1139 | - >>> potmsgset = factory.makePOTMsgSet(potemplate=potemplate, singular="bla") |
1140 | + >>> potmsgset = factory.makePOTMsgSet( |
1141 | + ... potemplate=potemplate, |
1142 | + ... singular="bla") |
1143 | |
1144 | Verify interface. |
1145 | |
1146 | @@ -31,7 +34,8 @@ |
1147 | >>> import pytz |
1148 | |
1149 | |
1150 | -== POTMsgSet.is_translation_credit and POTMsgSet.translation_credit_type == |
1151 | +POTMsgSet.is_translation_credit and POTMsgSet.translation_credit_type |
1152 | +--------------------------------------------------------------------- |
1153 | |
1154 | A POTMsgSet can be translation credits. These have special msgids that may |
1155 | differ for historical reason for the same type of credit. The property |
1156 | @@ -51,7 +55,8 @@ |
1157 | Gnome credits message |
1158 | |
1159 | |
1160 | -== POTMsgSet.normalizeWhitespaces == |
1161 | +POTMsgSet.normalizeWhitespaces |
1162 | +------------------------------ |
1163 | |
1164 | This function copies the leading and trailing whitespaces from |
1165 | POTMsgSet's msgid into the 'text' argument. |
1166 | @@ -96,7 +101,8 @@ |
1167 | True |
1168 | |
1169 | |
1170 | -== POTMsgSet.convertDotToSpace == |
1171 | +POTMsgSet.convertDotToSpace |
1172 | +--------------------------- |
1173 | |
1174 | This method changes the u'\u2022' char by the normal white space. |
1175 | |
1176 | @@ -126,14 +132,17 @@ |
1177 | u'a string with the char \u2022' |
1178 | |
1179 | |
1180 | -== POTMsgSet.normalizeNewLines == |
1181 | +POTMsgSet.normalizeNewLines |
1182 | +--------------------------- |
1183 | |
1184 | This method syncs the new line chars to use the same as the associated msgid. |
1185 | |
1186 | As this test is too specific, we are going to change a msgid as we need for |
1187 | every test. |
1188 | |
1189 | - >>> potmsgset_windows = factory.makePOTMsgSet(potemplate, singular=u'\r\n') |
1190 | + >>> potmsgset_windows = factory.makePOTMsgSet( |
1191 | + ... potemplate, |
1192 | + ... singular=u'\r\n') |
1193 | >>> potmsgset_unix = factory.makePOTMsgSet(potemplate, singular=u'\n') |
1194 | >>> potmsgset_mac = factory.makePOTMsgSet(potemplate, singular=u'\r') |
1195 | >>> text_windows = u'\r\n' |
1196 | @@ -180,7 +189,8 @@ |
1197 | BrokenTextError: ... |
1198 | |
1199 | |
1200 | -== POTMsgSet.applySanityFixes == |
1201 | +POTMsgSet.applySanityFixes |
1202 | +-------------------------- |
1203 | |
1204 | This function applies all checks we know to fix broken input |
1205 | |
1206 | @@ -199,7 +209,8 @@ |
1207 | u'\nTranslation\nto test\n' |
1208 | |
1209 | |
1210 | -== POTMsgSet.updateTranslation == |
1211 | +POTMsgSet.updateTranslation |
1212 | +--------------------------- |
1213 | |
1214 | This method is the core piece of Translations infrastructure: it |
1215 | updates a single language translation for a POTMsgSet, and modifies a |
1216 | @@ -309,7 +320,8 @@ |
1217 | >>> current.date_created is None |
1218 | False |
1219 | |
1220 | -=== Unsetting a translation from the import === |
1221 | +Unsetting a translation from the import |
1222 | +....................................... |
1223 | |
1224 | A translation can be removed from the import by being set to an empty string. |
1225 | |
1226 | @@ -349,7 +361,8 @@ |
1227 | >>> upstream_pofile.updateStatistics() |
1228 | (0, 0, 0, 2) |
1229 | |
1230 | -=== Activating an existing suggestion === |
1231 | +Activating an existing suggestion |
1232 | +................................. |
1233 | |
1234 | Foo Bar is a privileged translator who can do reviews and submit translations |
1235 | directly, while No Privileges user can only submit suggestions. |
1236 | @@ -438,7 +451,8 @@ |
1237 | u'Foo Bar' |
1238 | |
1239 | |
1240 | -== Plural forms == |
1241 | +Plural forms |
1242 | +------------ |
1243 | |
1244 | Let's focus on handling of messages with plural forms. |
1245 | |
1246 | @@ -513,7 +527,8 @@ |
1247 | [None, None, None] |
1248 | |
1249 | |
1250 | -=== Missing forms === |
1251 | +Missing forms |
1252 | +............. |
1253 | |
1254 | Even when a message has a singular and a plural in English, a |
1255 | translation does not have to cover all plural forms available in the |
1256 | @@ -538,7 +553,8 @@ |
1257 | False |
1258 | |
1259 | |
1260 | -=== Extraneous forms === |
1261 | +Extraneous forms |
1262 | +................ |
1263 | |
1264 | It's not normally possible to input more plural forms for a translated |
1265 | message than the language has. But that number is configurable, and can |
1266 | @@ -614,7 +630,8 @@ |
1267 | possible. |
1268 | |
1269 | |
1270 | -== isTranslationNewerThan == |
1271 | +isTranslationNewerThan |
1272 | +---------------------- |
1273 | |
1274 | This method tells us whether the active translation was reviewed after |
1275 | the given timestamp. |
1276 | @@ -633,7 +650,8 @@ |
1277 | False |
1278 | |
1279 | |
1280 | -== External translation suggestions == |
1281 | +External translation suggestions |
1282 | +-------------------------------- |
1283 | |
1284 | External translation suggestions are current, imported or suggested |
1285 | translation for exactly the same English string, but in a different |
1286 | @@ -670,7 +688,8 @@ |
1287 | ... print line |
1288 | |
1289 | |
1290 | -== POTMsgSet.getExternallyUsedTranslationMessages == |
1291 | +POTMsgSet.getExternallyUsedTranslationMessages |
1292 | +---------------------------------------------- |
1293 | |
1294 | On one side, we have a translation template for the evolution product. |
1295 | |
1296 | @@ -692,10 +711,10 @@ |
1297 | |
1298 | Both, product and distribution use Launchpad Translations. |
1299 | |
1300 | - >>> evolution.official_rosetta |
1301 | - True |
1302 | - >>> ubuntu.official_rosetta |
1303 | - True |
1304 | + >>> evolution.translations_usage.name |
1305 | + 'LAUNCHPAD' |
1306 | + >>> ubuntu.translations_usage.name |
1307 | + 'LAUNCHPAD' |
1308 | |
1309 | And both translation templates are current |
1310 | |
1311 | @@ -754,7 +773,9 @@ |
1312 | The same happens if the distribution is not officially using |
1313 | translations. |
1314 | |
1315 | - >>> ubuntu.official_rosetta = False |
1316 | + >>> from lp.app.enums import ServiceUsage |
1317 | + |
1318 | + >>> ubuntu.translations_usage = ServiceUsage.NOT_APPLICABLE |
1319 | |
1320 | # We set the template as current again so we are sure that we don't show |
1321 | # suggestions just due to the change to the official_rosetta flag. |
1322 | @@ -767,7 +788,7 @@ |
1323 | |
1324 | And products not using translations officially have the same behaviour. |
1325 | |
1326 | - >>> evolution.official_rosetta = False |
1327 | + >>> evolution.translations_usage = ServiceUsage.NOT_APPLICABLE |
1328 | >>> transaction.commit() |
1329 | >>> suggestions = evo_distro_message.getExternallyUsedTranslationMessages( |
1330 | ... spanish) |
1331 | @@ -776,12 +797,13 @@ |
1332 | |
1333 | Let's restore the flags for next section. |
1334 | |
1335 | - >>> ubuntu.official_rosetta = True |
1336 | - >>> evolution.official_rosetta = True |
1337 | + >>> ubuntu.translations_usage = ServiceUsage.LAUNCHPAD |
1338 | + >>> evolution.translations_usage = ServiceUsage.LAUNCHPAD |
1339 | >>> transaction.commit() |
1340 | |
1341 | |
1342 | -== POTMsgSet.getExternallySuggestedTranslationMessages == |
1343 | +POTMsgSet.getExternallySuggestedTranslationMessages |
1344 | +--------------------------------------------------- |
1345 | |
1346 | This method returns a set of submissions that have suggested translations |
1347 | for the same msgid as the given POTMsgSet across the whole system. |
1348 | @@ -876,7 +898,7 @@ |
1349 | # We set the template as current again so we are sure that we don't show |
1350 | # suggestions just due to the change to the official_rosetta flag. |
1351 | >>> potmsgset_translated.potemplate.iscurrent = True |
1352 | - >>> ubuntu.official_rosetta = False |
1353 | + >>> ubuntu.translations_usage = ServiceUsage.NOT_APPLICABLE |
1354 | >>> transaction.commit() |
1355 | |
1356 | >>> wiki_submissions = ( |
1357 | @@ -886,7 +908,8 @@ |
1358 | 0 |
1359 | |
1360 | |
1361 | -== POTMsgSet.getCurrentDummyTranslationMessage == |
1362 | +POTMsgSet.getCurrentDummyTranslationMessage |
1363 | +------------------------------------------- |
1364 | |
1365 | Sometimes, there are POTMsgSet objects with no translations to a language, |
1366 | and we need to get dummy objects which emulate them to do read operations. |
1367 | @@ -908,7 +931,8 @@ |
1368 | AssertionError: There is already a translation message ... |
1369 | |
1370 | |
1371 | -== Suggestions for translator credits == |
1372 | +Suggestions for translator credits |
1373 | +---------------------------------- |
1374 | |
1375 | Messages with translator credits are translated automatically by |
1376 | Launchpad, so we should not get any suggestions for them. |
1377 | @@ -936,8 +960,8 @@ |
1378 | |
1379 | Now, let's add 'translation-credits' message to a different POTemplate: |
1380 | |
1381 | - >>> new_credits = evolution_potemplate.createMessageSetFromText( |
1382 | - ... singular_text=u'translation-credits', plural_text=None) |
1383 | + >>> new_credits = evolution_potemplate.createMessageSetFromText( |
1384 | + ... singular_text=u'translation-credits', plural_text=None) |
1385 | |
1386 | However, this one doesn't show up as external suggestion for Spanish. |
1387 | |
1388 | @@ -946,7 +970,8 @@ |
1389 | >>> new_credits.getExternallySuggestedTranslationMessages(spanish) |
1390 | [] |
1391 | |
1392 | -== POTMsgSet.setSequence == |
1393 | +POTMsgSet.setSequence |
1394 | +--------------------- |
1395 | |
1396 | Finally, the new `IPOTMsgSet` should have an entry in the |
1397 | `TranslationTemplateItem` table once we assign a sequence number. |
1398 | @@ -998,7 +1023,8 @@ |
1399 | 0 |
1400 | |
1401 | |
1402 | -== POTMsgSet.flags == |
1403 | +POTMsgSet.flags |
1404 | +--------------- |
1405 | |
1406 | The gettext format can associate flags with a POTMsgSet, such as "this |
1407 | is a fuzzily matched message" or "this message follows C format-string |
1408 | |
1409 | === modified file 'lib/lp/translations/doc/translationimportqueue.txt' |
1410 | --- lib/lp/translations/doc/translationimportqueue.txt 2010-07-13 21:49:34 +0000 |
1411 | +++ lib/lp/translations/doc/translationimportqueue.txt 2010-09-09 15:34:46 +0000 |
1412 | @@ -1,4 +1,5 @@ |
1413 | -= TranslationImportQueueEntry = |
1414 | +TranslationImportQueueEntry |
1415 | +=========================== |
1416 | |
1417 | The TranslationImportQueueEntry is an entry of the queue that will be imported |
1418 | into Rosetta. |
1419 | @@ -14,7 +15,8 @@ |
1420 | ... store.find(TranslationImportQueueEntry).remove() |
1421 | |
1422 | |
1423 | -== getGuessedPOFile == |
1424 | +getGuessedPOFile |
1425 | +---------------- |
1426 | |
1427 | This property gives us the IPOFile where we think we should import this entry. |
1428 | |
1429 | @@ -59,7 +61,8 @@ |
1430 | ... u'po/sr.po', 'foo', True, rosetta_experts, |
1431 | ... productseries=evolution_productseries) |
1432 | |
1433 | -This entry has no information about the IPOFile where it should be attached to: |
1434 | +This entry has no information about the IPOFile where it should be attached |
1435 | +to: |
1436 | |
1437 | >>> entry.import_into is None |
1438 | True |
1439 | @@ -82,7 +85,8 @@ |
1440 | ... sourcepackagename=evolution_sourcepackagename) |
1441 | >>> transaction.commit() |
1442 | |
1443 | -This entry has no information about the IPOFile where it should be attached to: |
1444 | +This entry has no information about the IPOFile where it should be attached |
1445 | +to: |
1446 | |
1447 | >>> entry.import_into is None |
1448 | True |
1449 | @@ -225,7 +229,8 @@ |
1450 | >>> pofile.path |
1451 | u'po/sr.po' |
1452 | |
1453 | -=== getGuessedPOFile with KDE === |
1454 | +getGuessedPOFile with KDE |
1455 | +......................... |
1456 | |
1457 | Official KDE packages have a non standard layout where the .pot files are |
1458 | stored inside the sourcepackage with the binaries that will use it and the |
1459 | @@ -363,7 +368,8 @@ |
1460 | >>> transaction.abort() |
1461 | |
1462 | |
1463 | -=== getGuessedPOFile with KOffice === |
1464 | +getGuessedPOFile with KOffice |
1465 | +............................. |
1466 | |
1467 | Like official KDE packages, KOffice stores the .pot and .po files in different |
1468 | packages, the only difference it has is that there is just one source package |
1469 | @@ -403,7 +409,9 @@ |
1470 | |
1471 | And set this entry as already imported. |
1472 | |
1473 | - >>> koffice_pot_entry.setStatus(RosettaImportStatus.IMPORTED, rosetta_experts) |
1474 | + >>> koffice_pot_entry.setStatus( |
1475 | + ... RosettaImportStatus.IMPORTED, |
1476 | + ... rosetta_experts) |
1477 | >>> flush_database_updates() |
1478 | |
1479 | Let's attach a .po file from koffice-l10n |
1480 | @@ -449,7 +457,8 @@ |
1481 | >>> transaction.abort() |
1482 | |
1483 | |
1484 | -=== getGuessedPOFile with .po files in different directories === |
1485 | +getGuessedPOFile with .po files in different directories |
1486 | +........................................................ |
1487 | |
1488 | Some packages have translations and templates inside the same package, but |
1489 | they don't have them inside the same directory. The layout is: |
1490 | @@ -500,7 +509,9 @@ |
1491 | |
1492 | And set this entry as already imported. |
1493 | |
1494 | - >>> adept_pot_entry.setStatus(RosettaImportStatus.IMPORTED, rosetta_experts) |
1495 | + >>> adept_pot_entry.setStatus( |
1496 | + ... RosettaImportStatus.IMPORTED, |
1497 | + ... rosetta_experts) |
1498 | >>> flush_database_updates() |
1499 | |
1500 | Let's attach a .po file now. |
1501 | @@ -551,7 +562,9 @@ |
1502 | |
1503 | And set this entry as already imported. |
1504 | |
1505 | - >>> ktorrent_pot_entry.setStatus(RosettaImportStatus.IMPORTED, rosetta_experts) |
1506 | + >>> ktorrent_pot_entry.setStatus( |
1507 | + ... RosettaImportStatus.IMPORTED, |
1508 | + ... rosetta_experts) |
1509 | >>> flush_database_updates() |
1510 | |
1511 | Let's attach a .po file now. |
1512 | @@ -739,7 +752,8 @@ |
1513 | >>> transaction.abort() |
1514 | |
1515 | |
1516 | -== executeOptimisticBlock == |
1517 | +executeOptimisticBlock |
1518 | +---------------------- |
1519 | |
1520 | This method looks on the queue to find entries to block based on other .pot |
1521 | entries that are stored on the same directory and are already blocked. |
1522 | @@ -803,7 +817,8 @@ |
1523 | True |
1524 | |
1525 | On the other hand, this other one is for the same |
1526 | -distroseries/sourcepackagename than the .pot file we have so it's also blocked. |
1527 | +distroseries/sourcepackagename than the .pot file we have so it's also |
1528 | +blocked. |
1529 | |
1530 | >>> entry4 = translationimportqueue.get(4) |
1531 | >>> entry4.path |
1532 | @@ -820,7 +835,8 @@ |
1533 | True |
1534 | |
1535 | |
1536 | -== getElapsedTimeText == |
1537 | +getElapsedTimeText |
1538 | +----------------- |
1539 | |
1540 | This method returns a string representing the elapsed time since the entry |
1541 | was added to the queue. |
1542 | @@ -860,13 +876,15 @@ |
1543 | '2 days 13 hours 5 minutes ago' |
1544 | |
1545 | |
1546 | -= TranslationImportQueue = |
1547 | +TranslationImportQueue |
1548 | +====================== |
1549 | |
1550 | The translation import queue is the place where the new translation imports |
1551 | end before being imported into Rosetta. |
1552 | |
1553 | |
1554 | -== getTemplatesOnSameDirectory == |
1555 | +getTemplatesOnSameDirectory |
1556 | +--------------------------- |
1557 | |
1558 | This method allows us to get the set of .pot files we have on the same |
1559 | directory that a given entry. |
1560 | @@ -905,7 +923,8 @@ |
1561 | 0 |
1562 | |
1563 | |
1564 | -== getRequestTargets == |
1565 | +getRequestTargets |
1566 | +----------------- |
1567 | |
1568 | >>> # Helper functions |
1569 | >>> def get_target_names(status=None): |
1570 | @@ -1069,7 +1088,8 @@ |
1571 | firefox Mozilla Firefox |
1572 | ubuntu/hoary Hoary |
1573 | |
1574 | -== addOrUpdateEntry() == |
1575 | +addOrUpdateEntry() |
1576 | +------------------ |
1577 | |
1578 | addOrUpdateEntry adds a new entry to the import queue so we can handle it |
1579 | later with poimport script. |
1580 | @@ -1264,7 +1284,8 @@ |
1581 | >>> print entry.content.read() |
1582 | New bar content |
1583 | |
1584 | -= Filename filters = |
1585 | +Filename filters |
1586 | +================ |
1587 | |
1588 | A tarball doesn't always have everything in quite the right place. If |
1589 | you need to manipulate the file paths within a tarball before the files |
1590 | @@ -1307,7 +1328,8 @@ |
1591 | netapplet | None | new-directory/fr.po |
1592 | |
1593 | |
1594 | -= Invalid data = |
1595 | +Invalid data |
1596 | +============ |
1597 | |
1598 | If administrators fail to correct certain errors in requests while approving |
1599 | them, and the admin user interface mistakenly accepts the approval, we may |
1600 | @@ -1385,7 +1407,8 @@ |
1601 | >>> clear_queue(translationimportqueue) |
1602 | |
1603 | |
1604 | -== getRequestTargets output ordering == |
1605 | +getRequestTargets output ordering |
1606 | +--------------------------------- |
1607 | |
1608 | The queue is populated with a wild mix of requests: for packages in |
1609 | different release series of Ubuntu, for packages in different distros, |
1610 | @@ -1472,7 +1495,8 @@ |
1611 | evolution Evolution |
1612 | |
1613 | |
1614 | -== cleanUpQueue == |
1615 | +cleanUpQueue |
1616 | +------------ |
1617 | |
1618 | The queue is cleaned up regularly. |
1619 | |
1620 | @@ -1489,7 +1513,8 @@ |
1621 | 0 |
1622 | |
1623 | |
1624 | -=== State and Age === |
1625 | +State and Age |
1626 | +............. |
1627 | |
1628 | Entries can be cleaned up because they have been in a specific state for |
1629 | at least a specified period of time. |
1630 | @@ -1516,18 +1541,22 @@ |
1631 | >>> print_queue_entries(translationimportqueue) |
1632 | |
1633 | |
1634 | -=== Deactivated Products === |
1635 | +Deactivated Products |
1636 | +.................... |
1637 | |
1638 | Another reason for deleting entries is that they belong to products that |
1639 | have been deactivated. |
1640 | |
1641 | A user sets up Jokosher for translation, and uploads a template. |
1642 | |
1643 | + >>> from lp.app.enums import ServiceUsage |
1644 | + |
1645 | >>> jokosher = productset['jokosher'] |
1646 | >>> jokosher_trunk = jokosher.getSeries('trunk') |
1647 | - >>> jokosher.official_rosetta = True |
1648 | + >>> jokosher.translations_usage = ServiceUsage.LAUNCHPAD |
1649 | >>> syncUpdate(jokosher) |
1650 | - >>> jokosher_subset = potemplateset.getSubset(productseries=jokosher_trunk) |
1651 | + >>> jokosher_subset = potemplateset.getSubset( |
1652 | + ... productseries=jokosher_trunk) |
1653 | >>> template = jokosher_subset.new( |
1654 | ... 'jokosher', 'jokosher', 'jokosher.pot', rosetta_experts) |
1655 | >>> syncUpdate(template) |
1656 | |
1657 | === modified file 'lib/lp/translations/doc/translationmessage-destroy.txt' |
1658 | --- lib/lp/translations/doc/translationmessage-destroy.txt 2009-07-02 17:16:50 +0000 |
1659 | +++ lib/lp/translations/doc/translationmessage-destroy.txt 2010-09-09 15:34:46 +0000 |
1660 | @@ -1,4 +1,5 @@ |
1661 | -== destroySelf == |
1662 | +destroySelf |
1663 | +=========== |
1664 | |
1665 | (Note: this test runs as rosettaadmin to obtain the necessary |
1666 | privileges) |
1667 | @@ -26,7 +27,8 @@ |
1668 | SQLObjectNotFound:... |
1669 | |
1670 | |
1671 | -== POFileTranslator update on remove == |
1672 | +POFileTranslator update on remove |
1673 | +================================= |
1674 | |
1675 | In two sharing POTemplates with one shared POTMsgSet with one shared |
1676 | translation, we get two POFileTranslator records for each of the POFiles. |
1677 | @@ -35,16 +37,17 @@ |
1678 | >>> # a global 'postgres' permission which allows everything. |
1679 | >>> LaunchpadZopelessLayer.switchDbUser('postgres') |
1680 | >>> from canonical.database.sqlbase import sqlvalues |
1681 | + >>> from lp.app.enums import ServiceUsage |
1682 | >>> from lp.translations.model.pofiletranslator import POFileTranslator |
1683 | >>> from lp.testing.factory import LaunchpadObjectFactory |
1684 | >>> factory = LaunchpadObjectFactory() |
1685 | |
1686 | - >>> foo = factory.makeProduct() |
1687 | + >>> foo = factory.makeProduct( |
1688 | + ... translations_usage=ServiceUsage.LAUNCHPAD) |
1689 | >>> foo_devel = factory.makeProductSeries( |
1690 | ... name='devel', product=foo) |
1691 | >>> foo_stable = factory.makeProductSeries( |
1692 | ... name='stable', product=foo) |
1693 | - >>> foo.official_rosetta = True |
1694 | >>> devel_potemplate = factory.makePOTemplate( |
1695 | ... productseries=foo_devel, name="messages") |
1696 | >>> stable_potemplate = factory.makePOTemplate(foo_stable, |
1697 | @@ -56,7 +59,9 @@ |
1698 | >>> potmsgset = factory.makePOTMsgSet(devel_potemplate, sequence=1) |
1699 | >>> potmsgset.setSequence(stable_potemplate, 1) |
1700 | >>> tm = factory.makeTranslationMessage( |
1701 | - ... pofile=devel_sr_pofile, potmsgset=potmsgset, translations=[u"blah"]) |
1702 | + ... pofile=devel_sr_pofile, |
1703 | + ... potmsgset=potmsgset, |
1704 | + ... translations=[u"blah"]) |
1705 | >>> print POFileTranslator.select( |
1706 | ... "latest_message=%s" % sqlvalues(tm)).count() |
1707 | 2 |
1708 | |
1709 | === modified file 'lib/lp/translations/doc/translations-export-to-branch.txt' |
1710 | --- lib/lp/translations/doc/translations-export-to-branch.txt 2010-07-20 17:50:45 +0000 |
1711 | +++ lib/lp/translations/doc/translations-export-to-branch.txt 2010-09-09 15:34:46 +0000 |
1712 | @@ -1,4 +1,5 @@ |
1713 | -= Exporting translations to a bzr branch = |
1714 | +Exporting translations to a bzr branch |
1715 | +====================================== |
1716 | |
1717 | The translations-export-to-branch script visits all ProductSeries with a |
1718 | translations_branch set, and for each, exports the series' translations |
1719 | @@ -76,10 +77,11 @@ |
1720 | branch. |
1721 | |
1722 | >>> from zope.security.proxy import removeSecurityProxy |
1723 | + >>> from lp.app.enums import ServiceUsage |
1724 | |
1725 | >>> gazblachko = removeSecurityProxy(factory.makeProduct( |
1726 | ... name='gazblachko', displayname='Gazblachko')) |
1727 | - >>> gazblachko.official_rosetta = True |
1728 | + >>> gazblachko.translations_usage = ServiceUsage.LAUNCHPAD |
1729 | |
1730 | >>> branch = removeSecurityProxy(factory.makeBranch( |
1731 | ... name='gazpo', owner=gazblachko.owner, product=gazblachko)) |
1732 | @@ -162,13 +164,13 @@ |
1733 | When Gazblachko stops using Launchpad for Translations, the exports stop |
1734 | also. |
1735 | |
1736 | - >>> gazblachko.official_rosetta = False |
1737 | + >>> gazblachko.translations_usage = ServiceUsage.NOT_APPLICABLE |
1738 | >>> transaction.commit() |
1739 | >>> script.main() |
1740 | INFO Exporting to translations branches. |
1741 | INFO Processed 0 item(s); 0 failure(s), 0 unpushed branch(es). |
1742 | |
1743 | - >>> gazblachko.official_rosetta = True |
1744 | + >>> gazblachko.translations_usage = ServiceUsage.LAUNCHPAD |
1745 | >>> transaction.commit() |
1746 | |
1747 | |
1748 | @@ -271,7 +273,8 @@ |
1749 | collected for import yet. |
1750 | |
1751 | |
1752 | -=== Branch races === |
1753 | +Branch races |
1754 | +............ |
1755 | |
1756 | Any translations coming in through a branch push are safe once they're |
1757 | in the translations import queue. So the race window spans from the |
1758 | @@ -299,7 +302,8 @@ |
1759 | INFO Processed 1 item(s); 1 failure(s), 0 unpushed branch(es). |
1760 | |
1761 | |
1762 | -=== Pending imports from same branch === |
1763 | +Pending imports from same branch |
1764 | +................................ |
1765 | |
1766 | Another race condition is detected by the script itself: there may be |
1767 | pending translations BranchJobs on the branch. |
1768 | |
1769 | === modified file 'lib/lp/translations/doc/translationsoverview.txt' |
1770 | --- lib/lp/translations/doc/translationsoverview.txt 2009-07-24 12:55:03 +0000 |
1771 | +++ lib/lp/translations/doc/translationsoverview.txt 2010-09-09 15:34:46 +0000 |
1772 | @@ -1,4 +1,5 @@ |
1773 | -= TranslationsOverview = |
1774 | +TranslationsOverview |
1775 | +==================== |
1776 | |
1777 | This class provides a basic overview of the Launchpad Translations component. |
1778 | It includes data such as projects which have so far received the most |
1779 | @@ -45,14 +46,16 @@ |
1780 | 18 |
1781 | |
1782 | |
1783 | -== _normalizeSizes == |
1784 | +_normalizeSizes |
1785 | +--------------- |
1786 | |
1787 | This private method accepts a list of tuples (object, size) and |
1788 | normalizes `size` values into the range [MINIMUM_SIZE, MAXIMUM_SIZE]. |
1789 | |
1790 | >>> test_list = [('one', 3), ('two', 0), ('three', 1)] |
1791 | >>> from zope.security.proxy import removeSecurityProxy |
1792 | - >>> result = removeSecurityProxy(overview)._normalizeSizes(test_list, 0, 3) |
1793 | + >>> naked_overview = removeSecurityProxy(overview) |
1794 | + >>> result = naked_overview._normalizeSizes(test_list, 0, 3) |
1795 | >>> for pillar in result: |
1796 | ... print "%s: %d" % (pillar['pillar'], pillar['weight']) |
1797 | one: 18 |
1798 | @@ -60,7 +63,8 @@ |
1799 | three: 13 |
1800 | |
1801 | |
1802 | -== Getting the most translated pillars == |
1803 | +Getting the most translated pillars |
1804 | +----------------------------------- |
1805 | |
1806 | Method getMostTranslatedPillars() returns a list of dicts listing |
1807 | pillars with most translations karma so far, along with a relative |
1808 | @@ -104,10 +108,13 @@ |
1809 | |
1810 | Adding a little bit of karma to upstart will put it in the list as well. |
1811 | |
1812 | + >>> from lp.app.enums import ServiceUsage |
1813 | + |
1814 | >>> start_karma_update() |
1815 | >>> upstart = product_set.getByName('upstart') |
1816 | >>> upstart_id = upstart.id |
1817 | - >>> removeSecurityProxy(upstart).official_rosetta = True |
1818 | + >>> naked_upstart = removeSecurityProxy(upstart) |
1819 | + >>> naked_upstart.translations_usage = ServiceUsage.LAUNCHPAD |
1820 | >>> cache_entry = karmacachemanager.new( |
1821 | ... 50, carlos.id, translations.id, product_id=upstart_id) |
1822 | >>> finish_karma_update() |
1823 | @@ -153,7 +160,8 @@ |
1824 | Ubuntu: 24 |
1825 | |
1826 | |
1827 | -== Zero karma == |
1828 | +Zero karma |
1829 | +---------- |
1830 | |
1831 | Sometimes a pillar appears to be listed in the karma cache with zero |
1832 | karma. Our algorithm takes the logarithm of its karma, but it's |
1833 | |
1834 | === modified file 'lib/lp/translations/model/potemplate.py' |
1835 | --- lib/lp/translations/model/potemplate.py 2010-09-03 03:12:39 +0000 |
1836 | +++ lib/lp/translations/model/potemplate.py 2010-09-09 15:34:46 +0000 |
1837 | @@ -64,6 +64,7 @@ |
1838 | IMasterStore, |
1839 | IStore, |
1840 | ) |
1841 | +from lp.app.enums import service_uses_launchpad |
1842 | from lp.app.errors import NotFoundError |
1843 | from lp.registry.interfaces.person import validate_public_person |
1844 | from lp.registry.model.sourcepackagename import SourcePackageName |
1845 | @@ -1322,8 +1323,7 @@ |
1846 | preferred_matches = [ |
1847 | match |
1848 | for match in matches |
1849 | - if match.from_sourcepackagename == sourcepackagename |
1850 | - ] |
1851 | + if match.from_sourcepackagename == sourcepackagename] |
1852 | |
1853 | if len(preferred_matches) == 1: |
1854 | return preferred_matches[0] |
1855 | @@ -1378,6 +1378,9 @@ |
1856 | |
1857 | def populateSuggestivePOTemplatesCache(self): |
1858 | """See `IPOTemplateSet`.""" |
1859 | + # XXX j.c.sackett 2010-08-30 bug=627631 Once data migration has |
1860 | + # happened for the usage enums, this sql needs to be updated to |
1861 | + # check for the translations_usage, not official_rosetta. |
1862 | return IMasterStore(POTemplate).execute(""" |
1863 | INSERT INTO SuggestivePOTemplate ( |
1864 | SELECT POTemplate.id |
1865 | @@ -1437,15 +1440,13 @@ |
1866 | if self.product: |
1867 | subsets = [ |
1868 | self.potemplateset.getSubset(productseries=series) |
1869 | - for series in self.product.series |
1870 | - ] |
1871 | + for series in self.product.series] |
1872 | else: |
1873 | subsets = [ |
1874 | self.potemplateset.getSubset( |
1875 | distroseries=series, |
1876 | sourcepackagename=self.sourcepackagename) |
1877 | - for series in self.distribution.series |
1878 | - ] |
1879 | + for series in self.distribution.series] |
1880 | for subset in subsets: |
1881 | for template in subset: |
1882 | if name_pattern is None or re.match(name_pattern, |
1883 | @@ -1548,8 +1549,7 @@ |
1884 | msgset.flags = set([ |
1885 | flag.strip() |
1886 | for flag in row.flags_comment.split(',') |
1887 | - if flag |
1888 | - ]) |
1889 | + if flag]) |
1890 | |
1891 | # Store the message. |
1892 | messages.append(msgset) |
1893 | @@ -1578,8 +1578,9 @@ |
1894 | collection = self.getTemplatesCollection() |
1895 | |
1896 | # XXX JeroenVermeulen 2010-07-15 bug=605924: Move the |
1897 | - # official_rosetta distinction into browser code. |
1898 | - if collection.target_pillar.official_rosetta: |
1899 | + # translations_usage distinction into browser code. |
1900 | + pillar = collection.target_pillar |
1901 | + if service_uses_launchpad(pillar.translations_usage): |
1902 | return collection.restrictCurrent(current_value) |
1903 | else: |
1904 | # Product/Distribution does not have translation enabled. |
1905 | |
1906 | === modified file 'lib/lp/translations/model/potmsgset.py' |
1907 | --- lib/lp/translations/model/potmsgset.py 2010-09-06 03:35:47 +0000 |
1908 | +++ lib/lp/translations/model/potmsgset.py 2010-09-09 15:34:46 +0000 |
1909 | @@ -361,6 +361,9 @@ |
1910 | query = ["(NOT %s)" % in_use_clause] |
1911 | query.append('TranslationMessage.language = %s' % sqlvalues(language)) |
1912 | |
1913 | + # XXX j.c.sackett 2010-08-30 bug=627631 Once data migration has |
1914 | + # happened for the usage enums, this sql needs to be updated |
1915 | + # to check for the translations_usage, not official_rosetta. |
1916 | query.append(''' |
1917 | potmsgset IN ( |
1918 | SELECT POTMsgSet.id |
1919 | @@ -381,7 +384,8 @@ |
1920 | POTMsgSet.id <> %s AND |
1921 | msgid_singular = %s AND |
1922 | POTemplate.iscurrent AND |
1923 | - (Product.official_rosetta OR Distribution.official_rosetta) |
1924 | + (Product.official_rosetta OR |
1925 | + Distribution.official_rosetta) |
1926 | )''' % sqlvalues(self, self.msgid_singular)) |
1927 | |
1928 | # Subquery to find the ids of TranslationMessages that are |
1929 | @@ -396,8 +400,8 @@ |
1930 | for form in xrange(TranslationConstants.MAX_PLURAL_FORMS)]) |
1931 | ids_query_params = { |
1932 | 'msgstrs': msgstrs, |
1933 | - 'where': ' AND '.join(query) |
1934 | - } |
1935 | + 'where': ' AND '.join(query), |
1936 | + } |
1937 | ids_query = ''' |
1938 | SELECT DISTINCT ON (%(msgstrs)s) |
1939 | TranslationMessage.id |
1940 | @@ -565,8 +569,7 @@ |
1941 | # plural forms. |
1942 | order.extend([ |
1943 | 'msgstr%s NULLS FIRST' % quote(form) |
1944 | - for form in remaining_plural_forms |
1945 | - ]) |
1946 | + for form in remaining_plural_forms]) |
1947 | matches = list( |
1948 | TranslationMessage.select(' AND '.join(clauses), orderBy=order)) |
1949 | |
1950 | @@ -722,7 +725,6 @@ |
1951 | if is_imported or new_message == imported_message: |
1952 | new_message.is_imported = True |
1953 | |
1954 | - |
1955 | def _isTranslationMessageASuggestion(self, force_suggestion, |
1956 | pofile, submitter, |
1957 | force_edition_rights, is_imported, |
1958 | @@ -1178,4 +1180,3 @@ |
1959 | """See `IPOTMsgSet`.""" |
1960 | return TranslationTemplateItem.selectBy( |
1961 | potmsgset=self, orderBy=['id']) |
1962 | - |
1963 | |
1964 | === modified file 'lib/lp/translations/model/translationsoverview.py' |
1965 | --- lib/lp/translations/model/translationsoverview.py 2010-08-20 20:31:18 +0000 |
1966 | +++ lib/lp/translations/model/translationsoverview.py 2010-09-09 15:34:46 +0000 |
1967 | @@ -39,13 +39,15 @@ |
1968 | new_size = int(round( |
1969 | real_minimum + |
1970 | (size - offset - real_minimum) * multiplier)) |
1971 | - normalized_sizes.append({'pillar' : pillar, |
1972 | - 'weight' : new_size }) |
1973 | + normalized_sizes.append({'pillar': pillar, 'weight': new_size}) |
1974 | return normalized_sizes |
1975 | |
1976 | def getMostTranslatedPillars(self, limit=50): |
1977 | """See `ITranslationsOverview`.""" |
1978 | |
1979 | + # XXX j.c.sackett 2010-08-30 bug=627631 Once data migration has |
1980 | + # happened for the usage enums, this sql needs to be updated |
1981 | + # to check for the translations_usage, not official_rosetta. |
1982 | query = """ |
1983 | SELECT LOWER(COALESCE(product_name, distro_name)) AS name, |
1984 | product_id, |
1985 | @@ -65,7 +67,8 @@ |
1986 | distribution=distribution.id |
1987 | WHERE category=3 AND |
1988 | (product IS NOT NULL OR distribution IS NOT NULL) AND |
1989 | - (product.official_rosetta OR distribution.official_rosetta) |
1990 | + (product.official_rosetta OR |
1991 | + distribution.official_rosetta) |
1992 | GROUP BY product.displayname, product.id, |
1993 | distribution.displayname, distribution.id |
1994 | HAVING SUM(karmavalue) > 0 |
1995 | |
1996 | === modified file 'lib/lp/translations/model/translationsperson.py' |
1997 | --- lib/lp/translations/model/translationsperson.py 2010-08-27 10:53:40 +0000 |
1998 | +++ lib/lp/translations/model/translationsperson.py 2010-09-09 15:34:46 +0000 |
1999 | @@ -262,6 +262,10 @@ |
2000 | The added joins may make the overall query non-distinct, so be |
2001 | sure to enforce distinctness. |
2002 | """ |
2003 | + # XXX j.c.sackett 2010-08-30 bug=627631 Once data migration has |
2004 | + # happened for the usage enums, this query needs to be updated |
2005 | + # to check for the translations_usage, not official_rosetta. |
2006 | + |
2007 | POTemplateJoin = Join(POTemplate, And( |
2008 | POTemplate.id == POFile.potemplateID, |
2009 | POTemplate.iscurrent == True)) |
2010 | |
2011 | === modified file 'lib/lp/translations/scripts/translations_to_branch.py' |
2012 | --- lib/lp/translations/scripts/translations_to_branch.py 2010-08-20 20:31:18 +0000 |
2013 | +++ lib/lp/translations/scripts/translations_to_branch.py 2010-09-09 15:34:46 +0000 |
2014 | @@ -306,6 +306,9 @@ |
2015 | |
2016 | self.store = getUtility(IStoreSelector).get(MAIN_STORE, SLAVE_FLAVOR) |
2017 | |
2018 | + # XXX j.c.sackett 2010-08-30 bug=627631 Once data migration has |
2019 | + # happened for the usage enums, this sql needs to be updated to |
2020 | + # check for the translations_usage, not official_rosetta. |
2021 | product_join = Join( |
2022 | ProductSeries, Product, ProductSeries.product == Product.id) |
2023 | productseries = self.store.using(product_join).find( |
2024 | |
2025 | === modified file 'lib/lp/translations/stories/buildfarm/xx-build-summary.txt' |
2026 | --- lib/lp/translations/stories/buildfarm/xx-build-summary.txt 2010-07-20 17:50:45 +0000 |
2027 | +++ lib/lp/translations/stories/buildfarm/xx-build-summary.txt 2010-09-09 15:34:46 +0000 |
2028 | @@ -1,9 +1,11 @@ |
2029 | -= TranslationTemplatesBuildJob Build Summary = |
2030 | +TranslationTemplatesBuildJob Build Summary |
2031 | +========================================== |
2032 | |
2033 | The builders UI can show TranslationTemplateBuildJobs, although they |
2034 | look a little different from Soyuz-style jobs. |
2035 | |
2036 | -== Setup == |
2037 | +Setup |
2038 | +----- |
2039 | |
2040 | Create a builder working on a TranslationTemplatesBuildJob for a branch. |
2041 | |
2042 | @@ -13,6 +15,7 @@ |
2043 | >>> from canonical.launchpad.interfaces.librarian import ( |
2044 | ... ILibraryFileAliasSet) |
2045 | >>> from canonical.launchpad.scripts.logger import QuietFakeLogger |
2046 | + >>> from lp.app.enums import ServiceUsage |
2047 | >>> from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
2048 | >>> from lp.testing.factory import ( |
2049 | ... remove_security_proxy_and_shout_at_engineer) |
2050 | @@ -32,7 +35,7 @@ |
2051 | >>> productseries = factory.makeProductSeries(owner=owner) |
2052 | >>> product = productseries.product |
2053 | >>> naked_product = remove_security_proxy_and_shout_at_engineer(product) |
2054 | - >>> naked_product.official_rosetta = True |
2055 | + >>> naked_product.translations_usage = ServiceUsage.LAUNCHPAD |
2056 | >>> branch = factory.makeProductBranch(product=product, owner=owner) |
2057 | >>> branch_url = branch.unique_name |
2058 | |
2059 | @@ -62,7 +65,8 @@ |
2060 | ... return find_tag_by_id(browser.contents, 'current-build-summary') |
2061 | |
2062 | |
2063 | -== Show summary == |
2064 | +Show summary |
2065 | +------------ |
2066 | |
2067 | The job's summary shows that what type of job this is. It also links |
2068 | to the branch. |
2069 | |
2070 | === modified file 'lib/lp/translations/stories/importqueue/xx-entry-details.txt' |
2071 | --- lib/lp/translations/stories/importqueue/xx-entry-details.txt 2010-03-11 20:54:36 +0000 |
2072 | +++ lib/lp/translations/stories/importqueue/xx-entry-details.txt 2010-09-09 15:34:46 +0000 |
2073 | @@ -1,9 +1,11 @@ |
2074 | -= Entry details = |
2075 | +Entry details |
2076 | +============= |
2077 | |
2078 | The translation import queue entry page shows various details about an |
2079 | entry and its target that may be helpful in queue review. |
2080 | |
2081 | >>> from zope.security.proxy import removeSecurityProxy |
2082 | + >>> from lp.app.enums import ServiceUsage |
2083 | >>> from lp.translations.model.translationimportqueue import ( |
2084 | ... TranslationImportQueue) |
2085 | |
2086 | @@ -11,8 +13,8 @@ |
2087 | |
2088 | >>> login(ANONYMOUS) |
2089 | >>> queue = TranslationImportQueue() |
2090 | - >>> product = factory.makeProduct() |
2091 | - >>> removeSecurityProxy(product).official_rosetta = True |
2092 | + >>> product = factory.makeProduct( |
2093 | + ... translations_usage=ServiceUsage.LAUNCHPAD) |
2094 | >>> trunk = product.getSeries('trunk') |
2095 | >>> uploader = factory.makePerson() |
2096 | >>> entry = queue.addOrUpdateEntry( |
2097 | @@ -47,7 +49,8 @@ |
2098 | http://...foo.pot |
2099 | |
2100 | |
2101 | -== Existing templates == |
2102 | +Existing templates |
2103 | +------------------ |
2104 | |
2105 | If there are translatable templates in the series, this will be stated |
2106 | and there will be a link to the templates list. |
2107 | @@ -81,7 +84,8 @@ |
2108 | ... |
2109 | |
2110 | |
2111 | -== Source packages == |
2112 | +Source packages |
2113 | +--------------- |
2114 | |
2115 | The portlet shows different (well, less) information for uploads |
2116 | attached to distribution packages. |
2117 | |
2118 | === modified file 'lib/lp/translations/stories/productseries/xx-productseries-export-to-branch.txt' |
2119 | --- lib/lp/translations/stories/productseries/xx-productseries-export-to-branch.txt 2009-09-02 16:35:54 +0000 |
2120 | +++ lib/lp/translations/stories/productseries/xx-productseries-export-to-branch.txt 2010-09-09 15:34:46 +0000 |
2121 | @@ -1,15 +1,16 @@ |
2122 | -= ProductSeries Translations Branch = |
2123 | +ProductSeries Translations Branch |
2124 | +================================= |
2125 | |
2126 | If a ProductSeries has its translations_branch set, Launchpad will |
2127 | periodically commit snapshots of the series' translations to that |
2128 | branch. |
2129 | |
2130 | - >>> from zope.security.proxy import removeSecurityProxy |
2131 | + >>> from lp.app.enums import ServiceUsage |
2132 | |
2133 | >>> login(ANONYMOUS) |
2134 | >>> owner = factory.makePerson(email='x@example.com', password='****') |
2135 | - >>> product = factory.makeProduct(owner=owner) |
2136 | - >>> removeSecurityProxy(product).official_rosetta = True |
2137 | + >>> product = factory.makeProduct(owner=owner, |
2138 | + ... translations_usage=ServiceUsage.LAUNCHPAD) |
2139 | >>> productseries = product.getSeries('trunk') |
2140 | >>> branch = factory.makeBranch(product=product, owner=owner) |
2141 | >>> branch_name = branch.name |
2142 | @@ -99,7 +100,8 @@ |
2143 | </div> |
2144 | |
2145 | |
2146 | -== Disabling exports == |
2147 | +Disabling exports |
2148 | +----------------- |
2149 | |
2150 | The field can also be cleared in order to disable the exports. |
2151 | |
2152 | @@ -125,7 +127,8 @@ |
2153 | None |
2154 | |
2155 | |
2156 | -== Security == |
2157 | +Security |
2158 | +-------- |
2159 | |
2160 | You can only set the translations_branch to a branch that you own. |
2161 | Otherwise you'd be giving Launchpad a blanket license to commit |
2162 | |
2163 | === modified file 'lib/lp/translations/stories/productseries/xx-productseries-translations.txt' |
2164 | --- lib/lp/translations/stories/productseries/xx-productseries-translations.txt 2010-03-31 20:25:33 +0000 |
2165 | +++ lib/lp/translations/stories/productseries/xx-productseries-translations.txt 2010-09-09 15:34:46 +0000 |
2166 | @@ -5,9 +5,10 @@ |
2167 | a single product series, or instructions on how to set up a series for |
2168 | translation. |
2169 | |
2170 | + >>> from lp.app.enums import ServiceUsage |
2171 | >>> login('foo.bar@canonical.com') |
2172 | - >>> frobnicator = factory.makeProduct(name='frobnicator') |
2173 | - >>> frobnicator.official_rosetta = True |
2174 | + >>> frobnicator = factory.makeProduct(name='frobnicator', |
2175 | + ... translations_usage=ServiceUsage.LAUNCHPAD) |
2176 | >>> frobnicator_trunk = frobnicator.getSeries('trunk') |
2177 | >>> frobnicator_trunk_url = canonical_url( |
2178 | ... frobnicator_trunk, rootsite='translations') |
2179 | @@ -148,7 +149,8 @@ |
2180 | |
2181 | # Use the raw DB object to bypass the security proxy. |
2182 | >>> from lp.registry.model.product import Product |
2183 | - >>> Product.byName('bazaar').official_rosetta = False |
2184 | + >>> product = Product.byName('bazaar') |
2185 | + >>> product.translations_usage = ServiceUsage.NOT_APPLICABLE |
2186 | |
2187 | When the owner now visits the upload page for trunk, there's a notice. |
2188 | |
2189 | |
2190 | === modified file 'lib/lp/translations/stories/standalone/custom-language-codes.txt' |
2191 | --- lib/lp/translations/stories/standalone/custom-language-codes.txt 2010-03-11 20:54:36 +0000 |
2192 | +++ lib/lp/translations/stories/standalone/custom-language-codes.txt 2010-09-09 15:34:46 +0000 |
2193 | @@ -11,11 +11,11 @@ |
2194 | Custom language codes are attached to either a product or a source |
2195 | package. |
2196 | |
2197 | - >>> import re |
2198 | >>> from zope.component import getUtility |
2199 | >>> from zope.security.proxy import removeSecurityProxy |
2200 | >>> from canonical.launchpad.interfaces.launchpad import ( |
2201 | ... ILaunchpadCelebrities) |
2202 | + >>> from lp.app.enums import ServiceUsage |
2203 | |
2204 | >>> def find_custom_language_codes_link(browser): |
2205 | ... """Find reference to custom language codes on a page.""" |
2206 | @@ -29,7 +29,8 @@ |
2207 | ... getUtility(ILaunchpadCelebrities).rosetta_experts) |
2208 | >>> product = factory.makeProduct(displayname="Foo", owner=owner) |
2209 | >>> trunk = product.getSeries('trunk') |
2210 | - >>> removeSecurityProxy(product).official_rosetta = True |
2211 | + >>> naked_product = removeSecurityProxy(product) |
2212 | + >>> naked_product.translations_usage = ServiceUsage.LAUNCHPAD |
2213 | >>> template = factory.makePOTemplate(productseries=trunk) |
2214 | >>> product_page = canonical_url(product, rootsite='translations') |
2215 | >>> logout() |
2216 | @@ -198,7 +199,8 @@ |
2217 | >>> sourcepackagename = SourcePackageName(name='bar') |
2218 | >>> package = factory.makeSourcePackage( |
2219 | ... sourcepackagename=sourcepackagename, distroseries=distroseries) |
2220 | - >>> removeSecurityProxy(distro).official_rosetta = True |
2221 | + >>> naked_distro = removeSecurityProxy(distro) |
2222 | + >>> naked_distro.translations_usage = ServiceUsage.LAUNCHPAD |
2223 | >>> other_series = factory.makeDistroRelease(distribution=distro) |
2224 | >>> template = factory.makePOTemplate( |
2225 | ... distroseries=package.distroseries, |
2226 | |
2227 | === modified file 'lib/lp/translations/stories/standalone/xx-potemplate-index.txt' |
2228 | --- lib/lp/translations/stories/standalone/xx-potemplate-index.txt 2010-02-16 21:21:14 +0000 |
2229 | +++ lib/lp/translations/stories/standalone/xx-potemplate-index.txt 2010-09-09 15:34:46 +0000 |
2230 | @@ -6,7 +6,7 @@ |
2231 | ----------- |
2232 | |
2233 | The index page for a POTemplate lists all available translations |
2234 | -for a source package. No Privileges Person visits the |
2235 | +for a source package. No Privileges Person visits the |
2236 | evolution-2.2 POTemplate page. |
2237 | |
2238 | >>> anon_browser.open("http://translations.launchpad.dev/" |
2239 | @@ -85,7 +85,7 @@ |
2240 | </p> |
2241 | |
2242 | |
2243 | -DistroSeries and ProductSeries links to related templates |
2244 | +DistroSeries and ProductSeries links to related templates |
2245 | --------------------------------------------------------- |
2246 | |
2247 | We are presented not only with links to alternate templates from the same |
2248 | @@ -117,8 +117,8 @@ |
2249 | A source package with five templates is created. |
2250 | |
2251 | >>> from zope.component import getUtility |
2252 | - >>> from canonical.launchpad.interfaces.launchpad import ( |
2253 | - ... ILaunchpadCelebrities) |
2254 | + >>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities |
2255 | + |
2256 | >>> login('admin@canonical.com') |
2257 | >>> ubuntu = getUtility(ILaunchpadCelebrities).ubuntu |
2258 | >>> hoary = ubuntu.getSeries('hoary') |
2259 | @@ -212,8 +212,10 @@ |
2260 | >>> from zope.component import getUtility |
2261 | >>> from canonical.launchpad.interfaces.launchpad import ( |
2262 | ... ILaunchpadCelebrities) |
2263 | + >>> from lp.app.enums import ServiceUsage |
2264 | >>> login('admin@canonical.com') |
2265 | - >>> product = factory.makeProduct(name="fusa", official_rosetta=True) |
2266 | + >>> product = factory.makeProduct(name="fusa", |
2267 | + ... translations_usage=ServiceUsage.LAUNCHPAD) |
2268 | >>> product_trunk = product.getSeries('trunk') |
2269 | >>> template = factory.makePOTemplate( |
2270 | ... productseries=product_trunk, name='first') |
2271 | @@ -253,7 +255,9 @@ |
2272 | Anonymous visitors see only a list of all existing templates, with no |
2273 | administration or download/upload links. |
2274 | |
2275 | - >>> anon_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2276 | + >>> anon_browser.open( |
2277 | + ... 'http://translations.launchpad.dev/' |
2278 | + ... 'ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2279 | >>> anon_browser.getLink('upload') |
2280 | Traceback (most recent call last): |
2281 | ... |
2282 | @@ -267,7 +271,9 @@ |
2283 | As an authenticated user, you should see the download link, |
2284 | but not the one for uploading file to this potemplate. |
2285 | |
2286 | - >>> user_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2287 | + >>> user_browser.open( |
2288 | + ... 'http://translations.launchpad.dev/' |
2289 | + ... 'ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2290 | >>> user_browser.getLink('upload') |
2291 | Traceback (most recent call last): |
2292 | ... |
2293 | @@ -281,27 +287,37 @@ |
2294 | Beside administering this template, "Change permissions" |
2295 | and "Change details" should be also accessible. |
2296 | |
2297 | - >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2298 | + >>> admin_browser.open( |
2299 | + ... 'http://translations.launchpad.dev/' |
2300 | + ... 'ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2301 | >>> admin_browser.getLink('upload').click() |
2302 | >>> print admin_browser.url |
2303 | http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+upload |
2304 | |
2305 | - >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2306 | + >>> admin_browser.open( |
2307 | + ... 'http://translations.launchpad.dev/' |
2308 | + ... 'ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2309 | >>> admin_browser.getLink('download').click() |
2310 | >>> print admin_browser.url |
2311 | http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+export |
2312 | |
2313 | - >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2314 | + >>> admin_browser.open( |
2315 | + ... 'http://translations.launchpad.dev/' |
2316 | + ... 'ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2317 | >>> admin_browser.getLink('Administer this template').click() |
2318 | >>> print admin_browser.url |
2319 | http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+admin |
2320 | |
2321 | - >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2322 | + >>> admin_browser.open( |
2323 | + ... 'http://translations.launchpad.dev/' |
2324 | + ... 'ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2325 | >>> admin_browser.getLink('Change details').click() |
2326 | >>> print admin_browser.url |
2327 | http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+edit |
2328 | |
2329 | - >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2330 | + >>> admin_browser.open( |
2331 | + ... 'http://translations.launchpad.dev/' |
2332 | + ... 'ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
2333 | >>> admin_browser.getLink('Change permissions').click() |
2334 | >>> print admin_browser.url |
2335 | http://translations.launchpad.dev/ubuntu/+settings |
2336 | |
2337 | === modified file 'lib/lp/translations/stories/standalone/xx-product-export.txt' |
2338 | --- lib/lp/translations/stories/standalone/xx-product-export.txt 2009-09-18 15:42:19 +0000 |
2339 | +++ lib/lp/translations/stories/standalone/xx-product-export.txt 2010-09-09 15:34:46 +0000 |
2340 | @@ -1,4 +1,5 @@ |
2341 | -= Downloading Product Series Translations = |
2342 | +Downloading Product Series Translations |
2343 | +======================================= |
2344 | |
2345 | Products and product series that use Translations offer complete |
2346 | translation downloads. |
2347 | @@ -33,16 +34,18 @@ |
2348 | Your request has been received. Expect to receive an email shortly. |
2349 | |
2350 | |
2351 | -== Use of Launchpad Translations == |
2352 | +Use of Launchpad Translations |
2353 | +----------------------------- |
2354 | |
2355 | The Download link is not shown if the product does not use Launchpad |
2356 | Translations. |
2357 | |
2358 | # Use the DB classes directly to avoid having to setup a zope interaction |
2359 | # (i.e. login()) and bypass the security proxy. |
2360 | + >>> from lp.app.enums import ServiceUsage |
2361 | >>> from lp.registry.model.product import Product |
2362 | >>> product = Product.byName('evolution') |
2363 | - >>> product.official_rosetta = False |
2364 | + >>> product.translations_usage = ServiceUsage.NOT_APPLICABLE |
2365 | >>> product.sync() |
2366 | >>> user_browser.open('http://translations.launchpad.dev/evolution') |
2367 | >>> user_browser.getLink('download') |
2368 | @@ -51,14 +54,15 @@ |
2369 | LinkNotFoundError |
2370 | |
2371 | >>> # Restore previous state for subsequent tests, and verify |
2372 | - >>> product.official_rosetta = True |
2373 | + >>> product.translations_usage = ServiceUsage.LAUNCHPAD |
2374 | >>> product.sync() |
2375 | >>> user_browser.open('http://translations.launchpad.dev/evolution') |
2376 | >>> user_browser.getLink('download') is not None |
2377 | True |
2378 | |
2379 | |
2380 | -== Authorization == |
2381 | +Authorization |
2382 | +------------- |
2383 | |
2384 | Only logged-in users get the option to request downloads. |
2385 | |
2386 | |
2387 | === modified file 'lib/lp/translations/stories/standalone/xx-product-translations.txt' |
2388 | --- lib/lp/translations/stories/standalone/xx-product-translations.txt 2010-08-25 00:01:57 +0000 |
2389 | +++ lib/lp/translations/stories/standalone/xx-product-translations.txt 2010-09-09 15:34:46 +0000 |
2390 | @@ -1,4 +1,3 @@ |
2391 | -==================== |
2392 | Product Translations |
2393 | ==================== |
2394 | |
2395 | |
2396 | === modified file 'lib/lp/translations/stories/standalone/xx-template-description-escaping.txt' |
2397 | --- lib/lp/translations/stories/standalone/xx-template-description-escaping.txt 2009-09-14 15:41:21 +0000 |
2398 | +++ lib/lp/translations/stories/standalone/xx-template-description-escaping.txt 2010-09-09 15:34:46 +0000 |
2399 | @@ -1,12 +1,14 @@ |
2400 | >>> import re |
2401 | >>> from zope.security.proxy import removeSecurityProxy |
2402 | + >>> from lp.app.enums import ServiceUsage |
2403 | |
2404 | >>> login('foo.bar@canonical.com') |
2405 | >>> package = factory.makeSourcePackage() |
2406 | >>> template = removeSecurityProxy(factory.makePOTemplate( |
2407 | ... distroseries=package.distroseries, |
2408 | ... sourcepackagename=package.sourcepackagename)) |
2409 | - >>> template.distroseries.distribution.official_rosetta = True |
2410 | + >>> distribution = template.distroseries.distribution |
2411 | + >>> distribution.translations_usage = ServiceUsage.LAUNCHPAD |
2412 | >>> template.distroseries.hide_all_translations = False |
2413 | >>> template.description = "See http://example.com/ for an example!" |
2414 | >>> package_url = canonical_url(package, rootsite='translations') |
2415 | |
2416 | === modified file 'lib/lp/translations/stories/translationfocus/xx-product-translationfocus.txt' |
2417 | --- lib/lp/translations/stories/translationfocus/xx-product-translationfocus.txt 2010-01-20 20:21:42 +0000 |
2418 | +++ lib/lp/translations/stories/translationfocus/xx-product-translationfocus.txt 2010-09-09 15:34:46 +0000 |
2419 | @@ -1,9 +1,10 @@ |
2420 | The translation focus of a product can be explicitly set to a specific series. |
2421 | When not set, launchpad recommends the development focus to translate. |
2422 | |
2423 | + >>> from lp.app.enums import ServiceUsage |
2424 | >>> login('admin@canonical.com') |
2425 | >>> fooproject = factory.makeProduct(name="fooproject") |
2426 | - >>> fooproject.official_rosetta = True |
2427 | + >>> fooproject.translations_usage = ServiceUsage.LAUNCHPAD |
2428 | >>> fooproject_trunk = fooproject.getSeries("trunk") |
2429 | >>> fooproject_url = canonical_url( |
2430 | ... fooproject, rootsite="translations") |
2431 | @@ -25,7 +26,8 @@ |
2432 | ... |
2433 | IndexError: list index out of range |
2434 | |
2435 | -== Setting the translation focus == |
2436 | +Setting the translation focus |
2437 | +============================= |
2438 | |
2439 | >>> login('admin@canonical.com') |
2440 | >>> from zope.security.proxy import removeSecurityProxy |
2441 | @@ -35,7 +37,7 @@ |
2442 | >>> pofile = factory.makePOFile("pt_BR", potemplate=pot_main) |
2443 | >>> logout() |
2444 | |
2445 | -When the translation focus is not set, Launchpad suggests the |
2446 | +When the translation focus is not set, Launchpad suggests the |
2447 | development focus as the current series to be translated. |
2448 | It needs to be translatable. |
2449 | |
2450 | |
2451 | === modified file 'lib/lp/translations/stories/translationgroups/xx-change-translation-policy.txt' |
2452 | --- lib/lp/translations/stories/translationgroups/xx-change-translation-policy.txt 2010-02-16 21:21:14 +0000 |
2453 | +++ lib/lp/translations/stories/translationgroups/xx-change-translation-policy.txt 2010-09-09 15:34:46 +0000 |
2454 | @@ -4,11 +4,15 @@ |
2455 | A product owner, Rosetta expert, and Ubuntu translations coordinator |
2456 | browser is created. |
2457 | |
2458 | + >>> from lp.app.enums import ServiceUsage |
2459 | + |
2460 | >>> login('admin@canonical.com') |
2461 | >>> product_owner = factory.makePerson( |
2462 | ... email="po@ex.com", password="test") |
2463 | >>> chestii = factory.makeProduct( |
2464 | - ... name='chestii', owner=product_owner, official_rosetta=True) |
2465 | + ... name='chestii', |
2466 | + ... owner=product_owner, |
2467 | + ... translations_usage=ServiceUsage.LAUNCHPAD) |
2468 | >>> logout() |
2469 | >>> dtc_browser = setupDTCBrowser() |
2470 | >>> re_browser = setupRosettaExpertBrowser() |
2471 | |
2472 | === modified file 'lib/lp/translations/templates/product-portlet-not-using-launchpad.pt' |
2473 | --- lib/lp/translations/templates/product-portlet-not-using-launchpad.pt 2010-03-15 20:17:21 +0000 |
2474 | +++ lib/lp/translations/templates/product-portlet-not-using-launchpad.pt 2010-09-09 15:34:46 +0000 |
2475 | @@ -5,7 +5,7 @@ |
2476 | omit-tag=""> |
2477 | |
2478 | <div id="not-translated-in-launchpad" |
2479 | - tal:condition="not: context/official_rosetta"> |
2480 | + tal:condition="not: context/translations_usage/enumvalue:LAUNCHPAD"> |
2481 | <strong> |
2482 | This project is not using Launchpad for translations. |
2483 | </strong> |
2484 | |
2485 | === modified file 'lib/lp/translations/templates/productseries-translations.pt' |
2486 | --- lib/lp/translations/templates/productseries-translations.pt 2009-12-16 15:21:36 +0000 |
2487 | +++ lib/lp/translations/templates/productseries-translations.pt 2010-09-09 15:34:46 +0000 |
2488 | @@ -30,7 +30,7 @@ |
2489 | <a href="https://help.launchpad.net/Translations/YourProject">start |
2490 | translating your project</a>, |
2491 | <tal:uses-translations condition="not: |
2492 | - context/product/official_rosetta"> |
2493 | + context/product/translations_usage/enumvalue:LAUNCHPAD"> |
2494 | you should enable translations in your project settings, and |
2495 | </tal:uses-translations> |
2496 | you can either |
2497 | |
2498 | === modified file 'lib/lp/translations/tests/test_autoapproval.py' |
2499 | --- lib/lp/translations/tests/test_autoapproval.py 2010-08-20 20:31:18 +0000 |
2500 | +++ lib/lp/translations/tests/test_autoapproval.py 2010-09-09 15:34:46 +0000 |
2501 | @@ -23,6 +23,7 @@ |
2502 | from canonical.launchpad.interfaces.lpstorm import IMasterStore |
2503 | from canonical.launchpad.webapp.testing import verifyObject |
2504 | from canonical.testing import LaunchpadZopelessLayer |
2505 | +from lp.app.enums import ServiceUsage |
2506 | from lp.registry.interfaces.series import SeriesStatus |
2507 | from lp.registry.model.distribution import Distribution |
2508 | from lp.registry.model.sourcepackagename import ( |
2509 | @@ -714,8 +715,8 @@ |
2510 | # _get_pofile_from_language will find an enabled template, and |
2511 | # return either an existing POFile for the given language, or a |
2512 | # newly created one. |
2513 | - product = self.factory.makeProduct() |
2514 | - product.official_rosetta = True |
2515 | + product = self.factory.makeProduct( |
2516 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2517 | trunk = product.getSeries('trunk') |
2518 | template = self.factory.makePOTemplate( |
2519 | productseries=trunk, translation_domain='domain') |
2520 | @@ -732,8 +733,8 @@ |
2521 | # _get_pofile_from_language will not consider a disabled |
2522 | # template as an auto-approval target, and so will not return a |
2523 | # POFile for it. |
2524 | - product = self.factory.makeProduct() |
2525 | - product.official_rosetta = True |
2526 | + product = self.factory.makeProduct( |
2527 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2528 | trunk = product.getSeries('trunk') |
2529 | template = self.factory.makePOTemplate( |
2530 | productseries=trunk, translation_domain='domain') |
2531 | @@ -750,8 +751,8 @@ |
2532 | # When the template has translation credits, a new dummy translation |
2533 | # is created in the new POFile. Since this is running with gardener |
2534 | # privileges, we need to check that this works, too. |
2535 | - product = self.factory.makeProduct() |
2536 | - product.official_rosetta = True |
2537 | + product = self.factory.makeProduct( |
2538 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2539 | trunk = product.getSeries('trunk') |
2540 | template = self.factory.makePOTemplate( |
2541 | productseries=trunk, translation_domain='domain') |
2542 | @@ -778,8 +779,8 @@ |
2543 | |
2544 | def _makeProductEntry(self, path='foo.pot', status=None): |
2545 | """Simulate upload for a product.""" |
2546 | - product = self.factory.makeProduct() |
2547 | - product.official_rosetta = True |
2548 | + product = self.factory.makeProduct( |
2549 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2550 | trunk = product.getSeries('trunk') |
2551 | entry = self.queue.addOrUpdateEntry( |
2552 | path, '# contents', False, product.owner, productseries=trunk) |
2553 | |
2554 | === modified file 'lib/lp/translations/tests/test_empty_messages.py' |
2555 | --- lib/lp/translations/tests/test_empty_messages.py 2010-08-20 20:31:18 +0000 |
2556 | +++ lib/lp/translations/tests/test_empty_messages.py 2010-09-09 15:34:46 +0000 |
2557 | @@ -4,17 +4,17 @@ |
2558 | __metaclass__ = type |
2559 | |
2560 | from datetime import datetime |
2561 | -import unittest |
2562 | |
2563 | from pytz import timezone |
2564 | from zope.component import getUtility |
2565 | |
2566 | from canonical.testing import LaunchpadZopelessLayer |
2567 | +from lp.app.enums import ServiceUsage |
2568 | from lp.services.worlddata.interfaces.language import ILanguageSet |
2569 | -from lp.testing.factory import LaunchpadObjectFactory |
2570 | - |
2571 | - |
2572 | -class TestTranslationEmptyMessages(unittest.TestCase): |
2573 | +from lp.testing import TestCaseWithFactory |
2574 | + |
2575 | + |
2576 | +class TestTranslationEmptyMessages(TestCaseWithFactory): |
2577 | """Test behaviour of empty translation messages.""" |
2578 | |
2579 | layer = LaunchpadZopelessLayer |
2580 | @@ -23,13 +23,15 @@ |
2581 | """Set up context to test in.""" |
2582 | # Pretend we have a product being translated to Serbian. |
2583 | # This is where we are going to be importing translations to. |
2584 | - factory = LaunchpadObjectFactory() |
2585 | - self.factory = factory |
2586 | - self.productseries = factory.makeProductSeries() |
2587 | - self.productseries.product.official_rosetta = True |
2588 | - self.potemplate = factory.makePOTemplate(self.productseries) |
2589 | + super(TestTranslationEmptyMessages, self).setUp() |
2590 | + product = self.factory.makeProduct( |
2591 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2592 | + self.productseries = self.factory.makeProductSeries(product=product) |
2593 | + self.potemplate = self.factory.makePOTemplate(self.productseries) |
2594 | self.serbian = getUtility(ILanguageSet).getLanguageByCode('sr') |
2595 | - self.pofile_sr = factory.makePOFile('sr', potemplate=self.potemplate) |
2596 | + self.pofile_sr = self.factory.makePOFile( |
2597 | + 'sr', |
2598 | + potemplate=self.potemplate) |
2599 | self.now = datetime.now(timezone('UTC')) |
2600 | |
2601 | def test_NoEmptyImporedTranslation(self): |
2602 | |
2603 | === modified file 'lib/lp/translations/tests/test_hastranslationtemplates.py' |
2604 | --- lib/lp/translations/tests/test_hastranslationtemplates.py 2010-08-20 20:31:18 +0000 |
2605 | +++ lib/lp/translations/tests/test_hastranslationtemplates.py 2010-09-09 15:34:46 +0000 |
2606 | @@ -6,6 +6,7 @@ |
2607 | from zope.interface.verify import verifyObject |
2608 | |
2609 | from canonical.testing import ZopelessDatabaseLayer |
2610 | +from lp.app.enums import ServiceUsage |
2611 | from lp.testing import TestCaseWithFactory |
2612 | from lp.translations.interfaces.potemplate import IHasTranslationTemplates |
2613 | from lp.translations.interfaces.translationfileformat import ( |
2614 | @@ -152,7 +153,7 @@ |
2615 | |
2616 | # A product or distribution that doesn't use Launchpad for |
2617 | # translations has no current templates. |
2618 | - self.product_or_distro.official_rosetta = False |
2619 | + self.product_or_distro.translations_usage = ServiceUsage.EXTERNAL |
2620 | self.assertFalse(self.container.has_current_translation_templates) |
2621 | |
2622 | def test_getTranslationTemplateFormats(self): |
2623 | @@ -205,7 +206,7 @@ |
2624 | super(TestProductSeriesHasTranslationTemplates, self).setUp() |
2625 | self.container = self.factory.makeProductSeries() |
2626 | self.product_or_distro = self.container.product |
2627 | - self.product_or_distro.official_rosetta = True |
2628 | + self.product_or_distro.translations_usage = ServiceUsage.LAUNCHPAD |
2629 | |
2630 | |
2631 | class TestSourcePackageHasTranslationTemplates( |
2632 | @@ -223,7 +224,7 @@ |
2633 | super(TestSourcePackageHasTranslationTemplates, self).setUp() |
2634 | self.container = self.factory.makeSourcePackage() |
2635 | self.product_or_distro = self.container.distroseries.distribution |
2636 | - self.product_or_distro.official_rosetta = True |
2637 | + self.product_or_distro.translations_usage = ServiceUsage.LAUNCHPAD |
2638 | |
2639 | |
2640 | class TestDistroSeriesHasTranslationTemplates( |
2641 | @@ -243,4 +244,4 @@ |
2642 | super(TestDistroSeriesHasTranslationTemplates, self).setUp() |
2643 | self.container = self.factory.makeDistroRelease() |
2644 | self.product_or_distro = self.container.distribution |
2645 | - self.product_or_distro.official_rosetta = True |
2646 | + self.product_or_distro.translations_usage = ServiceUsage.LAUNCHPAD |
2647 | |
2648 | === modified file 'lib/lp/translations/tests/test_pofile.py' |
2649 | --- lib/lp/translations/tests/test_pofile.py 2010-09-03 14:38:20 +0000 |
2650 | +++ lib/lp/translations/tests/test_pofile.py 2010-09-09 15:34:46 +0000 |
2651 | @@ -24,6 +24,7 @@ |
2652 | LaunchpadZopelessLayer, |
2653 | ZopelessDatabaseLayer, |
2654 | ) |
2655 | +from lp.app.enums import ServiceUsage |
2656 | from lp.testing import TestCaseWithFactory |
2657 | from lp.translations.interfaces.pofile import IPOFileSet |
2658 | from lp.translations.interfaces.translatablemessage import ( |
2659 | @@ -46,12 +47,13 @@ |
2660 | # Create a product with two series and a shared POTemplate |
2661 | # in different series ('devel' and 'stable'). |
2662 | super(TestTranslationSharedPOFile, self).setUp() |
2663 | - self.foo = self.factory.makeProduct(name='foo') |
2664 | + self.foo = self.factory.makeProduct( |
2665 | + name='foo', |
2666 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2667 | self.foo_devel = self.factory.makeProductSeries( |
2668 | name='devel', product=self.foo) |
2669 | self.foo_stable = self.factory.makeProductSeries( |
2670 | name='stable', product=self.foo) |
2671 | - self.foo.official_rosetta = True |
2672 | |
2673 | # POTemplate is 'shared' if it has the same name ('messages'). |
2674 | self.devel_potemplate = self.factory.makePOTemplate( |
2675 | @@ -76,7 +78,8 @@ |
2676 | 'http://translations.launchpad.dev/foo/devel/+pots/messages/sr', |
2677 | canonical_url(self.devel_sr_pofile)) |
2678 | self.assertEqual( |
2679 | - 'http://translations.launchpad.dev/foo/devel/+pots/messages/sr/+details', |
2680 | + ('http://translations.launchpad.dev/' |
2681 | + 'foo/devel/+pots/messages/sr/+details'), |
2682 | canonical_url(self.devel_sr_pofile, view_name="+details")) |
2683 | |
2684 | def test_findPOTMsgSetsContaining(self): |
2685 | @@ -879,12 +882,12 @@ |
2686 | # Create a product with two series and a shared POTemplate |
2687 | # in different series ('devel' and 'stable'). |
2688 | super(TestSharedPOFileCreation, self).setUp() |
2689 | - self.foo = self.factory.makeProduct() |
2690 | + self.foo = self.factory.makeProduct( |
2691 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2692 | self.foo_devel = self.factory.makeProductSeries( |
2693 | name='devel', product=self.foo) |
2694 | self.foo_stable = self.factory.makeProductSeries( |
2695 | name='stable', product=self.foo) |
2696 | - self.foo.official_rosetta = True |
2697 | |
2698 | def test_pofile_creation_shared(self): |
2699 | # When a pofile is created in a POTemplate it is also created in |
2700 | @@ -1009,12 +1012,12 @@ |
2701 | # Create a product with two series and a shared POTemplate |
2702 | # in different series ('devel' and 'stable'). |
2703 | super(TestTranslationPOFilePOTMsgSetOrdering, self).setUp() |
2704 | - self.foo = self.factory.makeProduct() |
2705 | + self.foo = self.factory.makeProduct( |
2706 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2707 | self.foo_devel = self.factory.makeProductSeries( |
2708 | name='devel', product=self.foo) |
2709 | self.foo_stable = self.factory.makeProductSeries( |
2710 | name='stable', product=self.foo) |
2711 | - self.foo.official_rosetta = True |
2712 | |
2713 | # POTemplate is 'shared' if it has the same name ('messages'). |
2714 | self.devel_potemplate = self.factory.makePOTemplate( |
2715 | @@ -1288,8 +1291,8 @@ |
2716 | # We create a product with two series, and attach |
2717 | # a POTemplate and Serbian POFile to each, making |
2718 | # sure they share translations (potemplates have the same name). |
2719 | - product = self.factory.makeProduct() |
2720 | - product.official_rosetta = True |
2721 | + product = self.factory.makeProduct( |
2722 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2723 | series1 = self.factory.makeProductSeries(product=product, |
2724 | name='one') |
2725 | series2 = self.factory.makeProductSeries(product=product, |
2726 | @@ -1324,8 +1327,8 @@ |
2727 | # This is a test for bug #414832 which caused sharing POFiles |
2728 | # of the touched POFile not to be returned if they had |
2729 | # IDs smaller than the touched POFile. |
2730 | - product = self.factory.makeProduct() |
2731 | - product.official_rosetta = True |
2732 | + product = self.factory.makeProduct( |
2733 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2734 | series1 = self.factory.makeProductSeries(product=product, |
2735 | name='one') |
2736 | series2 = self.factory.makeProductSeries(product=product, |
2737 | @@ -1357,7 +1360,7 @@ |
2738 | # POFile to each, making sure they share translations |
2739 | # (potemplates have the same name). |
2740 | distro = self.factory.makeDistribution() |
2741 | - distro.official_rosetta = True |
2742 | + distro.translations_usage = ServiceUsage.LAUNCHPAD |
2743 | series1 = self.factory.makeDistroRelease(distribution=distro, |
2744 | name='one') |
2745 | sourcepackagename = self.factory.makeSourcePackageName() |
2746 | @@ -1395,9 +1398,9 @@ |
2747 | # Make sure POFiles which are in different products |
2748 | # are not returned even though they have the same potemplate name. |
2749 | series1 = self.factory.makeProductSeries(name='one') |
2750 | - series1.product.official_rosetta = True |
2751 | + series1.product.translations_usage = ServiceUsage.LAUNCHPAD |
2752 | series2 = self.factory.makeProductSeries(name='two') |
2753 | - series2.product.official_rosetta = True |
2754 | + series1.product.translations_usage = ServiceUsage.LAUNCHPAD |
2755 | self.assertNotEqual(series1.product, series2.product) |
2756 | |
2757 | potemplate1 = self.factory.makePOTemplate(name='shared', |
2758 | |
2759 | === modified file 'lib/lp/translations/tests/test_potemplate.py' |
2760 | --- lib/lp/translations/tests/test_potemplate.py 2010-08-20 20:31:18 +0000 |
2761 | +++ lib/lp/translations/tests/test_potemplate.py 2010-09-09 15:34:46 +0000 |
2762 | @@ -7,6 +7,7 @@ |
2763 | from zope.security.proxy import removeSecurityProxy |
2764 | |
2765 | from canonical.testing import DatabaseFunctionalLayer |
2766 | +from lp.app.enums import ServiceUsage |
2767 | from lp.registry.interfaces.distribution import IDistributionSet |
2768 | from lp.services.worlddata.interfaces.language import ILanguageSet |
2769 | from lp.testing import TestCaseWithFactory |
2770 | @@ -327,8 +328,8 @@ |
2771 | |
2772 | def setUp(self): |
2773 | super(TestTemplatePrecedence, self).setUp(user='mark@example.com') |
2774 | - self.product = self.factory.makeProduct() |
2775 | - self.product.official_rosetta = True |
2776 | + self.product = self.factory.makeProduct( |
2777 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2778 | self.trunk = self.product.getSeries('trunk') |
2779 | self.one_dot_oh = self.factory.makeProductSeries( |
2780 | product=self.product, name='one') |
2781 | |
2782 | === modified file 'lib/lp/translations/tests/test_potmsgset.py' |
2783 | --- lib/lp/translations/tests/test_potmsgset.py 2010-08-20 20:31:18 +0000 |
2784 | +++ lib/lp/translations/tests/test_potmsgset.py 2010-09-09 15:34:46 +0000 |
2785 | @@ -20,6 +20,7 @@ |
2786 | |
2787 | from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities |
2788 | from canonical.testing import ZopelessDatabaseLayer |
2789 | +from lp.app.enums import ServiceUsage |
2790 | from lp.registry.interfaces.person import IPersonSet |
2791 | from lp.registry.interfaces.product import IProductSet |
2792 | from lp.services.worlddata.interfaces.language import ILanguageSet |
2793 | @@ -45,12 +46,12 @@ |
2794 | # Create a product with two series and a shared POTemplate |
2795 | # in different series ('devel' and 'stable'). |
2796 | super(TestTranslationSharedPOTMsgSets, self).setUp() |
2797 | - self.foo = self.factory.makeProduct() |
2798 | + self.foo = self.factory.makeProduct( |
2799 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2800 | self.foo_devel = self.factory.makeProductSeries( |
2801 | name='devel', product=self.foo) |
2802 | self.foo_stable = self.factory.makeProductSeries( |
2803 | name='stable', product=self.foo) |
2804 | - self.foo.official_rosetta = True |
2805 | |
2806 | # POTemplate is 'shared' if it has the same name ('messages'). |
2807 | self.devel_potemplate = self.factory.makePOTemplate( |
2808 | @@ -324,7 +325,8 @@ |
2809 | # Create an external POTemplate with a POTMsgSet using |
2810 | # the same English string as the one in self.potmsgset. |
2811 | external_template = self.factory.makePOTemplate() |
2812 | - external_template.productseries.product.official_rosetta = True |
2813 | + product = external_template.productseries.product |
2814 | + product.translations_usage = ServiceUsage.LAUNCHPAD |
2815 | external_potmsgset = self.factory.makePOTMsgSet( |
2816 | external_template, |
2817 | singular=self.potmsgset.singular_text) |
2818 | @@ -383,7 +385,8 @@ |
2819 | # Create an external POTemplate with a POTMsgSet using |
2820 | # the same English string as the one in self.potmsgset. |
2821 | external_template = self.factory.makePOTemplate() |
2822 | - external_template.productseries.product.official_rosetta = True |
2823 | + product = external_template.productseries.product |
2824 | + product.translations_usage = ServiceUsage.LAUNCHPAD |
2825 | external_potmsgset = self.factory.makePOTMsgSet( |
2826 | external_template, |
2827 | singular=self.potmsgset.singular_text) |
2828 | @@ -738,10 +741,10 @@ |
2829 | # create TranslationMessage objects. |
2830 | super(TestPOTMsgSetSuggestions, self).setUp() |
2831 | self.now = self.gen_now().next |
2832 | - self.foo = self.factory.makeProduct() |
2833 | + self.foo = self.factory.makeProduct( |
2834 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2835 | self.foo_main = self.factory.makeProductSeries( |
2836 | name='main', product=self.foo) |
2837 | - self.foo.official_rosetta = True |
2838 | |
2839 | self.potemplate = self.factory.makePOTemplate( |
2840 | productseries=self.foo_main, name="messages") |
2841 | @@ -926,10 +929,10 @@ |
2842 | # create TranslationMessage objects. |
2843 | super(TestPOTMsgSetResetTranslation, self).setUp() |
2844 | self.now = self.gen_now().next |
2845 | - self.foo = self.factory.makeProduct() |
2846 | + self.foo = self.factory.makeProduct( |
2847 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2848 | self.foo_main = self.factory.makeProductSeries( |
2849 | name='main', product=self.foo) |
2850 | - self.foo.official_rosetta = True |
2851 | |
2852 | self.potemplate = self.factory.makePOTemplate( |
2853 | productseries=self.foo_main, name="messages") |
2854 | |
2855 | === modified file 'lib/lp/translations/tests/test_productserieslanguage.py' |
2856 | --- lib/lp/translations/tests/test_productserieslanguage.py 2010-08-20 20:31:18 +0000 |
2857 | +++ lib/lp/translations/tests/test_productserieslanguage.py 2010-09-09 15:34:46 +0000 |
2858 | @@ -10,6 +10,7 @@ |
2859 | from zope.security.proxy import removeSecurityProxy |
2860 | |
2861 | from canonical.testing import ZopelessDatabaseLayer |
2862 | +from lp.app.enums import ServiceUsage |
2863 | from lp.services.worlddata.interfaces.language import ILanguageSet |
2864 | from lp.testing import TestCaseWithFactory |
2865 | from lp.translations.interfaces.productserieslanguage import ( |
2866 | @@ -26,8 +27,10 @@ |
2867 | def setUp(self): |
2868 | # Create a productseries that uses translations. |
2869 | TestCaseWithFactory.setUp(self) |
2870 | - self.productseries = self.factory.makeProductSeries() |
2871 | - self.productseries.product.official_rosetta = True |
2872 | + product = self.factory.makeProduct( |
2873 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2874 | + self.productseries = self.factory.makeProductSeries( |
2875 | + product=product) |
2876 | |
2877 | def test_no_templates_no_translation(self): |
2878 | # There are no templates and no translations. |
2879 | @@ -125,8 +128,10 @@ |
2880 | def setUp(self): |
2881 | # Create a productseries that uses translations. |
2882 | TestCaseWithFactory.setUp(self) |
2883 | - self.productseries = self.factory.makeProductSeries() |
2884 | - self.productseries.product.official_rosetta = True |
2885 | + product = self.factory.makeProduct( |
2886 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2887 | + self.productseries = self.factory.makeProductSeries( |
2888 | + product=product) |
2889 | self.psl_set = getUtility(IProductSeriesLanguageSet) |
2890 | self.language = getUtility(ILanguageSet).getLanguageByCode('sr') |
2891 | |
2892 | |
2893 | === modified file 'lib/lp/translations/tests/test_shared_potemplate.py' |
2894 | --- lib/lp/translations/tests/test_shared_potemplate.py 2010-08-20 20:31:18 +0000 |
2895 | +++ lib/lp/translations/tests/test_shared_potemplate.py 2010-09-09 15:34:46 +0000 |
2896 | @@ -10,6 +10,7 @@ |
2897 | from zope.security.proxy import removeSecurityProxy |
2898 | |
2899 | from canonical.testing import ZopelessDatabaseLayer |
2900 | +from lp.app.enums import ServiceUsage |
2901 | from lp.testing.factory import LaunchpadObjectFactory |
2902 | |
2903 | |
2904 | @@ -24,12 +25,12 @@ |
2905 | # in different series ('devel' and 'stable'). |
2906 | factory = LaunchpadObjectFactory() |
2907 | self.factory = factory |
2908 | - self.foo = factory.makeProduct() |
2909 | + self.foo = self.factory.makeProduct( |
2910 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2911 | self.foo_devel = factory.makeProductSeries( |
2912 | name='devel', product=self.foo) |
2913 | self.foo_stable = factory.makeProductSeries( |
2914 | name='stable', product=self.foo) |
2915 | - self.foo.official_rosetta = True |
2916 | |
2917 | # POTemplate is a 'sharing' one if it has the same name ('messages'). |
2918 | self.devel_potemplate = factory.makePOTemplate( |
2919 | |
2920 | === modified file 'lib/lp/translations/tests/test_suggestions.py' |
2921 | --- lib/lp/translations/tests/test_suggestions.py 2010-08-20 20:31:18 +0000 |
2922 | +++ lib/lp/translations/tests/test_suggestions.py 2010-09-09 15:34:46 +0000 |
2923 | @@ -17,6 +17,7 @@ |
2924 | |
2925 | from canonical.config import config |
2926 | from canonical.testing import LaunchpadZopelessLayer |
2927 | +from lp.app.enums import ServiceUsage |
2928 | from lp.services.worlddata.interfaces.language import ILanguageSet |
2929 | from lp.testing.factory import LaunchpadObjectFactory |
2930 | from lp.translations.interfaces.translationmessage import ( |
2931 | @@ -36,10 +37,14 @@ |
2932 | # suggestions for the other. |
2933 | factory = LaunchpadObjectFactory() |
2934 | self.factory = factory |
2935 | - self.foo_trunk = factory.makeProductSeries() |
2936 | - self.bar_trunk = factory.makeProductSeries() |
2937 | - self.foo_trunk.product.official_rosetta = True |
2938 | - self.bar_trunk.product.official_rosetta = True |
2939 | + foo_product = factory.makeProduct( |
2940 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2941 | + bar_product = factory.makeProduct( |
2942 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2943 | + self.foo_trunk = factory.makeProductSeries( |
2944 | + product=foo_product) |
2945 | + self.bar_trunk = factory.makeProductSeries( |
2946 | + product=bar_product) |
2947 | self.foo_template = factory.makePOTemplate(self.foo_trunk) |
2948 | self.bar_template = factory.makePOTemplate(self.bar_trunk) |
2949 | self.nl = getUtility(ILanguageSet).getLanguageByCode('nl') |
2950 | @@ -222,5 +227,6 @@ |
2951 | "TranslationMessage with errors is not correctly" |
2952 | "marked as such in the database.") |
2953 | |
2954 | + |
2955 | def test_suite(): |
2956 | return unittest.TestLoader().loadTestsFromName(__name__) |
2957 | |
2958 | === modified file 'lib/lp/translations/tests/test_translatablemessage.py' |
2959 | --- lib/lp/translations/tests/test_translatablemessage.py 2010-08-20 20:31:18 +0000 |
2960 | +++ lib/lp/translations/tests/test_translatablemessage.py 2010-09-09 15:34:46 +0000 |
2961 | @@ -15,6 +15,7 @@ |
2962 | import transaction |
2963 | |
2964 | from canonical.testing import ZopelessDatabaseLayer |
2965 | +from lp.app.enums import ServiceUsage |
2966 | from lp.testing import TestCaseWithFactory |
2967 | from lp.translations.model.translatablemessage import TranslatableMessage |
2968 | |
2969 | @@ -31,8 +32,8 @@ |
2970 | `POTMsgSet`, as well as a Esperanto translation. |
2971 | """ |
2972 | super(TestTranslatableMessageBase, self).setUp() |
2973 | - self.product = self.factory.makeProduct() |
2974 | - self.product.official_rosetta = True |
2975 | + self.product = self.factory.makeProduct( |
2976 | + translations_usage=ServiceUsage.LAUNCHPAD) |
2977 | self.trunk = self.product.getSeries('trunk') |
2978 | self.potemplate = self.factory.makePOTemplate( |
2979 | productseries=self.trunk) |
2980 | @@ -137,7 +138,8 @@ |
2981 | super(TestTranslatableMessageExternal, self).setUp() |
2982 | common_msgid = self.potmsgset.singular_text |
2983 | self.external_potemplate = self.factory.makePOTemplate() |
2984 | - self.external_potemplate.productseries.product.official_rosetta = True |
2985 | + product = self.external_potemplate.productseries.product |
2986 | + product.translations_usage = ServiceUsage.LAUNCHPAD |
2987 | self.external_potmsgset = self.factory.makePOTMsgSet( |
2988 | potemplate=self.external_potemplate, |
2989 | singular=common_msgid, sequence=1) |
2990 | @@ -175,24 +177,24 @@ |
2991 | super(TestTranslatableMessageSuggestions, self).setUp() |
2992 | self.now = self.gen_now().next |
2993 | self.suggestion1 = self._createTranslation(date_updated=self.now()) |
2994 | - self.current = self._createTranslation(is_current=True, |
2995 | + self.current = self._createTranslation(is_current=True, |
2996 | date_updated=self.now()) |
2997 | self.suggestion2 = self._createTranslation(date_updated=self.now()) |
2998 | self.message = TranslatableMessage(self.potmsgset, self.pofile) |
2999 | |
3000 | def test_getAllSuggestions(self): |
3001 | - # There are three different methods to return |
3002 | + # There are three different methods to return |
3003 | suggestions = self.message.getAllSuggestions() |
3004 | self.assertContentEqual([self.suggestion1, self.suggestion2], |
3005 | suggestions) |
3006 | |
3007 | def test_getDismissedSuggestions(self): |
3008 | - # There are three different methods to return |
3009 | + # There are three different methods to return |
3010 | suggestions = self.message.getDismissedSuggestions() |
3011 | self.assertContentEqual([self.suggestion1], suggestions) |
3012 | |
3013 | def test_getUnreviewedSuggestions(self): |
3014 | - # There are three different methods to return |
3015 | + # There are three different methods to return |
3016 | suggestions = self.message.getUnreviewedSuggestions() |
3017 | self.assertContentEqual([self.suggestion2], suggestions) |
3018 | |
3019 | |
3020 | === modified file 'lib/lp/translations/tests/test_translatedlanguage.py' |
3021 | --- lib/lp/translations/tests/test_translatedlanguage.py 2010-08-20 20:31:18 +0000 |
3022 | +++ lib/lp/translations/tests/test_translatedlanguage.py 2010-09-09 15:34:46 +0000 |
3023 | @@ -8,6 +8,7 @@ |
3024 | from zope.security.proxy import removeSecurityProxy |
3025 | |
3026 | from canonical.testing import ZopelessDatabaseLayer |
3027 | +from lp.app.enums import ServiceUsage |
3028 | from lp.testing import TestCaseWithFactory |
3029 | from lp.translations.interfaces.productserieslanguage import ( |
3030 | IProductSeriesLanguageSet, |
3031 | @@ -24,8 +25,10 @@ |
3032 | def setUp(self): |
3033 | # Create a productseries that uses translations. |
3034 | TestCaseWithFactory.setUp(self) |
3035 | - self.productseries = self.factory.makeProductSeries() |
3036 | - self.productseries.product.official_rosetta = True |
3037 | + product = self.factory.makeProduct( |
3038 | + translations_usage = ServiceUsage.LAUNCHPAD) |
3039 | + self.productseries = self.factory.makeProductSeries( |
3040 | + product=product) |
3041 | self.parent = self.productseries |
3042 | self.psl_set = getUtility(IProductSeriesLanguageSet) |
3043 | self.language = self.factory.makeLanguage('sr@test') |
3044 | |
3045 | === modified file 'lib/lp/translations/tests/test_translations_to_review.py' |
3046 | --- lib/lp/translations/tests/test_translations_to_review.py 2010-08-20 20:31:18 +0000 |
3047 | +++ lib/lp/translations/tests/test_translations_to_review.py 2010-09-09 15:34:46 +0000 |
3048 | @@ -16,6 +16,7 @@ |
3049 | from zope.security.proxy import removeSecurityProxy |
3050 | |
3051 | from canonical.testing import DatabaseFunctionalLayer |
3052 | +from lp.app.enums import ServiceUsage |
3053 | from lp.services.worlddata.model.language import LanguageSet |
3054 | from lp.testing import TestCaseWithFactory |
3055 | from lp.translations.interfaces.translationsperson import ITranslationsPerson |
3056 | @@ -28,6 +29,7 @@ |
3057 | |
3058 | class ReviewTestMixin: |
3059 | """Base for testing which translations a reviewer can review.""" |
3060 | + |
3061 | def setUpMixin(self, for_product=True): |
3062 | """Set up test environment. |
3063 | |
3064 | @@ -68,7 +70,7 @@ |
3065 | transaction.commit() |
3066 | |
3067 | self.supercontext.translationgroup = self.translationgroup |
3068 | - self.supercontext.official_rosetta = True |
3069 | + self.supercontext.translations_usage = ServiceUsage.LAUNCHPAD |
3070 | |
3071 | self.potemplate = self.factory.makePOTemplate( |
3072 | productseries=self.productseries, distroseries=self.distroseries, |
3073 | @@ -111,6 +113,7 @@ |
3074 | |
3075 | Can be applied to product or distribution setups. |
3076 | """ |
3077 | + |
3078 | def test_OneFileToReview(self): |
3079 | # In the base case, the method finds one POFile for self.person |
3080 | # to review. |
3081 | @@ -131,7 +134,7 @@ |
3082 | def test_getReviewableTranslationFiles_not_translating_in_launchpad(self): |
3083 | # We don't see products/distros that don't use Launchpad for |
3084 | # translations. |
3085 | - self.supercontext.official_rosetta = False |
3086 | + self.supercontext.translations_usage = ServiceUsage.NOT_APPLICABLE |
3087 | self.assertEqual(self._getReviewables(), []) |
3088 | |
3089 | def test_getReviewableTranslationFiles_non_reviewer(self): |
3090 | @@ -200,7 +203,7 @@ |
3091 | other_pofile = removeSecurityProxy(other_pofile) |
3092 | |
3093 | product = other_pofile.potemplate.productseries.product |
3094 | - product.official_rosetta = True |
3095 | + product.translations_usage = ServiceUsage.LAUNCHPAD |
3096 | |
3097 | if with_unreviewed: |
3098 | other_pofile.unreviewed_count = 1 |
3099 | |
3100 | === modified file 'lib/lp/translations/windmill/tests/test_documentation_links.py' |
3101 | --- lib/lp/translations/windmill/tests/test_documentation_links.py 2010-08-20 20:31:18 +0000 |
3102 | +++ lib/lp/translations/windmill/tests/test_documentation_links.py 2010-09-09 15:34:46 +0000 |
3103 | @@ -9,6 +9,7 @@ |
3104 | from zope.security.proxy import removeSecurityProxy |
3105 | |
3106 | from canonical.launchpad.windmill.testing import lpuser |
3107 | +from lp.app.enums import ServiceUsage |
3108 | from lp.testing import WindmillTestCase |
3109 | from lp.translations.windmill.testing import TranslationsWindmillLayer |
3110 | |
3111 | @@ -52,7 +53,7 @@ |
3112 | project = self.factory.makeProduct( |
3113 | name='test-product', |
3114 | displayname='Test Product', |
3115 | - official_rosetta=True) |
3116 | + translations_usage=ServiceUsage.LAUNCHPAD) |
3117 | removeSecurityProxy(project).translationgroup = group |
3118 | |
3119 | potemplate = self.createPOTemplateWithPOTMsgSets( |
3120 | |
3121 | === modified file 'lib/lp/translations/windmill/tests/test_import_queue.py' |
3122 | --- lib/lp/translations/windmill/tests/test_import_queue.py 2010-08-20 20:31:18 +0000 |
3123 | +++ lib/lp/translations/windmill/tests/test_import_queue.py 2010-09-09 15:34:46 +0000 |
3124 | @@ -8,7 +8,6 @@ |
3125 | |
3126 | import transaction |
3127 | from zope.component import getUtility |
3128 | -from zope.security.proxy import removeSecurityProxy |
3129 | |
3130 | from canonical.launchpad.webapp import canonical_url |
3131 | from canonical.launchpad.windmill.testing import lpuser |
3132 | @@ -18,6 +17,7 @@ |
3133 | SLEEP, |
3134 | ) |
3135 | from canonical.launchpad.windmill.testing.lpuser import login_person |
3136 | +from lp.app.enums import ServiceUsage |
3137 | from lp.testing import WindmillTestCase |
3138 | from lp.translations.interfaces.translationimportqueue import ( |
3139 | ITranslationImportQueue, |
3140 | @@ -41,8 +41,8 @@ |
3141 | 'field.potemplate', |
3142 | 'field.potemplate_name', |
3143 | 'field.language', |
3144 | - ] |
3145 | - } |
3146 | + ], |
3147 | + } |
3148 | SELECT_FIELDS = [ |
3149 | 'field.potemplate', |
3150 | 'field.language', |
3151 | @@ -55,8 +55,7 @@ |
3152 | input_tag = 'input' |
3153 | return ( |
3154 | u"//tr[contains(@class,'unseen')]" |
3155 | - u"//%s[@id='%s']" % (input_tag, field_id) |
3156 | - ) |
3157 | + u"//%s[@id='%s']" % (input_tag, field_id)) |
3158 | |
3159 | def _assertAllFieldsVisible(self, client, fields): |
3160 | """Assert that all given fields are visible. |
3161 | @@ -279,8 +278,9 @@ |
3162 | name="hubert", displayname="Hubert Hunt", password="test", |
3163 | email="hubert@example.com") |
3164 | # Create a project and an import entry with it. |
3165 | - product = self.factory.makeProduct(owner=hubert) |
3166 | - removeSecurityProxy(product).official_rosetta = True |
3167 | + product = self.factory.makeProduct( |
3168 | + owner=hubert, |
3169 | + translations_usage=ServiceUsage.LAUNCHPAD) |
3170 | productseries = product.getSeries('trunk') |
3171 | queue = getUtility(ITranslationImportQueue) |
3172 | potemplate = self.factory.makePOTemplate(productseries=productseries) |
Needs bugs for the two problems marked with XXXes (lines 422 et al, and line 453). Other than that, it looks good.