Merge lp:~henninge/launchpad/devel-737422-remove-translationsharinginfo into lp:launchpad

Proposed by Henning Eggers
Status: Merged
Merged at revision: 12655
Proposed branch: lp:~henninge/launchpad/devel-737422-remove-translationsharinginfo
Merge into: lp:launchpad
Diff against target: 1164 lines (+276/-597)
16 files modified
lib/lp/registry/interfaces/productseries.py (+5/-2)
lib/lp/registry/model/distribution.py (+11/-7)
lib/lp/registry/model/productseries.py (+16/-0)
lib/lp/registry/tests/test_productseries.py (+66/-0)
lib/lp/translations/browser/pofile.py (+13/-22)
lib/lp/translations/browser/potemplate.py (+13/-25)
lib/lp/translations/browser/productseries.py (+6/-10)
lib/lp/translations/browser/sourcepackage.py (+14/-15)
lib/lp/translations/interfaces/potemplate.py (+5/-0)
lib/lp/translations/model/pofile.py (+1/-26)
lib/lp/translations/model/potemplate.py (+22/-0)
lib/lp/translations/tests/test_potemplate.py (+86/-2)
lib/lp/translations/tests/test_translationtemplatescollection.py (+13/-0)
lib/lp/translations/utilities/tests/test_translation_sharing_info.py (+0/-308)
lib/lp/translations/utilities/translation_import.py (+5/-3)
lib/lp/translations/utilities/translationsharinginfo.py (+0/-177)
To merge this branch: bzr merge lp:~henninge/launchpad/devel-737422-remove-translationsharinginfo
Reviewer Review Type Date Requested Status
Deryck Hodge (community) code Approve
Review via email: mp+54184@code.launchpad.net

Commit message

Remove translationsharinginfo.

Description of the change

Details
=======

This is a clean-up branch that resulted in removing the module that I had meant to clean up. I found out that all of its needed (some was not needed) functionality could be achieved by using existing code (with some additions). A lot of files were touched but in total more code was removed than was added, so that must be good.

Proposed Fix
------------

Both sourcepackage and productseries implement IHasTranslationTemplates by using the HasTranslationTemplatesMixin. That mixin has methods like "had_current_translation_templates" which translationsharinginfo implemented, too. It also uses POTemplateCollection which is very useful for building queries.

The only thing that was missing was to get the "other side" of a packaging link. For a sourcepackage that's simple because each sourcepackage packages exactly one productseries, so SourcePackage.productseries is what I want. For a productseries there is not one corresponding sourcepackage, it only provides a list of packages. So I had to pick one. First criterium is that it needs to be a source package in Ubuntu. Second is that is is packaged in the "translation_focus" distroseris of Ubuntu or if not there in the "current" series or if not there in "any" series. In practice those fall backs won't be very important, though, because on Ubuntu main is translated in Launchpad and so all packages are very likely to be present in the translation focus. I added "getUbuntuTranslationFocusPackage" but better suggestions for a better method name are welcome. ;)

I found that I had implemented "getOtherSidePOFile" but that it was really finding the template on the other side and then looking up the POFile for on the given language on it. So I moved that code into POTemplate where it belongs (up on level), so I can use both "getOtherSidePOTemplate" and "getOtherSidePOFile".

Finally, POTemplateCollection is a nice tool but it was missing "restrictName" to search for a specific template name. So I added that, too.

Implementation details
----------------------

When you look at the browser code you'll see that the "is_sharing" is more complex now than it was before and is repeated in the different views. This is a result of bug 605924 which prevents me from using getCurrentTemplatesCollection and had_current_translation_templates. I intend to fix that bug in my next branch and update the is_sharing code with that.

Tests
-----

When writing the tests for getUbuntuTranslationFocusPackage I stumbled over the fact that a distroseries status is EXPERIMENTAL by default but the factory method sets it to DEVELOPMENT by default combined with the way Distroseries.currentseries finds a "current" series (which is not necessarily the series marked as CURRENT). Just so you know. ;-)

Here are the tests for the new code:

bin/test -vvcm lp.registry.tests.test_productseries \
    -t TestProductSeriesGetUbuntuTranslationFocusPackage
bin/test -vvcm lp.translations.tests.test_potemplate \
    -t test_getOtherSidePOTemplate
bin/test -vvcm lp.translations.tests.test_translationtemplatescollection

But to test for possible regressions, it would be safest to run all translation tests.

bin/test -vvcm lp.translations

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/interfaces/productseries.py
  lib/lp/registry/model/distribution.py
  lib/lp/registry/model/productseries.py
  lib/lp/registry/tests/test_productseries.py
  lib/lp/translations/browser/pofile.py
  lib/lp/translations/browser/potemplate.py
  lib/lp/translations/browser/productseries.py
  lib/lp/translations/browser/sourcepackage.py
  lib/lp/translations/interfaces/potemplate.py
  lib/lp/translations/model/pofile.py
  lib/lp/translations/model/potemplate.py
  lib/lp/translations/tests/test_potemplate.py
  lib/lp/translations/tests/test_translationtemplatescollection.py
  lib/lp/translations/utilities/translation_import.py

./lib/lp/translations/browser/pofile.py
     788: E301 expected 1 blank line, found 2
     904: E301 expected 1 blank line, found 2

To post a comment you must log in.
Revision history for this message
Deryck Hodge (deryck) wrote :

Nice refactor. Thanks for doing this!

review: Approve (code)
Revision history for this message
Henning Eggers (henninge) wrote :

Thanks! Unfortunately the branch has a design flaw that causes a lot of
"Forbidden Attribute" errors in tests. TranslationTemplatesCollection is not
security aware (no interface, not in configure.zcml) because it is only used
inside the model classes.

The next branch will fix this anyway and therefore I won't fix this here and
not land this branch.

1=== modified file 'lib/lp/registry/model/distribution.py'
2--- lib/lp/registry/model/distribution.py 2011-03-21 09:56:49 +0000
3+++ lib/lp/registry/model/distribution.py 2011-03-21 16:03:36 +0000
4@@ -1822,7 +1822,13 @@
5 assert sourcepackage is not None, (
6 "Translations sharing policy requires a SourcePackage.")
7
8- if not sourcepackage.productseries.has_current_translation_templates:
9+ has_upstream_translations = False
10+ productseries = sourcepackage.productseries
11+ if productseries is not None:
12+ collection = productseries.getTemplatesCollection()
13+ has_upstream_translations = bool(
14+ collection.restrictCurrent().select().any())
15+ if productseries is None or not has_upstream_translations:
16 # There is no known upstream template or series. Take the
17 # uploader's word for whether these are upstream translations
18 # (in which case they're shared) or not.
19
20=== modified file 'lib/lp/translations/browser/productseries.py'
21--- lib/lp/translations/browser/productseries.py 2011-03-18 17:12:56 +0000
22+++ lib/lp/translations/browser/productseries.py 2011-03-21 15:07:49 +0000
23@@ -459,7 +459,7 @@
24 sourcepackage = self.context.getUbuntuTranslationFocusPackage()
25 if sourcepackage is None:
26 return False
27- collection = sourcepackage.getTemplateCollection().restrictCurrent()
28+ collection = sourcepackage.getTemplatesCollection().restrictCurrent()
29 return bool(collection.select().any())
30
31 @property
32
33=== modified file 'lib/lp/translations/browser/sourcepackage.py'
34--- lib/lp/translations/browser/sourcepackage.py 2011-03-18 17:12:56 +0000
35+++ lib/lp/translations/browser/sourcepackage.py 2011-03-21 15:11:01 +0000
36@@ -58,7 +58,7 @@
37 productseries = self.context.productseries
38 if productseries is None:
39 return False
40- collection = productseries.getTemplateCollection().restrictCurrent()
41+ collection = productseries.getTemplatesCollection().restrictCurrent()
42 return bool(collection.select().any())
43
44 @property
45@@ -123,7 +123,7 @@
46 productseries = self.context.productseries
47 if productseries is None:
48 return False
49- collection = productseries.getTemplateCollection().restrictCurrent()
50+ collection = productseries.getTemplatesCollection().restrictCurrent()
51 return bool(collection.select().any())
52
53 def initialize(self):
54
55=== modified file 'lib/lp/translations/utilities/translation_import.py'
56--- lib/lp/translations/utilities/translation_import.py 2011-03-18 17:12:56 +0000
57+++ lib/lp/translations/utilities/translation_import.py 2011-03-21 15:09:50 +0000
58@@ -447,7 +447,7 @@
59 productseries = sourcepackage.productseries
60 if productseries is None:
61 return True
62- collection = productseries.getTemplateCollection().restrictCurrent()
63+ collection = productseries.getTemplatesCollection().restrictCurrent()
64 return not bool(collection.select().any())
65
66 @cachedproperty

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/interfaces/productseries.py'
2--- lib/lp/registry/interfaces/productseries.py 2011-03-08 15:28:40 +0000
3+++ lib/lp/registry/interfaces/productseries.py 2011-03-23 12:25:33 +0000
4@@ -241,8 +241,7 @@
5 description=_("Specify which files will be imported from the "
6 "source code branch.")),
7 ('devel', {'exported': True}),
8- exported=False
9- )
10+ exported=False)
11
12 potemplate_count = Int(
13 title=_("The total number of POTemplates in this series."),
14@@ -276,6 +275,10 @@
15 it will also work through the ancestry of the distroseries to try
16 to find a Packaging entry that may be relevant."""
17
18+ def getUbuntuTranslationFocusPackage(self):
19+ """Return the SourcePackage that packages this project in Ubuntu's
20+ translation focus or current series or any series, in that order."""
21+
22 def setPackaging(distroseries, sourcepackagename, owner):
23 """Create or update a Packaging record for this product series,
24 connecting it to the given distroseries and source package name.
25
26=== modified file 'lib/lp/registry/model/distribution.py'
27--- lib/lp/registry/model/distribution.py 2011-03-01 05:05:26 +0000
28+++ lib/lp/registry/model/distribution.py 2011-03-23 12:25:33 +0000
29@@ -207,9 +207,6 @@
30 HasTranslationImportsMixin,
31 )
32 from lp.translations.model.translationpolicy import TranslationPolicyMixin
33-from lp.translations.utilities.translationsharinginfo import (
34- has_upstream_template,
35- )
36
37
38 class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
39@@ -478,8 +475,9 @@
40 arch_mirrors = list(Store.of(self).find(
41 (MirrorDistroArchSeries.distribution_mirrorID,
42 Max(MirrorDistroArchSeries.freshness)),
43- MirrorDistroArchSeries.distribution_mirrorID.is_in(mirror_ids)
44- ).group_by(MirrorDistroArchSeries.distribution_mirrorID))
45+ MirrorDistroArchSeries.distribution_mirrorID.is_in(
46+ mirror_ids)).group_by(
47+ MirrorDistroArchSeries.distribution_mirrorID))
48 arch_mirror_freshness = {}
49 arch_mirror_freshness.update(
50 [(mirror_id, MirrorFreshness.items[mirror_freshness]) for
51@@ -778,7 +776,7 @@
52 def getCurrentSourceReleases(self, source_package_names):
53 """See `IDistribution`."""
54 return getUtility(IDistributionSet).getCurrentSourceReleases(
55- {self:source_package_names})
56+ {self: source_package_names})
57
58 @property
59 def has_any_specifications(self):
60@@ -1824,7 +1822,13 @@
61 assert sourcepackage is not None, (
62 "Translations sharing policy requires a SourcePackage.")
63
64- if not has_upstream_template(sourcepackage):
65+ has_upstream_translations = False
66+ productseries = sourcepackage.productseries
67+ if productseries is not None:
68+ collection = productseries.getTemplatesCollection()
69+ has_upstream_translations = bool(
70+ collection.restrictCurrent().select().any())
71+ if productseries is None or not has_upstream_translations:
72 # There is no known upstream template or series. Take the
73 # uploader's word for whether these are upstream translations
74 # (in which case they're shared) or not.
75
76=== modified file 'lib/lp/registry/model/productseries.py'
77--- lib/lp/registry/model/productseries.py 2011-01-21 08:12:29 +0000
78+++ lib/lp/registry/model/productseries.py 2011-03-23 12:25:33 +0000
79@@ -481,6 +481,22 @@
80 # the distroseries to try to find a relevant packaging record
81 raise NotFoundError(distroseries)
82
83+ def getUbuntuTranslationFocusPackage(self):
84+ """See `IProductSeries`."""
85+ ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
86+ translation_focus = ubuntu.translation_focus
87+ current_series = ubuntu.currentseries
88+ candidate = None
89+ for package in self.sourcepackages:
90+ if package.distroseries == translation_focus:
91+ return package
92+ if package.distroseries == current_series:
93+ candidate = package
94+ elif package.distroseries.distribution == ubuntu:
95+ if candidate is None:
96+ candidate = package
97+ return candidate
98+
99 def setPackaging(self, distroseries, sourcepackagename, owner):
100 """See IProductSeries."""
101 if distroseries.distribution.full_functionality:
102
103=== modified file 'lib/lp/registry/tests/test_productseries.py'
104--- lib/lp/registry/tests/test_productseries.py 2011-03-04 21:15:00 +0000
105+++ lib/lp/registry/tests/test_productseries.py 2011-03-23 12:25:33 +0000
106@@ -7,6 +7,7 @@
107
108 import transaction
109 from zope.component import getUtility
110+from zope.security.proxy import removeSecurityProxy
111
112 from canonical.launchpad.ftests import login
113 from canonical.testing.layers import (
114@@ -20,6 +21,7 @@
115 IProductSeries,
116 IProductSeriesSet,
117 )
118+from lp.registry.interfaces.series import SeriesStatus
119 from lp.testing import (
120 TestCaseWithFactory,
121 WebServiceTestCase,
122@@ -80,6 +82,70 @@
123 self.debian_series, self.sourcepackagename, self.person)
124
125
126+class TestProductSeriesGetUbuntuTranslationFocusPackage(TestCaseWithFactory):
127+ """Test for ProductSeries.getUbuntuTranslationFocusPackage."""
128+
129+ layer = DatabaseFunctionalLayer
130+
131+ def _makeSourcePackage(self, productseries,
132+ series_status=SeriesStatus.EXPERIMENTAL):
133+ """Make a sourcepckage that packages the productseries."""
134+ distroseries = self.factory.makeUbuntuDistroSeries(
135+ status=series_status)
136+ packaging = self.factory.makePackagingLink(
137+ productseries=productseries, distroseries=distroseries)
138+ return packaging.sourcepackage
139+
140+ def _test_packaged_in_series(
141+ self, in_translation_focus, in_current_series, in_other_series):
142+ """Test the given combination of packagings."""
143+ productseries = self.factory.makeProductSeries()
144+ package = None
145+ if in_other_series:
146+ package = self._makeSourcePackage(productseries)
147+ if in_current_series:
148+ package = self._makeSourcePackage(
149+ productseries, SeriesStatus.FROZEN)
150+ if in_translation_focus:
151+ package = self._makeSourcePackage(productseries)
152+ naked_distribution = removeSecurityProxy(
153+ package.distroseries.distribution)
154+ naked_distribution.translation_focus = package.distroseries
155+ self.assertEqual(
156+ package,
157+ productseries.getUbuntuTranslationFocusPackage())
158+
159+ def test_no_sourcepackage(self):
160+ self._test_packaged_in_series(
161+ in_translation_focus=False,
162+ in_current_series=False,
163+ in_other_series=False)
164+
165+ def test_packaged_in_translation_focus(self):
166+ # The productseries is packaged in the translation focus series
167+ # and others but only the focus is returned.
168+ self._test_packaged_in_series(
169+ in_translation_focus=True,
170+ in_current_series=True,
171+ in_other_series=True)
172+
173+ def test_packaged_in_current_series(self):
174+ # The productseries is packaged in the current series and others but
175+ # only the current is returned.
176+ self._test_packaged_in_series(
177+ in_translation_focus=False,
178+ in_current_series=True,
179+ in_other_series=True)
180+
181+ def test_packaged_in_other_series(self):
182+ # The productseries is not packaged in the translation focus or the
183+ # current series, so that packaging is returned.
184+ self._test_packaged_in_series(
185+ in_translation_focus=False,
186+ in_current_series=False,
187+ in_other_series=True)
188+
189+
190 class TestProductSeriesDrivers(TestCaseWithFactory):
191 """Test the 'drivers' attribute of a ProductSeries."""
192
193
194=== modified file 'lib/lp/translations/browser/pofile.py'
195--- lib/lp/translations/browser/pofile.py 2011-03-01 20:05:57 +0000
196+++ lib/lp/translations/browser/pofile.py 2011-03-23 12:25:33 +0000
197@@ -59,12 +59,6 @@
198 ITranslationImportQueue,
199 )
200 from lp.translations.interfaces.translationsperson import ITranslationsPerson
201-from lp.translations.utilities.translationsharinginfo import (
202- has_ubuntu_template,
203- has_upstream_template,
204- get_ubuntu_sharing_info,
205- get_upstream_sharing_info,
206- )
207
208
209 class POFileNavigation(Navigation):
210@@ -999,27 +993,24 @@
211
212 def is_sharing(self):
213 if self.is_upstream_pofile:
214- return has_ubuntu_template(
215- productseries=self.context.potemplate.productseries,
216- templatename=self.context.potemplate.name)
217+ productseries = self.context.potemplate.productseries
218+ other_side_object = (
219+ productseries.getUbuntuTranslationFocusPackage())
220 else:
221- return has_upstream_template(
222- sourcepackage=self.context.potemplate.sourcepackage,
223- templatename=self.context.potemplate.name)
224+ sourcepackage = self.context.potemplate.sourcepackage
225+ other_side_object = sourcepackage.productseries
226+ if other_side_object is None:
227+ return False
228+ collection = other_side_object.getTemplatesCollection()
229+ name = self.context.potemplate.name
230+ return bool(
231+ collection.restrictCurrent().restrictName(name).select().any())
232
233 @property
234 def sharing_pofile(self):
235- if self.is_upstream_pofile:
236- infos = get_ubuntu_sharing_info(
237- productseries=self.context.potemplate.productseries,
238- templatename=self.context.potemplate.name)
239- else:
240- infos = get_upstream_sharing_info(
241- sourcepackage=self.context.potemplate.sourcepackage,
242- templatename=self.context.potemplate.name)
243- if len(infos) == 0:
244+ potemplate = self.context.potemplate.getOtherSidePOTemplate()
245+ if potemplate is None:
246 return None
247- obj, potemplate = infos[0]
248 pofile = potemplate.getPOFileByLang(self.context.language.code)
249 if pofile is None:
250 pofile = potemplate.getDummyPOFile(
251
252=== modified file 'lib/lp/translations/browser/potemplate.py'
253--- lib/lp/translations/browser/potemplate.py 2011-03-08 09:59:36 +0000
254+++ lib/lp/translations/browser/potemplate.py 2011-03-23 12:25:33 +0000
255@@ -87,12 +87,6 @@
256 from lp.translations.interfaces.translationimportqueue import (
257 ITranslationImportQueue,
258 )
259-from lp.translations.utilities.translationsharinginfo import (
260- has_ubuntu_template,
261- get_ubuntu_sharing_info,
262- has_upstream_template,
263- get_upstream_sharing_info,
264- )
265
266
267 class POTemplateNavigation(Navigation):
268@@ -353,29 +347,23 @@
269 return self.context.translation_side == TranslationSide.UPSTREAM
270
271 def is_sharing(self):
272- if self.is_upstream_template:
273- return has_ubuntu_template(
274- productseries=self.context.productseries,
275- templatename=self.context.name)
276+ if self.is_upstream_pofile:
277+ productseries = self.context.productseries
278+ other_side_object = (
279+ productseries.getUbuntuTranslationFocusPackage())
280 else:
281- return has_upstream_template(
282- sourcepackage=self.context.sourcepackage,
283- templatename=self.context.name)
284+ sourcepackage = self.potemplate.sourcepackage
285+ other_side_object = sourcepackage.productseries
286+ if other_side_object is None:
287+ return False
288+ collection = other_side_object.getTemplatesCollection()
289+ name = self.context.name
290+ return bool(
291+ collection.restrictCurrent().restrictName(name).select().any())
292
293 @property
294 def sharing_template(self):
295- if self.is_upstream_template:
296- infos = get_ubuntu_sharing_info(
297- productseries=self.context.productseries,
298- templatename=self.context.name)
299- else:
300- infos = get_upstream_sharing_info(
301- sourcepackage=self.context.sourcepackage,
302- templatename=self.context.name)
303- if len(infos) == 0:
304- return None
305- obj, template = infos[0]
306- return template
307+ return self.context.getOtherSidePOTemplate()
308
309 def getTranslationTarget(self):
310 """See `TranslationSharingDetailsMixin`."""
311
312=== modified file 'lib/lp/translations/browser/productseries.py'
313--- lib/lp/translations/browser/productseries.py 2011-03-16 14:52:37 +0000
314+++ lib/lp/translations/browser/productseries.py 2011-03-23 12:25:33 +0000
315@@ -65,10 +65,6 @@
316 from lp.translations.interfaces.translations import (
317 TranslationsBranchImportMode,
318 )
319-from lp.translations.utilities.translationsharinginfo import (
320- has_ubuntu_template,
321- get_ubuntu_sharing_info,
322- )
323
324
325 class ProductSeriesTranslationsMenuMixIn:
326@@ -460,15 +456,15 @@
327 return check_permission("launchpad.TranslationsAdmin", self.context)
328
329 def is_sharing(self):
330- return has_ubuntu_template(productseries=self.context)
331+ sourcepackage = self.context.getUbuntuTranslationFocusPackage()
332+ if sourcepackage is None:
333+ return False
334+ collection = sourcepackage.getTemplatesCollection().restrictCurrent()
335+ return bool(collection.select().any())
336
337 @property
338 def sharing_sourcepackage(self):
339- infos = get_ubuntu_sharing_info(productseries=self.context)
340- if len(infos) == 0:
341- return None
342- sourcepackage, template = infos[0]
343- return sourcepackage
344+ return self.context.getUbuntuTranslationFocusPackage()
345
346 def getTranslationTarget(self):
347 """See `TranslationSharingDetailsMixin`."""
348
349=== modified file 'lib/lp/translations/browser/sourcepackage.py'
350--- lib/lp/translations/browser/sourcepackage.py 2011-03-16 14:33:28 +0000
351+++ lib/lp/translations/browser/sourcepackage.py 2011-03-23 12:25:33 +0000
352@@ -34,10 +34,6 @@
353 TranslationsBranchImportMode,
354 )
355 from lp.translations.model.translationpackagingjob import TranslationMergeJob
356-from lp.translations.utilities.translationsharinginfo import (
357- has_upstream_template,
358- get_upstream_sharing_info,
359- )
360
361
362 class SharingDetailsPermissionsMixin:
363@@ -59,16 +55,15 @@
364 return "Translations for %s" % self.context.displayname
365
366 def is_sharing(self):
367- return has_upstream_template(self.context)
368+ productseries = self.context.productseries
369+ if productseries is None:
370+ return False
371+ collection = productseries.getTemplatesCollection().restrictCurrent()
372+ return bool(collection.select().any())
373
374 @property
375 def sharing_productseries(self):
376- infos = get_upstream_sharing_info(self.context)
377- if len(infos) == 0:
378- return None
379-
380- productseries, template = infos[0]
381- return productseries
382+ return self.context.productseries
383
384 def getTranslationTarget(self):
385 """See `TranslationSharingDetailsMixin`."""
386@@ -124,14 +119,18 @@
387
388 page_title = "Sharing details"
389
390+ def is_sharing(self):
391+ productseries = self.context.productseries
392+ if productseries is None:
393+ return False
394+ collection = productseries.getTemplatesCollection().restrictCurrent()
395+ return bool(collection.select().any())
396+
397 def initialize(self):
398 if not getFeatureFlag('translations.sharing_information.enabled'):
399 raise NotFound(self.context, '+sharing-details')
400 super(SourcePackageTranslationSharingDetailsView, self).initialize()
401- has_no_upstream_templates = (
402- self.is_configuration_complete and
403- not has_upstream_template(self.context))
404- if has_no_upstream_templates:
405+ if self.is_configuration_complete and not self.is_sharing():
406 self.request.response.addInfoNotification(
407 structured(
408 'No upstream templates have been found yet. Please follow '
409
410=== modified file 'lib/lp/translations/interfaces/potemplate.py'
411--- lib/lp/translations/interfaces/potemplate.py 2011-03-01 17:40:06 +0000
412+++ lib/lp/translations/interfaces/potemplate.py 2011-03-23 12:25:33 +0000
413@@ -415,6 +415,11 @@
414 Return None if there is no such POFile.
415 """
416
417+ def getOtherSidePOTemplate():
418+ """Get the POTemplate with the same name on the other side of a
419+ packaging link.
420+ """
421+
422 def hasPluralMessage():
423 """Test whether this template has any message sets which are plural
424 message sets."""
425
426=== modified file 'lib/lp/translations/model/pofile.py'
427--- lib/lp/translations/model/pofile.py 2011-02-23 16:56:01 +0000
428+++ lib/lp/translations/model/pofile.py 2011-03-23 12:25:33 +0000
429@@ -66,7 +66,6 @@
430 MASTER_FLAVOR,
431 )
432 from canonical.launchpad.webapp.publisher import canonical_url
433-from lp.app.errors import NotFoundError
434 from lp.registry.interfaces.person import validate_public_person
435 from lp.services.propertycache import cachedproperty
436 from lp.translations.enums import RosettaImportStatus
437@@ -74,7 +73,6 @@
438 IPOFile,
439 IPOFileSet,
440 )
441-from lp.translations.interfaces.potemplate import IPOTemplateSet
442 from lp.translations.interfaces.potmsgset import TranslationCreditsType
443 from lp.translations.interfaces.side import (
444 ITranslationSideTraitsSet,
445@@ -401,30 +399,7 @@
446
447 def getOtherSidePOFile(self):
448 """See `IPOFile`."""
449- potemplateset = getUtility(IPOTemplateSet)
450- if self.potemplate.translation_side == TranslationSide.UBUNTU:
451- from lp.registry.model.sourcepackage import SourcePackage
452- productseries = SourcePackage(
453- self.potemplate.sourcepackagename,
454- self.potemplate.distroseries).productseries
455- if productseries is None:
456- return None
457- subset = potemplateset.getSubset(productseries=productseries)
458- else:
459- ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
460- distroseries = ubuntu.translation_focus
461- if distroseries is None:
462- distroseries = ubuntu.currentseries
463- try:
464- sourcepackage = self.potemplate.productseries.getPackage(
465- distroseries)
466- except NotFoundError:
467- return None
468- subset = potemplateset.getSubset(
469- distroseries=distroseries,
470- sourcepackagename=sourcepackage.sourcepackagename)
471-
472- other_potemplate = subset.getPOTemplateByName(self.potemplate.name)
473+ other_potemplate = self.potemplate.getOtherSidePOTemplate()
474 if other_potemplate is None:
475 return None
476 return other_potemplate.getPOFileByLang(self.language.code)
477
478=== modified file 'lib/lp/translations/model/potemplate.py'
479--- lib/lp/translations/model/potemplate.py 2011-03-01 17:40:06 +0000
480+++ lib/lp/translations/model/potemplate.py 2011-03-23 12:25:33 +0000
481@@ -541,6 +541,19 @@
482
483 return self._cached_pofiles_by_language[language_code]
484
485+ def getOtherSidePOTemplate(self):
486+ """See `IPOTemplate`."""
487+ if self.translation_side == TranslationSide.UBUNTU:
488+ other_side_object = self.sourcepackage.productseries
489+ else:
490+ other_side_object = (
491+ self.productseries.getUbuntuTranslationFocusPackage())
492+ if other_side_object is None:
493+ return None
494+ collection = (
495+ other_side_object.getTemplatesCollection().restrictCurrent())
496+ return collection.restrictName(self.name).select().one()
497+
498 def messageCount(self):
499 """See `IRosettaStats`."""
500 return self.messagecount
501@@ -1684,6 +1697,15 @@
502 """
503 return self.refine(POTemplate.iscurrent == current_value)
504
505+ def restrictName(self, template_name):
506+ """Select based on `POTemplate.name`.
507+
508+ :param template: The value for `name` that you are looking for.
509+ :return: A `TranslationTemplatesCollection based on this one but
510+ restricted to ones with the desired `name` value.
511+ """
512+ return self.refine(POTemplate.name == template_name)
513+
514 def joinPOFile(self):
515 """Join `POFile` into the collection.
516
517
518=== modified file 'lib/lp/translations/tests/test_potemplate.py'
519--- lib/lp/translations/tests/test_potemplate.py 2011-02-10 15:08:52 +0000
520+++ lib/lp/translations/tests/test_potemplate.py 2011-03-23 12:25:33 +0000
521@@ -8,7 +8,10 @@
522 from zope.component import getUtility
523 from zope.security.proxy import removeSecurityProxy
524
525-from canonical.testing.layers import DatabaseFunctionalLayer
526+from canonical.testing.layers import (
527+ DatabaseFunctionalLayer,
528+ ZopelessDatabaseLayer,
529+ )
530 from lp.app.enums import ServiceUsage
531 from lp.registry.interfaces.distribution import IDistributionSet
532 from lp.services.worlddata.interfaces.language import ILanguageSet
533@@ -22,7 +25,6 @@
534 )
535 from lp.translations.model.potemplate import (
536 get_pofiles_for,
537- POTemplate,
538 )
539
540
541@@ -595,3 +597,85 @@
542 pofiles = get_pofiles_for([self.potemplate], self.greek)
543 pofile = pofiles[0]
544 self.assertIsInstance(pofile, DummyPOFile)
545+
546+
547+class TestPOTemplateUbuntuUpstreamSharingMixin:
548+ """Test sharing between Ubuntu und upstream POTemplates."""
549+
550+ layer = ZopelessDatabaseLayer
551+
552+ def createData(self):
553+ self.shared_template_name = self.factory.getUniqueString()
554+ self.distroseries = self.factory.makeUbuntuDistroSeries()
555+ self.distroseries.distribution.translation_focus = (
556+ self.distroseries)
557+ self.sourcepackage = self.factory.makeSourcePackage(
558+ distroseries=self.distroseries)
559+ self.productseries = self.factory.makeProductSeries()
560+
561+ def makeThisSidePOTemplate(self):
562+ """Create POTemplate on this side."""
563+ raise NotImplementedError
564+
565+ def makeOtherSidePOTemplate(self):
566+ """Create POTemplate on the other side. Override in subclass."""
567+ raise NotImplementedError
568+
569+ def _setPackagingLink(self):
570+ """Create the packaging link from source package to product series."""
571+ self.factory.makePackagingLink(
572+ productseries=self.productseries,
573+ sourcepackage=self.sourcepackage)
574+
575+ def test_getOtherSidePOTemplate_none(self):
576+ # Without a packaging link, None is returned.
577+ potemplate = self.makeThisSidePOTemplate()
578+ self.assertIs(None, potemplate.getOtherSidePOTemplate())
579+
580+ def test_getOtherSidePOTemplate_linked_no_template(self):
581+ # No sharing template exists on the other side.
582+ self._setPackagingLink()
583+ potemplate = self.makeThisSidePOTemplate()
584+ self.assertIs(None, potemplate.getOtherSidePOTemplate())
585+
586+ def test_getOtherSidePOTemplate_shared(self):
587+ # This is how sharing should look like.
588+ this_potemplate = self.makeThisSidePOTemplate()
589+ other_potemplate = self.makeOtherSidePOTemplate()
590+ self._setPackagingLink()
591+ self.assertEquals(
592+ other_potemplate, this_potemplate.getOtherSidePOTemplate())
593+
594+
595+class TestPOTemplateUbuntuSharing(TestCaseWithFactory,
596+ TestPOTemplateUbuntuUpstreamSharingMixin):
597+ """Test sharing on Ubuntu side."""
598+
599+ def setUp(self):
600+ super(TestPOTemplateUbuntuSharing, self).setUp()
601+ self.createData()
602+
603+ def makeThisSidePOTemplate(self):
604+ return self.factory.makePOTemplate(
605+ sourcepackage=self.sourcepackage, name=self.shared_template_name)
606+
607+ def makeOtherSidePOTemplate(self):
608+ return self.factory.makePOTemplate(
609+ productseries=self.productseries, name=self.shared_template_name)
610+
611+
612+class TestPOTemplateUpstreamSharing(TestCaseWithFactory,
613+ TestPOTemplateUbuntuUpstreamSharingMixin):
614+ """Test sharing on upstream side."""
615+
616+ def setUp(self):
617+ super(TestPOTemplateUpstreamSharing, self).setUp()
618+ self.createData()
619+
620+ def makeThisSidePOTemplate(self):
621+ return self.factory.makePOTemplate(
622+ productseries=self.productseries, name=self.shared_template_name)
623+
624+ def makeOtherSidePOTemplate(self):
625+ return self.factory.makePOTemplate(
626+ sourcepackage=self.sourcepackage, name=self.shared_template_name)
627
628=== modified file 'lib/lp/translations/tests/test_translationtemplatescollection.py'
629--- lib/lp/translations/tests/test_translationtemplatescollection.py 2010-10-04 19:50:45 +0000
630+++ lib/lp/translations/tests/test_translationtemplatescollection.py 2011-03-23 12:25:33 +0000
631@@ -171,6 +171,19 @@
632 self.assertContentEqual(
633 [template], obsolete_templates.select())
634
635+ def test_restrictName(self):
636+ trunk = self.factory.makeProduct().getSeries('trunk')
637+ template = self.factory.makePOTemplate(productseries=trunk)
638+ template_name = template.name
639+ # Other template that will not be returned.
640+ self.factory.makePOTemplate(productseries=trunk)
641+ collection = TranslationTemplatesCollection()
642+ by_series = collection.restrictProductSeries(trunk)
643+
644+ same_name_templates = by_series.restrictName(template_name)
645+ self.assertContentEqual(
646+ [template], same_name_templates.select())
647+
648 def test_joinPOFile(self):
649 trunk = self.factory.makeProduct().getSeries('trunk')
650 translated_template = self.factory.makePOTemplate(productseries=trunk)
651
652=== removed file 'lib/lp/translations/utilities/tests/test_translation_sharing_info.py'
653--- lib/lp/translations/utilities/tests/test_translation_sharing_info.py 2011-02-23 12:16:59 +0000
654+++ lib/lp/translations/utilities/tests/test_translation_sharing_info.py 1970-01-01 00:00:00 +0000
655@@ -1,308 +0,0 @@
656-# Copyright 2009 Canonical Ltd. This software is licensed under the
657-# GNU Affero General Public License version 3 (see the file LICENSE).
658-
659-__metaclass__ = type
660-
661-from canonical.testing.layers import ZopelessDatabaseLayer
662-from lp.testing import TestCaseWithFactory
663-from lp.translations.utilities.translationsharinginfo import (
664- get_ubuntu_sharing_info,
665- get_upstream_sharing_info,
666- has_ubuntu_template,
667- has_upstream_template,
668- )
669-
670-
671-class TestTranslationSharingInfo(TestCaseWithFactory):
672- """Tests for `get_upstream_sharing_info` and `get_ubuntu_sharing_info`"""
673-
674- layer = ZopelessDatabaseLayer
675-
676- def _makeSourcePackage(self):
677- """Create an Ubuntu source package."""
678- distroseries = self.factory.makeUbuntuDistroSeries()
679- return self.factory.makeSourcePackage(distroseries=distroseries)
680-
681- def _makeUpstreamProductSeries(self, sourcepackage):
682- """Create a product series and link it to the source package."""
683- productseries = self.factory.makeProductSeries()
684- self.factory.makePackagingLink(
685- distroseries=sourcepackage.distroseries,
686- sourcepackagename=sourcepackage.sourcepackagename,
687- productseries=productseries)
688- return productseries
689-
690- def test_no_upstream(self):
691- # With no upstream the sharing information on a source package will
692- # be empty.
693- sourcepackage = self._makeSourcePackage()
694- self.assertEquals(
695- [],
696- get_upstream_sharing_info(sourcepackage=sourcepackage))
697-
698- def test_no_upstream_with_name(self):
699- # With no upstream the sharing information on a source package will
700- # be empty, even when searching for a specific template name.
701- sourcepackage = self._makeSourcePackage()
702- templatename = self.factory.getUniqueString()
703- self.assertEquals(
704- [],
705- get_upstream_sharing_info(
706- sourcepackage=sourcepackage,
707- templatename=templatename))
708-
709- def test_upstream_no_template(self):
710- # With an upstream without a template the sharing information on a
711- # source package will be empty.
712- sourcepackage = self._makeSourcePackage()
713- productseries = self._makeUpstreamProductSeries(sourcepackage)
714- self.assertEquals(
715- [(productseries, None)],
716- get_upstream_sharing_info(sourcepackage=sourcepackage))
717-
718- def test_upstream_no_template_with_name(self):
719- # With an upstream without a template the sharing information on a
720- # source package will be empty, even when searching for a specific
721- # template name.
722- sourcepackage = self._makeSourcePackage()
723- productseries = self._makeUpstreamProductSeries(sourcepackage)
724- templatename = self.factory.getUniqueString()
725- self.assertEquals(
726- [(productseries, None)],
727- get_upstream_sharing_info(
728- sourcepackage=sourcepackage,
729- templatename=templatename))
730-
731- def test_upstream_one_template(self):
732- # With an upstream template the sharing information on a
733- # source package will return that.
734- sourcepackage = self._makeSourcePackage()
735- productseries = self._makeUpstreamProductSeries(sourcepackage)
736- potemplate = self.factory.makePOTemplate(productseries=productseries)
737- self.assertEquals(
738- [(productseries, potemplate)],
739- get_upstream_sharing_info(sourcepackage=sourcepackage))
740-
741- def test_upstream_one_template_with_name(self):
742- # With an upstream template the sharing information on a
743- # source package will return that, even when searching for a
744- # specific template name.
745- sourcepackage = self._makeSourcePackage()
746- productseries = self._makeUpstreamProductSeries(sourcepackage)
747- templatename = self.factory.getUniqueString()
748- potemplate = self.factory.makePOTemplate(
749- productseries=productseries, name=templatename)
750- self.assertEquals(
751- [(productseries, potemplate)],
752- get_upstream_sharing_info(
753- sourcepackage=sourcepackage,
754- templatename=templatename))
755-
756- def test_upstream_one_template_with_different_name(self):
757- # With an upstream template the sharing information on a
758- # source package will be empty if a different name is queried.
759- sourcepackage = self._makeSourcePackage()
760- productseries = self._makeUpstreamProductSeries(sourcepackage)
761- templatename = self.factory.getUniqueString()
762- self.factory.makePOTemplate(
763- productseries=productseries, name=templatename)
764- different_templatename = self.factory.getUniqueString()
765- self.assertEquals(
766- [(productseries, None)],
767- get_upstream_sharing_info(
768- sourcepackage=sourcepackage,
769- templatename=different_templatename))
770-
771- def test_no_ubuntu(self):
772- # With no sourcepackage the sharing information on a source package
773- # will be empty.
774- productseries = self.factory.makeProductSeries()
775- self.assertContentEqual(
776- [],
777- get_ubuntu_sharing_info(productseries=productseries))
778-
779- def test_no_ubuntu_with_name(self):
780- # With no sourcepackage the sharing information on a source package
781- # will be empty, even when searching for a specific template name.
782- productseries = self.factory.makeProductSeries()
783- templatename = self.factory.getUniqueString()
784- self.assertContentEqual(
785- [],
786- get_ubuntu_sharing_info(
787- productseries=productseries, templatename=templatename))
788-
789- def test_ubuntu_no_template(self):
790- # With a sourcepackage without a template the sharing information
791- # on a productseries will be empty.
792- sourcepackage = self._makeSourcePackage()
793- productseries = self._makeUpstreamProductSeries(sourcepackage)
794- self.assertContentEqual(
795- [(sourcepackage, None)],
796- get_ubuntu_sharing_info(productseries=productseries))
797-
798- def test_ubuntu_no_template_with_name(self):
799- # With a sourcepackage without a template the sharing information
800- # on a productseries will be empty, even when searching for a
801- # specific template name.
802- sourcepackage = self._makeSourcePackage()
803- productseries = self._makeUpstreamProductSeries(sourcepackage)
804- templatename = self.factory.getUniqueString()
805- self.assertContentEqual(
806- [(sourcepackage, None)],
807- get_ubuntu_sharing_info(
808- productseries=productseries, templatename=templatename))
809-
810- def test_ubuntu_one_template(self):
811- # With a sourcepackage template the sharing information on a
812- # source package will return that.
813- sourcepackage = self._makeSourcePackage()
814- productseries = self._makeUpstreamProductSeries(sourcepackage)
815- potemplate = self.factory.makePOTemplate(sourcepackage=sourcepackage)
816- self.assertContentEqual(
817- [(sourcepackage, potemplate)],
818- get_ubuntu_sharing_info(
819- productseries=productseries))
820-
821- def test_ubuntu_one_template_with_name(self):
822- # With a sourcepackage template the sharing information on a
823- # productseries will return that, even when searching for a
824- # specific template name.
825- sourcepackage = self._makeSourcePackage()
826- productseries = self._makeUpstreamProductSeries(sourcepackage)
827- templatename = self.factory.getUniqueString()
828- potemplate = self.factory.makePOTemplate(
829- sourcepackage=sourcepackage,
830- name=templatename)
831- self.assertContentEqual(
832- [(sourcepackage, potemplate)],
833- get_ubuntu_sharing_info(
834- productseries=productseries, templatename=templatename))
835-
836- def test_ubuntu_one_template_with_different_name(self):
837- # With a sourcepackage template the sharing information on a
838- # productseries will be empty if a different name is queried.
839- sourcepackage = self._makeSourcePackage()
840- productseries = self._makeUpstreamProductSeries(sourcepackage)
841- templatename = self.factory.getUniqueString()
842- self.factory.makePOTemplate(
843- sourcepackage=sourcepackage,
844- name=templatename)
845- different_templatename = self.factory.getUniqueString()
846- self.assertContentEqual(
847- [(sourcepackage, None)],
848- get_ubuntu_sharing_info(
849- productseries=productseries,
850- templatename=different_templatename))
851-
852- def test_has_upstream_template_no_productseries(self):
853- # Without an upstream project, no upstream templates won't be
854- # available either.
855- sourcepackage = self._makeSourcePackage()
856- templatename = self.factory.getUniqueString()
857-
858- self.assertFalse(
859- has_upstream_template(sourcepackage, templatename))
860-
861- def test_has_upstream_template_no_template(self):
862- # No template exists on the upstream project.
863- sourcepackage = self._makeSourcePackage()
864- productseries = self._makeUpstreamProductSeries(sourcepackage)
865- templatename = self.factory.getUniqueString()
866-
867- self.assertFalse(
868- has_upstream_template(sourcepackage, templatename))
869-
870- def test_has_upstream_template_one_template(self):
871- # There is one template on the upstream project that matches the
872- # name.
873- sourcepackage = self._makeSourcePackage()
874- productseries = self._makeUpstreamProductSeries(sourcepackage)
875- templatename = self.factory.getUniqueString()
876- self.factory.makePOTemplate(
877- productseries=productseries, name=templatename)
878-
879- self.assertTrue(
880- has_upstream_template(sourcepackage, templatename))
881-
882- def test_has_upstream_template_one_template_wrong_name(self):
883- # There is one template on the upstream project but it matches not
884- # the requested name.
885- sourcepackage = self._makeSourcePackage()
886- productseries = self._makeUpstreamProductSeries(sourcepackage)
887- self.factory.makePOTemplate(productseries=productseries)
888- different_templatename = self.factory.getUniqueString()
889-
890- self.assertFalse(
891- has_upstream_template(sourcepackage, different_templatename))
892-
893- def test_has_upstream_template_any_template(self):
894- # There is one template on the upstream project, not specifying
895- # a template name still indicates that there is a template.
896- sourcepackage = self._makeSourcePackage()
897- productseries = self._makeUpstreamProductSeries(sourcepackage)
898- self.factory.makePOTemplate(productseries=productseries)
899-
900- self.assertTrue(has_upstream_template(sourcepackage))
901-
902- def test_has_upstream_template_any_template_none(self):
903- # There is no template on the upstream project.
904- sourcepackage = self._makeSourcePackage()
905- self._makeUpstreamProductSeries(sourcepackage)
906-
907- self.assertFalse(has_upstream_template(sourcepackage))
908-
909- def test_has_ubuntu_template_no_sourcepackage(self):
910- # There is no Ubuntu source package, so no Ubuntu template can be
911- # found.
912- productseries = self.factory.makeProductSeries()
913- templatename = self.factory.getUniqueString()
914-
915- self.assertFalse(has_ubuntu_template(productseries, templatename))
916-
917- def test_has_ubuntu_template_no_template(self):
918- # The Ubuntu source package has no template.
919- sourcepackage = self._makeSourcePackage()
920- productseries = self._makeUpstreamProductSeries(sourcepackage)
921- templatename = self.factory.getUniqueString()
922-
923- self.assertFalse(has_ubuntu_template(productseries, templatename))
924-
925- def test_has_ubuntu_template_one_template(self):
926- # There is one template on the Ubuntu source package that matches
927- # the name.
928- sourcepackage = self._makeSourcePackage()
929- productseries = self._makeUpstreamProductSeries(sourcepackage)
930- templatename = self.factory.getUniqueString()
931- self.factory.makePOTemplate(
932- sourcepackage=sourcepackage, name=templatename)
933-
934- self.assertTrue(has_ubuntu_template(productseries, templatename))
935-
936- def test_has_ubuntu_template_one_template_wrong_name(self):
937- # There is one template on the Ubuntu source package but it matches
938- # not the requested name.
939- sourcepackage = self._makeSourcePackage()
940- productseries = self._makeUpstreamProductSeries(sourcepackage)
941- templatename = self.factory.getUniqueString()
942- self.factory.makePOTemplate(
943- sourcepackage=sourcepackage, name=templatename)
944- different_templatename = self.factory.getUniqueString()
945-
946- self.assertFalse(
947- has_ubuntu_template(productseries, different_templatename))
948-
949- def test_has_ubuntu_template_any_template(self):
950- # There is one template on the Ubuntu source package, not specifying
951- # a template name still indicates that there is a template.
952- sourcepackage= self._makeSourcePackage()
953- productseries = self._makeUpstreamProductSeries(sourcepackage)
954- self.factory.makePOTemplate(sourcepackage=sourcepackage)
955-
956- self.assertTrue(has_ubuntu_template(productseries))
957-
958- def test_has_ubuntu_template_any_template_none(self):
959- # There is no template on the Ubuntu source package.
960- sourcepackage = self._makeSourcePackage()
961- productseries = self._makeUpstreamProductSeries(sourcepackage)
962-
963- self.assertFalse(has_ubuntu_template(productseries))
964
965=== modified file 'lib/lp/translations/utilities/translation_import.py'
966--- lib/lp/translations/utilities/translation_import.py 2011-02-23 12:02:36 +0000
967+++ lib/lp/translations/utilities/translation_import.py 2011-03-23 12:25:33 +0000
968@@ -444,9 +444,11 @@
969 sourcepackage = getUtility(ISourcePackageFactory).new(
970 self.translation_import_queue_entry.sourcepackagename,
971 self.translation_import_queue_entry.distroseries)
972- from lp.translations.utilities.translationsharinginfo import (
973- has_upstream_template)
974- return not has_upstream_template(sourcepackage)
975+ productseries = sourcepackage.productseries
976+ if productseries is None:
977+ return True
978+ collection = productseries.getTemplatesCollection().restrictCurrent()
979+ return not bool(collection.select().any())
980
981 @cachedproperty
982 def translations_are_msgids(self):
983
984=== removed file 'lib/lp/translations/utilities/translationsharinginfo.py'
985--- lib/lp/translations/utilities/translationsharinginfo.py 2011-02-24 17:33:35 +0000
986+++ lib/lp/translations/utilities/translationsharinginfo.py 1970-01-01 00:00:00 +0000
987@@ -1,177 +0,0 @@
988-# Copyright 2011 Canonical Ltd. This software is licensed under the
989-# GNU Affero General Public License version 3 (see the file LICENSE).
990-
991-"""Provide sharing information.
992-
993-This module defines two different types of functions that provide
994-information about what sharing options are available on the other side of a
995-packaging link. Since they perform similar but slightly different complex
996-database queries combining them in any way will usually be wrong.
997-
998-get_ubuntu_sharing_info and get_upstream_sharing_info will give you
999-information about the source package or productseries respectively,
1000-combined with possibly available templates. You can restrict the search
1001-by specifying a template name.
1002-
1003-has_ubuntu_template and has_upstream_template make a direct search for a
1004-template of the given name on the other side. They do not search for
1005-source package or productseries but will only return True if an actual
1006-template exists. That is a significant difference to the get_* functions.
1007-"""
1008-
1009-__metaclass__ = type
1010-__all__ = [
1011- 'get_ubuntu_sharing_info',
1012- 'get_upstream_sharing_info',
1013- 'has_ubuntu_template',
1014- 'has_upstream_template',
1015- ]
1016-
1017-from storm.expr import (\
1018- And,
1019- Join,
1020- LeftJoin,
1021- )
1022-
1023-from canonical.launchpad.interfaces.lpstorm import IStore
1024-from lp.registry.model.distroseries import DistroSeries
1025-from lp.registry.model.packaging import Packaging
1026-from lp.registry.model.productseries import ProductSeries
1027-from lp.registry.model.sourcepackage import SourcePackage
1028-from lp.registry.model.sourcepackagename import SourcePackageName
1029-from lp.translations.model.potemplate import POTemplate
1030-
1031-
1032-def find_ubuntu_sharing_info(productseries, templatename=None,
1033- template_only=False):
1034- """Return a `ResultSet` of sharing information for this productseries.
1035-
1036- Target is either a productseries or a source package.
1037- :param productseries: The target productseries or None.
1038- :param templatename: The name of the template to find information for or
1039- None to get information about any sharing template in any series.
1040- :param template_only: Return only `POTemplate` instances.
1041- :returns: A result set of ('Distroseries', SourcePackageName, POTemplate)
1042- tuples.
1043- """
1044-
1045- # SELECT *
1046- # FROM Packaging
1047- # JOIN Distroseries
1048- # ON Packaging.distroseries = Distroseries.id
1049- # JOIN SourcePackageName
1050- # ON Packaging.sourcepackagename = SourcePackageName.id
1051- # LEFT JOIN POTemplate
1052- # ON Packaging.distroseries = POTemplate.distroseries AND
1053- # Packaging.sourcepackagename = POTemplate.sourcepackagename AND
1054- # POTemplate.name = templatename
1055- # WHERE Packaging.productseries = productseries
1056- #
1057- if templatename is None:
1058- potemplate_condition = And(
1059- Packaging.distroseriesID == POTemplate.distroseriesID,
1060- Packaging.sourcepackagenameID == POTemplate.sourcepackagenameID)
1061- else:
1062- potemplate_condition = And(
1063- Packaging.distroseriesID == POTemplate.distroseriesID,
1064- Packaging.sourcepackagenameID ==
1065- POTemplate.sourcepackagenameID,
1066- POTemplate.name == templatename)
1067- if template_only:
1068- prejoin = Join(
1069- Packaging,
1070- POTemplate,
1071- potemplate_condition)
1072- result_classes = POTemplate
1073- else:
1074- prejoin = LeftJoin(
1075- Join(
1076- Join(
1077- Packaging, DistroSeries,
1078- Packaging.distroseriesID == DistroSeries.id),
1079- SourcePackageName,
1080- Packaging.sourcepackagenameID == SourcePackageName.id),
1081- POTemplate,
1082- potemplate_condition)
1083- result_classes = (DistroSeries, SourcePackageName, POTemplate)
1084- conditions = [
1085- Packaging.productseries == productseries,
1086- ]
1087- return IStore(Packaging).using(prejoin).find(
1088- result_classes, *conditions)
1089-
1090-
1091-def find_upstream_sharing_info(sourcepackage,
1092- templatename=None, template_only=False):
1093- """Return a `ResultSet` of sharing information for this sourcepackage.
1094-
1095- :param distroseries: The target distroseries or None.
1096- :param sourcepackagename: The target sourcepackagename or None.
1097- :param templatename: The name of the template to find information for or
1098- None to get information about any sharing template in any series.
1099- :param template_only: Return only `POTemplate` instances.
1100- :returns: A ResultSet of (ProductSeries, POTemplate) tuples.
1101- """
1102- # SELECT *
1103- # FROM Packaging
1104- # JOIN ProductSeries
1105- # ON Packaging.productseries = Productseris.id
1106- # LEFT JOIN POTemplate
1107- # ON Packaging.productseries = POTemplate.productseries AND
1108- # POTemplate.name = templatename
1109- # WHERE Packaging.distroseries = distroseries AND
1110- # Packaging.sourcepackagename = sourcepackagename
1111- #
1112- if templatename is None:
1113- potemplate_condition = (
1114- Packaging.productseriesID == POTemplate.productseriesID)
1115- else:
1116- potemplate_condition = And(
1117- Packaging.productseriesID == POTemplate.productseriesID,
1118- POTemplate.name == templatename)
1119- if template_only:
1120- prejoin = Join(
1121- Packaging, POTemplate, potemplate_condition)
1122- result_classes = POTemplate
1123- else:
1124- prejoin = LeftJoin(
1125- Join(
1126- Packaging, ProductSeries,
1127- Packaging.productseriesID == ProductSeries.id),
1128- POTemplate,
1129- potemplate_condition)
1130- result_classes = (ProductSeries, POTemplate)
1131- conditions = [
1132- Packaging.distroseries == sourcepackage.distroseries,
1133- Packaging.sourcepackagename == sourcepackage.sourcepackagename,
1134- ]
1135-
1136- return IStore(Packaging).using(prejoin).find(
1137- result_classes, *conditions)
1138-
1139-
1140-def get_ubuntu_sharing_info(productseries, templatename=None):
1141- """Return a list of sharing information for the given target."""
1142- return [
1143- (SourcePackage(packagename, series), name)
1144- for series, packagename, name in find_ubuntu_sharing_info(
1145- productseries, templatename)]
1146-
1147-
1148-def get_upstream_sharing_info(sourcepackage, templatename=None):
1149- """Return a list of sharing information for the given target."""
1150- return list(find_upstream_sharing_info(sourcepackage, templatename))
1151-
1152-
1153-def has_ubuntu_template(productseries, templatename=None):
1154- """Check for existence of ubuntu template."""
1155- result = find_ubuntu_sharing_info(
1156- productseries, templatename, template_only=True)
1157- return not result.is_empty()
1158-
1159-
1160-def has_upstream_template(sourcepackage, templatename=None):
1161- """Check for existence of upstream template."""
1162- result = find_upstream_sharing_info(
1163- sourcepackage, templatename, template_only=True)
1164- return not result.is_empty()