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.

=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py 2011-03-21 09:56:49 +0000
+++ lib/lp/registry/model/distribution.py 2011-03-21 16:03:36 +0000
@@ -1822,7 +1822,13 @@
1822 assert sourcepackage is not None, (1822 assert sourcepackage is not None, (
1823 "Translations sharing policy requires a SourcePackage.")1823 "Translations sharing policy requires a SourcePackage.")
18241824
1825 if not sourcepackage.productseries.has_current_translation_templates:1825 has_upstream_translations = False
1826 productseries = sourcepackage.productseries
1827 if productseries is not None:
1828 collection = productseries.getTemplatesCollection()
1829 has_upstream_translations = bool(
1830 collection.restrictCurrent().select().any())
1831 if productseries is None or not has_upstream_translations:
1826 # There is no known upstream template or series. Take the1832 # There is no known upstream template or series. Take the
1827 # uploader's word for whether these are upstream translations1833 # uploader's word for whether these are upstream translations
1828 # (in which case they're shared) or not.1834 # (in which case they're shared) or not.
18291835
=== modified file 'lib/lp/translations/browser/productseries.py'
--- lib/lp/translations/browser/productseries.py 2011-03-18 17:12:56 +0000
+++ lib/lp/translations/browser/productseries.py 2011-03-21 15:07:49 +0000
@@ -459,7 +459,7 @@
459 sourcepackage = self.context.getUbuntuTranslationFocusPackage()459 sourcepackage = self.context.getUbuntuTranslationFocusPackage()
460 if sourcepackage is None:460 if sourcepackage is None:
461 return False461 return False
462 collection = sourcepackage.getTemplateCollection().restrictCurrent()462 collection = sourcepackage.getTemplatesCollection().restrictCurrent()
463 return bool(collection.select().any())463 return bool(collection.select().any())
464464
465 @property465 @property
466466
=== modified file 'lib/lp/translations/browser/sourcepackage.py'
--- lib/lp/translations/browser/sourcepackage.py 2011-03-18 17:12:56 +0000
+++ lib/lp/translations/browser/sourcepackage.py 2011-03-21 15:11:01 +0000
@@ -58,7 +58,7 @@
58 productseries = self.context.productseries58 productseries = self.context.productseries
59 if productseries is None:59 if productseries is None:
60 return False60 return False
61 collection = productseries.getTemplateCollection().restrictCurrent()61 collection = productseries.getTemplatesCollection().restrictCurrent()
62 return bool(collection.select().any())62 return bool(collection.select().any())
6363
64 @property64 @property
@@ -123,7 +123,7 @@
123 productseries = self.context.productseries123 productseries = self.context.productseries
124 if productseries is None:124 if productseries is None:
125 return False125 return False
126 collection = productseries.getTemplateCollection().restrictCurrent()126 collection = productseries.getTemplatesCollection().restrictCurrent()
127 return bool(collection.select().any())127 return bool(collection.select().any())
128128
129 def initialize(self):129 def initialize(self):
130130
=== modified file 'lib/lp/translations/utilities/translation_import.py'
--- lib/lp/translations/utilities/translation_import.py 2011-03-18 17:12:56 +0000
+++ lib/lp/translations/utilities/translation_import.py 2011-03-21 15:09:50 +0000
@@ -447,7 +447,7 @@
447 productseries = sourcepackage.productseries447 productseries = sourcepackage.productseries
448 if productseries is None:448 if productseries is None:
449 return True449 return True
450 collection = productseries.getTemplateCollection().restrictCurrent()450 collection = productseries.getTemplatesCollection().restrictCurrent()
451 return not bool(collection.select().any())451 return not bool(collection.select().any())
452452
453 @cachedproperty453 @cachedproperty

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/registry/interfaces/productseries.py'
--- lib/lp/registry/interfaces/productseries.py 2011-03-08 15:28:40 +0000
+++ lib/lp/registry/interfaces/productseries.py 2011-03-23 12:25:33 +0000
@@ -241,8 +241,7 @@
241 description=_("Specify which files will be imported from the "241 description=_("Specify which files will be imported from the "
242 "source code branch.")),242 "source code branch.")),
243 ('devel', {'exported': True}),243 ('devel', {'exported': True}),
244 exported=False244 exported=False)
245 )
246245
247 potemplate_count = Int(246 potemplate_count = Int(
248 title=_("The total number of POTemplates in this series."),247 title=_("The total number of POTemplates in this series."),
@@ -276,6 +275,10 @@
276 it will also work through the ancestry of the distroseries to try275 it will also work through the ancestry of the distroseries to try
277 to find a Packaging entry that may be relevant."""276 to find a Packaging entry that may be relevant."""
278277
278 def getUbuntuTranslationFocusPackage(self):
279 """Return the SourcePackage that packages this project in Ubuntu's
280 translation focus or current series or any series, in that order."""
281
279 def setPackaging(distroseries, sourcepackagename, owner):282 def setPackaging(distroseries, sourcepackagename, owner):
280 """Create or update a Packaging record for this product series,283 """Create or update a Packaging record for this product series,
281 connecting it to the given distroseries and source package name.284 connecting it to the given distroseries and source package name.
282285
=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py 2011-03-01 05:05:26 +0000
+++ lib/lp/registry/model/distribution.py 2011-03-23 12:25:33 +0000
@@ -207,9 +207,6 @@
207 HasTranslationImportsMixin,207 HasTranslationImportsMixin,
208 )208 )
209from lp.translations.model.translationpolicy import TranslationPolicyMixin209from lp.translations.model.translationpolicy import TranslationPolicyMixin
210from lp.translations.utilities.translationsharinginfo import (
211 has_upstream_template,
212 )
213210
214211
215class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,212class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
@@ -478,8 +475,9 @@
478 arch_mirrors = list(Store.of(self).find(475 arch_mirrors = list(Store.of(self).find(
479 (MirrorDistroArchSeries.distribution_mirrorID,476 (MirrorDistroArchSeries.distribution_mirrorID,
480 Max(MirrorDistroArchSeries.freshness)),477 Max(MirrorDistroArchSeries.freshness)),
481 MirrorDistroArchSeries.distribution_mirrorID.is_in(mirror_ids)478 MirrorDistroArchSeries.distribution_mirrorID.is_in(
482 ).group_by(MirrorDistroArchSeries.distribution_mirrorID))479 mirror_ids)).group_by(
480 MirrorDistroArchSeries.distribution_mirrorID))
483 arch_mirror_freshness = {}481 arch_mirror_freshness = {}
484 arch_mirror_freshness.update(482 arch_mirror_freshness.update(
485 [(mirror_id, MirrorFreshness.items[mirror_freshness]) for483 [(mirror_id, MirrorFreshness.items[mirror_freshness]) for
@@ -778,7 +776,7 @@
778 def getCurrentSourceReleases(self, source_package_names):776 def getCurrentSourceReleases(self, source_package_names):
779 """See `IDistribution`."""777 """See `IDistribution`."""
780 return getUtility(IDistributionSet).getCurrentSourceReleases(778 return getUtility(IDistributionSet).getCurrentSourceReleases(
781 {self:source_package_names})779 {self: source_package_names})
782780
783 @property781 @property
784 def has_any_specifications(self):782 def has_any_specifications(self):
@@ -1824,7 +1822,13 @@
1824 assert sourcepackage is not None, (1822 assert sourcepackage is not None, (
1825 "Translations sharing policy requires a SourcePackage.")1823 "Translations sharing policy requires a SourcePackage.")
18261824
1827 if not has_upstream_template(sourcepackage):1825 has_upstream_translations = False
1826 productseries = sourcepackage.productseries
1827 if productseries is not None:
1828 collection = productseries.getTemplatesCollection()
1829 has_upstream_translations = bool(
1830 collection.restrictCurrent().select().any())
1831 if productseries is None or not has_upstream_translations:
1828 # There is no known upstream template or series. Take the1832 # There is no known upstream template or series. Take the
1829 # uploader's word for whether these are upstream translations1833 # uploader's word for whether these are upstream translations
1830 # (in which case they're shared) or not.1834 # (in which case they're shared) or not.
18311835
=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py 2011-01-21 08:12:29 +0000
+++ lib/lp/registry/model/productseries.py 2011-03-23 12:25:33 +0000
@@ -481,6 +481,22 @@
481 # the distroseries to try to find a relevant packaging record481 # the distroseries to try to find a relevant packaging record
482 raise NotFoundError(distroseries)482 raise NotFoundError(distroseries)
483483
484 def getUbuntuTranslationFocusPackage(self):
485 """See `IProductSeries`."""
486 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
487 translation_focus = ubuntu.translation_focus
488 current_series = ubuntu.currentseries
489 candidate = None
490 for package in self.sourcepackages:
491 if package.distroseries == translation_focus:
492 return package
493 if package.distroseries == current_series:
494 candidate = package
495 elif package.distroseries.distribution == ubuntu:
496 if candidate is None:
497 candidate = package
498 return candidate
499
484 def setPackaging(self, distroseries, sourcepackagename, owner):500 def setPackaging(self, distroseries, sourcepackagename, owner):
485 """See IProductSeries."""501 """See IProductSeries."""
486 if distroseries.distribution.full_functionality:502 if distroseries.distribution.full_functionality:
487503
=== modified file 'lib/lp/registry/tests/test_productseries.py'
--- lib/lp/registry/tests/test_productseries.py 2011-03-04 21:15:00 +0000
+++ lib/lp/registry/tests/test_productseries.py 2011-03-23 12:25:33 +0000
@@ -7,6 +7,7 @@
77
8import transaction8import transaction
9from zope.component import getUtility9from zope.component import getUtility
10from zope.security.proxy import removeSecurityProxy
1011
11from canonical.launchpad.ftests import login12from canonical.launchpad.ftests import login
12from canonical.testing.layers import (13from canonical.testing.layers import (
@@ -20,6 +21,7 @@
20 IProductSeries,21 IProductSeries,
21 IProductSeriesSet,22 IProductSeriesSet,
22 )23 )
24from lp.registry.interfaces.series import SeriesStatus
23from lp.testing import (25from lp.testing import (
24 TestCaseWithFactory,26 TestCaseWithFactory,
25 WebServiceTestCase,27 WebServiceTestCase,
@@ -80,6 +82,70 @@
80 self.debian_series, self.sourcepackagename, self.person)82 self.debian_series, self.sourcepackagename, self.person)
8183
8284
85class TestProductSeriesGetUbuntuTranslationFocusPackage(TestCaseWithFactory):
86 """Test for ProductSeries.getUbuntuTranslationFocusPackage."""
87
88 layer = DatabaseFunctionalLayer
89
90 def _makeSourcePackage(self, productseries,
91 series_status=SeriesStatus.EXPERIMENTAL):
92 """Make a sourcepckage that packages the productseries."""
93 distroseries = self.factory.makeUbuntuDistroSeries(
94 status=series_status)
95 packaging = self.factory.makePackagingLink(
96 productseries=productseries, distroseries=distroseries)
97 return packaging.sourcepackage
98
99 def _test_packaged_in_series(
100 self, in_translation_focus, in_current_series, in_other_series):
101 """Test the given combination of packagings."""
102 productseries = self.factory.makeProductSeries()
103 package = None
104 if in_other_series:
105 package = self._makeSourcePackage(productseries)
106 if in_current_series:
107 package = self._makeSourcePackage(
108 productseries, SeriesStatus.FROZEN)
109 if in_translation_focus:
110 package = self._makeSourcePackage(productseries)
111 naked_distribution = removeSecurityProxy(
112 package.distroseries.distribution)
113 naked_distribution.translation_focus = package.distroseries
114 self.assertEqual(
115 package,
116 productseries.getUbuntuTranslationFocusPackage())
117
118 def test_no_sourcepackage(self):
119 self._test_packaged_in_series(
120 in_translation_focus=False,
121 in_current_series=False,
122 in_other_series=False)
123
124 def test_packaged_in_translation_focus(self):
125 # The productseries is packaged in the translation focus series
126 # and others but only the focus is returned.
127 self._test_packaged_in_series(
128 in_translation_focus=True,
129 in_current_series=True,
130 in_other_series=True)
131
132 def test_packaged_in_current_series(self):
133 # The productseries is packaged in the current series and others but
134 # only the current is returned.
135 self._test_packaged_in_series(
136 in_translation_focus=False,
137 in_current_series=True,
138 in_other_series=True)
139
140 def test_packaged_in_other_series(self):
141 # The productseries is not packaged in the translation focus or the
142 # current series, so that packaging is returned.
143 self._test_packaged_in_series(
144 in_translation_focus=False,
145 in_current_series=False,
146 in_other_series=True)
147
148
83class TestProductSeriesDrivers(TestCaseWithFactory):149class TestProductSeriesDrivers(TestCaseWithFactory):
84 """Test the 'drivers' attribute of a ProductSeries."""150 """Test the 'drivers' attribute of a ProductSeries."""
85151
86152
=== modified file 'lib/lp/translations/browser/pofile.py'
--- lib/lp/translations/browser/pofile.py 2011-03-01 20:05:57 +0000
+++ lib/lp/translations/browser/pofile.py 2011-03-23 12:25:33 +0000
@@ -59,12 +59,6 @@
59 ITranslationImportQueue,59 ITranslationImportQueue,
60 )60 )
61from lp.translations.interfaces.translationsperson import ITranslationsPerson61from lp.translations.interfaces.translationsperson import ITranslationsPerson
62from lp.translations.utilities.translationsharinginfo import (
63 has_ubuntu_template,
64 has_upstream_template,
65 get_ubuntu_sharing_info,
66 get_upstream_sharing_info,
67 )
6862
6963
70class POFileNavigation(Navigation):64class POFileNavigation(Navigation):
@@ -999,27 +993,24 @@
999993
1000 def is_sharing(self):994 def is_sharing(self):
1001 if self.is_upstream_pofile:995 if self.is_upstream_pofile:
1002 return has_ubuntu_template(996 productseries = self.context.potemplate.productseries
1003 productseries=self.context.potemplate.productseries,997 other_side_object = (
1004 templatename=self.context.potemplate.name)998 productseries.getUbuntuTranslationFocusPackage())
1005 else:999 else:
1006 return has_upstream_template(1000 sourcepackage = self.context.potemplate.sourcepackage
1007 sourcepackage=self.context.potemplate.sourcepackage,1001 other_side_object = sourcepackage.productseries
1008 templatename=self.context.potemplate.name)1002 if other_side_object is None:
1003 return False
1004 collection = other_side_object.getTemplatesCollection()
1005 name = self.context.potemplate.name
1006 return bool(
1007 collection.restrictCurrent().restrictName(name).select().any())
10091008
1010 @property1009 @property
1011 def sharing_pofile(self):1010 def sharing_pofile(self):
1012 if self.is_upstream_pofile:1011 potemplate = self.context.potemplate.getOtherSidePOTemplate()
1013 infos = get_ubuntu_sharing_info(1012 if potemplate is None:
1014 productseries=self.context.potemplate.productseries,
1015 templatename=self.context.potemplate.name)
1016 else:
1017 infos = get_upstream_sharing_info(
1018 sourcepackage=self.context.potemplate.sourcepackage,
1019 templatename=self.context.potemplate.name)
1020 if len(infos) == 0:
1021 return None1013 return None
1022 obj, potemplate = infos[0]
1023 pofile = potemplate.getPOFileByLang(self.context.language.code)1014 pofile = potemplate.getPOFileByLang(self.context.language.code)
1024 if pofile is None:1015 if pofile is None:
1025 pofile = potemplate.getDummyPOFile(1016 pofile = potemplate.getDummyPOFile(
10261017
=== modified file 'lib/lp/translations/browser/potemplate.py'
--- lib/lp/translations/browser/potemplate.py 2011-03-08 09:59:36 +0000
+++ lib/lp/translations/browser/potemplate.py 2011-03-23 12:25:33 +0000
@@ -87,12 +87,6 @@
87from lp.translations.interfaces.translationimportqueue import (87from lp.translations.interfaces.translationimportqueue import (
88 ITranslationImportQueue,88 ITranslationImportQueue,
89 )89 )
90from lp.translations.utilities.translationsharinginfo import (
91 has_ubuntu_template,
92 get_ubuntu_sharing_info,
93 has_upstream_template,
94 get_upstream_sharing_info,
95 )
9690
9791
98class POTemplateNavigation(Navigation):92class POTemplateNavigation(Navigation):
@@ -353,29 +347,23 @@
353 return self.context.translation_side == TranslationSide.UPSTREAM347 return self.context.translation_side == TranslationSide.UPSTREAM
354348
355 def is_sharing(self):349 def is_sharing(self):
356 if self.is_upstream_template:350 if self.is_upstream_pofile:
357 return has_ubuntu_template(351 productseries = self.context.productseries
358 productseries=self.context.productseries,352 other_side_object = (
359 templatename=self.context.name)353 productseries.getUbuntuTranslationFocusPackage())
360 else:354 else:
361 return has_upstream_template(355 sourcepackage = self.potemplate.sourcepackage
362 sourcepackage=self.context.sourcepackage,356 other_side_object = sourcepackage.productseries
363 templatename=self.context.name)357 if other_side_object is None:
358 return False
359 collection = other_side_object.getTemplatesCollection()
360 name = self.context.name
361 return bool(
362 collection.restrictCurrent().restrictName(name).select().any())
364363
365 @property364 @property
366 def sharing_template(self):365 def sharing_template(self):
367 if self.is_upstream_template:366 return self.context.getOtherSidePOTemplate()
368 infos = get_ubuntu_sharing_info(
369 productseries=self.context.productseries,
370 templatename=self.context.name)
371 else:
372 infos = get_upstream_sharing_info(
373 sourcepackage=self.context.sourcepackage,
374 templatename=self.context.name)
375 if len(infos) == 0:
376 return None
377 obj, template = infos[0]
378 return template
379367
380 def getTranslationTarget(self):368 def getTranslationTarget(self):
381 """See `TranslationSharingDetailsMixin`."""369 """See `TranslationSharingDetailsMixin`."""
382370
=== modified file 'lib/lp/translations/browser/productseries.py'
--- lib/lp/translations/browser/productseries.py 2011-03-16 14:52:37 +0000
+++ lib/lp/translations/browser/productseries.py 2011-03-23 12:25:33 +0000
@@ -65,10 +65,6 @@
65from lp.translations.interfaces.translations import (65from lp.translations.interfaces.translations import (
66 TranslationsBranchImportMode,66 TranslationsBranchImportMode,
67 )67 )
68from lp.translations.utilities.translationsharinginfo import (
69 has_ubuntu_template,
70 get_ubuntu_sharing_info,
71 )
7268
7369
74class ProductSeriesTranslationsMenuMixIn:70class ProductSeriesTranslationsMenuMixIn:
@@ -460,15 +456,15 @@
460 return check_permission("launchpad.TranslationsAdmin", self.context)456 return check_permission("launchpad.TranslationsAdmin", self.context)
461457
462 def is_sharing(self):458 def is_sharing(self):
463 return has_ubuntu_template(productseries=self.context)459 sourcepackage = self.context.getUbuntuTranslationFocusPackage()
460 if sourcepackage is None:
461 return False
462 collection = sourcepackage.getTemplatesCollection().restrictCurrent()
463 return bool(collection.select().any())
464464
465 @property465 @property
466 def sharing_sourcepackage(self):466 def sharing_sourcepackage(self):
467 infos = get_ubuntu_sharing_info(productseries=self.context)467 return self.context.getUbuntuTranslationFocusPackage()
468 if len(infos) == 0:
469 return None
470 sourcepackage, template = infos[0]
471 return sourcepackage
472468
473 def getTranslationTarget(self):469 def getTranslationTarget(self):
474 """See `TranslationSharingDetailsMixin`."""470 """See `TranslationSharingDetailsMixin`."""
475471
=== modified file 'lib/lp/translations/browser/sourcepackage.py'
--- lib/lp/translations/browser/sourcepackage.py 2011-03-16 14:33:28 +0000
+++ lib/lp/translations/browser/sourcepackage.py 2011-03-23 12:25:33 +0000
@@ -34,10 +34,6 @@
34 TranslationsBranchImportMode,34 TranslationsBranchImportMode,
35 )35 )
36from lp.translations.model.translationpackagingjob import TranslationMergeJob36from lp.translations.model.translationpackagingjob import TranslationMergeJob
37from lp.translations.utilities.translationsharinginfo import (
38 has_upstream_template,
39 get_upstream_sharing_info,
40 )
4137
4238
43class SharingDetailsPermissionsMixin:39class SharingDetailsPermissionsMixin:
@@ -59,16 +55,15 @@
59 return "Translations for %s" % self.context.displayname55 return "Translations for %s" % self.context.displayname
6056
61 def is_sharing(self):57 def is_sharing(self):
62 return has_upstream_template(self.context)58 productseries = self.context.productseries
59 if productseries is None:
60 return False
61 collection = productseries.getTemplatesCollection().restrictCurrent()
62 return bool(collection.select().any())
6363
64 @property64 @property
65 def sharing_productseries(self):65 def sharing_productseries(self):
66 infos = get_upstream_sharing_info(self.context)66 return self.context.productseries
67 if len(infos) == 0:
68 return None
69
70 productseries, template = infos[0]
71 return productseries
7267
73 def getTranslationTarget(self):68 def getTranslationTarget(self):
74 """See `TranslationSharingDetailsMixin`."""69 """See `TranslationSharingDetailsMixin`."""
@@ -124,14 +119,18 @@
124119
125 page_title = "Sharing details"120 page_title = "Sharing details"
126121
122 def is_sharing(self):
123 productseries = self.context.productseries
124 if productseries is None:
125 return False
126 collection = productseries.getTemplatesCollection().restrictCurrent()
127 return bool(collection.select().any())
128
127 def initialize(self):129 def initialize(self):
128 if not getFeatureFlag('translations.sharing_information.enabled'):130 if not getFeatureFlag('translations.sharing_information.enabled'):
129 raise NotFound(self.context, '+sharing-details')131 raise NotFound(self.context, '+sharing-details')
130 super(SourcePackageTranslationSharingDetailsView, self).initialize()132 super(SourcePackageTranslationSharingDetailsView, self).initialize()
131 has_no_upstream_templates = (133 if self.is_configuration_complete and not self.is_sharing():
132 self.is_configuration_complete and
133 not has_upstream_template(self.context))
134 if has_no_upstream_templates:
135 self.request.response.addInfoNotification(134 self.request.response.addInfoNotification(
136 structured(135 structured(
137 'No upstream templates have been found yet. Please follow '136 'No upstream templates have been found yet. Please follow '
138137
=== modified file 'lib/lp/translations/interfaces/potemplate.py'
--- lib/lp/translations/interfaces/potemplate.py 2011-03-01 17:40:06 +0000
+++ lib/lp/translations/interfaces/potemplate.py 2011-03-23 12:25:33 +0000
@@ -415,6 +415,11 @@
415 Return None if there is no such POFile.415 Return None if there is no such POFile.
416 """416 """
417417
418 def getOtherSidePOTemplate():
419 """Get the POTemplate with the same name on the other side of a
420 packaging link.
421 """
422
418 def hasPluralMessage():423 def hasPluralMessage():
419 """Test whether this template has any message sets which are plural424 """Test whether this template has any message sets which are plural
420 message sets."""425 message sets."""
421426
=== modified file 'lib/lp/translations/model/pofile.py'
--- lib/lp/translations/model/pofile.py 2011-02-23 16:56:01 +0000
+++ lib/lp/translations/model/pofile.py 2011-03-23 12:25:33 +0000
@@ -66,7 +66,6 @@
66 MASTER_FLAVOR,66 MASTER_FLAVOR,
67 )67 )
68from canonical.launchpad.webapp.publisher import canonical_url68from canonical.launchpad.webapp.publisher import canonical_url
69from lp.app.errors import NotFoundError
70from lp.registry.interfaces.person import validate_public_person69from lp.registry.interfaces.person import validate_public_person
71from lp.services.propertycache import cachedproperty70from lp.services.propertycache import cachedproperty
72from lp.translations.enums import RosettaImportStatus71from lp.translations.enums import RosettaImportStatus
@@ -74,7 +73,6 @@
74 IPOFile,73 IPOFile,
75 IPOFileSet,74 IPOFileSet,
76 )75 )
77from lp.translations.interfaces.potemplate import IPOTemplateSet
78from lp.translations.interfaces.potmsgset import TranslationCreditsType76from lp.translations.interfaces.potmsgset import TranslationCreditsType
79from lp.translations.interfaces.side import (77from lp.translations.interfaces.side import (
80 ITranslationSideTraitsSet,78 ITranslationSideTraitsSet,
@@ -401,30 +399,7 @@
401399
402 def getOtherSidePOFile(self):400 def getOtherSidePOFile(self):
403 """See `IPOFile`."""401 """See `IPOFile`."""
404 potemplateset = getUtility(IPOTemplateSet)402 other_potemplate = self.potemplate.getOtherSidePOTemplate()
405 if self.potemplate.translation_side == TranslationSide.UBUNTU:
406 from lp.registry.model.sourcepackage import SourcePackage
407 productseries = SourcePackage(
408 self.potemplate.sourcepackagename,
409 self.potemplate.distroseries).productseries
410 if productseries is None:
411 return None
412 subset = potemplateset.getSubset(productseries=productseries)
413 else:
414 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
415 distroseries = ubuntu.translation_focus
416 if distroseries is None:
417 distroseries = ubuntu.currentseries
418 try:
419 sourcepackage = self.potemplate.productseries.getPackage(
420 distroseries)
421 except NotFoundError:
422 return None
423 subset = potemplateset.getSubset(
424 distroseries=distroseries,
425 sourcepackagename=sourcepackage.sourcepackagename)
426
427 other_potemplate = subset.getPOTemplateByName(self.potemplate.name)
428 if other_potemplate is None:403 if other_potemplate is None:
429 return None404 return None
430 return other_potemplate.getPOFileByLang(self.language.code)405 return other_potemplate.getPOFileByLang(self.language.code)
431406
=== modified file 'lib/lp/translations/model/potemplate.py'
--- lib/lp/translations/model/potemplate.py 2011-03-01 17:40:06 +0000
+++ lib/lp/translations/model/potemplate.py 2011-03-23 12:25:33 +0000
@@ -541,6 +541,19 @@
541541
542 return self._cached_pofiles_by_language[language_code]542 return self._cached_pofiles_by_language[language_code]
543543
544 def getOtherSidePOTemplate(self):
545 """See `IPOTemplate`."""
546 if self.translation_side == TranslationSide.UBUNTU:
547 other_side_object = self.sourcepackage.productseries
548 else:
549 other_side_object = (
550 self.productseries.getUbuntuTranslationFocusPackage())
551 if other_side_object is None:
552 return None
553 collection = (
554 other_side_object.getTemplatesCollection().restrictCurrent())
555 return collection.restrictName(self.name).select().one()
556
544 def messageCount(self):557 def messageCount(self):
545 """See `IRosettaStats`."""558 """See `IRosettaStats`."""
546 return self.messagecount559 return self.messagecount
@@ -1684,6 +1697,15 @@
1684 """1697 """
1685 return self.refine(POTemplate.iscurrent == current_value)1698 return self.refine(POTemplate.iscurrent == current_value)
16861699
1700 def restrictName(self, template_name):
1701 """Select based on `POTemplate.name`.
1702
1703 :param template: The value for `name` that you are looking for.
1704 :return: A `TranslationTemplatesCollection based on this one but
1705 restricted to ones with the desired `name` value.
1706 """
1707 return self.refine(POTemplate.name == template_name)
1708
1687 def joinPOFile(self):1709 def joinPOFile(self):
1688 """Join `POFile` into the collection.1710 """Join `POFile` into the collection.
16891711
16901712
=== modified file 'lib/lp/translations/tests/test_potemplate.py'
--- lib/lp/translations/tests/test_potemplate.py 2011-02-10 15:08:52 +0000
+++ lib/lp/translations/tests/test_potemplate.py 2011-03-23 12:25:33 +0000
@@ -8,7 +8,10 @@
8from zope.component import getUtility8from zope.component import getUtility
9from zope.security.proxy import removeSecurityProxy9from zope.security.proxy import removeSecurityProxy
1010
11from canonical.testing.layers import DatabaseFunctionalLayer11from canonical.testing.layers import (
12 DatabaseFunctionalLayer,
13 ZopelessDatabaseLayer,
14 )
12from lp.app.enums import ServiceUsage15from lp.app.enums import ServiceUsage
13from lp.registry.interfaces.distribution import IDistributionSet16from lp.registry.interfaces.distribution import IDistributionSet
14from lp.services.worlddata.interfaces.language import ILanguageSet17from lp.services.worlddata.interfaces.language import ILanguageSet
@@ -22,7 +25,6 @@
22 )25 )
23from lp.translations.model.potemplate import (26from lp.translations.model.potemplate import (
24 get_pofiles_for,27 get_pofiles_for,
25 POTemplate,
26 )28 )
2729
2830
@@ -595,3 +597,85 @@
595 pofiles = get_pofiles_for([self.potemplate], self.greek)597 pofiles = get_pofiles_for([self.potemplate], self.greek)
596 pofile = pofiles[0]598 pofile = pofiles[0]
597 self.assertIsInstance(pofile, DummyPOFile)599 self.assertIsInstance(pofile, DummyPOFile)
600
601
602class TestPOTemplateUbuntuUpstreamSharingMixin:
603 """Test sharing between Ubuntu und upstream POTemplates."""
604
605 layer = ZopelessDatabaseLayer
606
607 def createData(self):
608 self.shared_template_name = self.factory.getUniqueString()
609 self.distroseries = self.factory.makeUbuntuDistroSeries()
610 self.distroseries.distribution.translation_focus = (
611 self.distroseries)
612 self.sourcepackage = self.factory.makeSourcePackage(
613 distroseries=self.distroseries)
614 self.productseries = self.factory.makeProductSeries()
615
616 def makeThisSidePOTemplate(self):
617 """Create POTemplate on this side."""
618 raise NotImplementedError
619
620 def makeOtherSidePOTemplate(self):
621 """Create POTemplate on the other side. Override in subclass."""
622 raise NotImplementedError
623
624 def _setPackagingLink(self):
625 """Create the packaging link from source package to product series."""
626 self.factory.makePackagingLink(
627 productseries=self.productseries,
628 sourcepackage=self.sourcepackage)
629
630 def test_getOtherSidePOTemplate_none(self):
631 # Without a packaging link, None is returned.
632 potemplate = self.makeThisSidePOTemplate()
633 self.assertIs(None, potemplate.getOtherSidePOTemplate())
634
635 def test_getOtherSidePOTemplate_linked_no_template(self):
636 # No sharing template exists on the other side.
637 self._setPackagingLink()
638 potemplate = self.makeThisSidePOTemplate()
639 self.assertIs(None, potemplate.getOtherSidePOTemplate())
640
641 def test_getOtherSidePOTemplate_shared(self):
642 # This is how sharing should look like.
643 this_potemplate = self.makeThisSidePOTemplate()
644 other_potemplate = self.makeOtherSidePOTemplate()
645 self._setPackagingLink()
646 self.assertEquals(
647 other_potemplate, this_potemplate.getOtherSidePOTemplate())
648
649
650class TestPOTemplateUbuntuSharing(TestCaseWithFactory,
651 TestPOTemplateUbuntuUpstreamSharingMixin):
652 """Test sharing on Ubuntu side."""
653
654 def setUp(self):
655 super(TestPOTemplateUbuntuSharing, self).setUp()
656 self.createData()
657
658 def makeThisSidePOTemplate(self):
659 return self.factory.makePOTemplate(
660 sourcepackage=self.sourcepackage, name=self.shared_template_name)
661
662 def makeOtherSidePOTemplate(self):
663 return self.factory.makePOTemplate(
664 productseries=self.productseries, name=self.shared_template_name)
665
666
667class TestPOTemplateUpstreamSharing(TestCaseWithFactory,
668 TestPOTemplateUbuntuUpstreamSharingMixin):
669 """Test sharing on upstream side."""
670
671 def setUp(self):
672 super(TestPOTemplateUpstreamSharing, self).setUp()
673 self.createData()
674
675 def makeThisSidePOTemplate(self):
676 return self.factory.makePOTemplate(
677 productseries=self.productseries, name=self.shared_template_name)
678
679 def makeOtherSidePOTemplate(self):
680 return self.factory.makePOTemplate(
681 sourcepackage=self.sourcepackage, name=self.shared_template_name)
598682
=== modified file 'lib/lp/translations/tests/test_translationtemplatescollection.py'
--- lib/lp/translations/tests/test_translationtemplatescollection.py 2010-10-04 19:50:45 +0000
+++ lib/lp/translations/tests/test_translationtemplatescollection.py 2011-03-23 12:25:33 +0000
@@ -171,6 +171,19 @@
171 self.assertContentEqual(171 self.assertContentEqual(
172 [template], obsolete_templates.select())172 [template], obsolete_templates.select())
173173
174 def test_restrictName(self):
175 trunk = self.factory.makeProduct().getSeries('trunk')
176 template = self.factory.makePOTemplate(productseries=trunk)
177 template_name = template.name
178 # Other template that will not be returned.
179 self.factory.makePOTemplate(productseries=trunk)
180 collection = TranslationTemplatesCollection()
181 by_series = collection.restrictProductSeries(trunk)
182
183 same_name_templates = by_series.restrictName(template_name)
184 self.assertContentEqual(
185 [template], same_name_templates.select())
186
174 def test_joinPOFile(self):187 def test_joinPOFile(self):
175 trunk = self.factory.makeProduct().getSeries('trunk')188 trunk = self.factory.makeProduct().getSeries('trunk')
176 translated_template = self.factory.makePOTemplate(productseries=trunk)189 translated_template = self.factory.makePOTemplate(productseries=trunk)
177190
=== removed file 'lib/lp/translations/utilities/tests/test_translation_sharing_info.py'
--- lib/lp/translations/utilities/tests/test_translation_sharing_info.py 2011-02-23 12:16:59 +0000
+++ lib/lp/translations/utilities/tests/test_translation_sharing_info.py 1970-01-01 00:00:00 +0000
@@ -1,308 +0,0 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4__metaclass__ = type
5
6from canonical.testing.layers import ZopelessDatabaseLayer
7from lp.testing import TestCaseWithFactory
8from lp.translations.utilities.translationsharinginfo import (
9 get_ubuntu_sharing_info,
10 get_upstream_sharing_info,
11 has_ubuntu_template,
12 has_upstream_template,
13 )
14
15
16class TestTranslationSharingInfo(TestCaseWithFactory):
17 """Tests for `get_upstream_sharing_info` and `get_ubuntu_sharing_info`"""
18
19 layer = ZopelessDatabaseLayer
20
21 def _makeSourcePackage(self):
22 """Create an Ubuntu source package."""
23 distroseries = self.factory.makeUbuntuDistroSeries()
24 return self.factory.makeSourcePackage(distroseries=distroseries)
25
26 def _makeUpstreamProductSeries(self, sourcepackage):
27 """Create a product series and link it to the source package."""
28 productseries = self.factory.makeProductSeries()
29 self.factory.makePackagingLink(
30 distroseries=sourcepackage.distroseries,
31 sourcepackagename=sourcepackage.sourcepackagename,
32 productseries=productseries)
33 return productseries
34
35 def test_no_upstream(self):
36 # With no upstream the sharing information on a source package will
37 # be empty.
38 sourcepackage = self._makeSourcePackage()
39 self.assertEquals(
40 [],
41 get_upstream_sharing_info(sourcepackage=sourcepackage))
42
43 def test_no_upstream_with_name(self):
44 # With no upstream the sharing information on a source package will
45 # be empty, even when searching for a specific template name.
46 sourcepackage = self._makeSourcePackage()
47 templatename = self.factory.getUniqueString()
48 self.assertEquals(
49 [],
50 get_upstream_sharing_info(
51 sourcepackage=sourcepackage,
52 templatename=templatename))
53
54 def test_upstream_no_template(self):
55 # With an upstream without a template the sharing information on a
56 # source package will be empty.
57 sourcepackage = self._makeSourcePackage()
58 productseries = self._makeUpstreamProductSeries(sourcepackage)
59 self.assertEquals(
60 [(productseries, None)],
61 get_upstream_sharing_info(sourcepackage=sourcepackage))
62
63 def test_upstream_no_template_with_name(self):
64 # With an upstream without a template the sharing information on a
65 # source package will be empty, even when searching for a specific
66 # template name.
67 sourcepackage = self._makeSourcePackage()
68 productseries = self._makeUpstreamProductSeries(sourcepackage)
69 templatename = self.factory.getUniqueString()
70 self.assertEquals(
71 [(productseries, None)],
72 get_upstream_sharing_info(
73 sourcepackage=sourcepackage,
74 templatename=templatename))
75
76 def test_upstream_one_template(self):
77 # With an upstream template the sharing information on a
78 # source package will return that.
79 sourcepackage = self._makeSourcePackage()
80 productseries = self._makeUpstreamProductSeries(sourcepackage)
81 potemplate = self.factory.makePOTemplate(productseries=productseries)
82 self.assertEquals(
83 [(productseries, potemplate)],
84 get_upstream_sharing_info(sourcepackage=sourcepackage))
85
86 def test_upstream_one_template_with_name(self):
87 # With an upstream template the sharing information on a
88 # source package will return that, even when searching for a
89 # specific template name.
90 sourcepackage = self._makeSourcePackage()
91 productseries = self._makeUpstreamProductSeries(sourcepackage)
92 templatename = self.factory.getUniqueString()
93 potemplate = self.factory.makePOTemplate(
94 productseries=productseries, name=templatename)
95 self.assertEquals(
96 [(productseries, potemplate)],
97 get_upstream_sharing_info(
98 sourcepackage=sourcepackage,
99 templatename=templatename))
100
101 def test_upstream_one_template_with_different_name(self):
102 # With an upstream template the sharing information on a
103 # source package will be empty if a different name is queried.
104 sourcepackage = self._makeSourcePackage()
105 productseries = self._makeUpstreamProductSeries(sourcepackage)
106 templatename = self.factory.getUniqueString()
107 self.factory.makePOTemplate(
108 productseries=productseries, name=templatename)
109 different_templatename = self.factory.getUniqueString()
110 self.assertEquals(
111 [(productseries, None)],
112 get_upstream_sharing_info(
113 sourcepackage=sourcepackage,
114 templatename=different_templatename))
115
116 def test_no_ubuntu(self):
117 # With no sourcepackage the sharing information on a source package
118 # will be empty.
119 productseries = self.factory.makeProductSeries()
120 self.assertContentEqual(
121 [],
122 get_ubuntu_sharing_info(productseries=productseries))
123
124 def test_no_ubuntu_with_name(self):
125 # With no sourcepackage the sharing information on a source package
126 # will be empty, even when searching for a specific template name.
127 productseries = self.factory.makeProductSeries()
128 templatename = self.factory.getUniqueString()
129 self.assertContentEqual(
130 [],
131 get_ubuntu_sharing_info(
132 productseries=productseries, templatename=templatename))
133
134 def test_ubuntu_no_template(self):
135 # With a sourcepackage without a template the sharing information
136 # on a productseries will be empty.
137 sourcepackage = self._makeSourcePackage()
138 productseries = self._makeUpstreamProductSeries(sourcepackage)
139 self.assertContentEqual(
140 [(sourcepackage, None)],
141 get_ubuntu_sharing_info(productseries=productseries))
142
143 def test_ubuntu_no_template_with_name(self):
144 # With a sourcepackage without a template the sharing information
145 # on a productseries will be empty, even when searching for a
146 # specific template name.
147 sourcepackage = self._makeSourcePackage()
148 productseries = self._makeUpstreamProductSeries(sourcepackage)
149 templatename = self.factory.getUniqueString()
150 self.assertContentEqual(
151 [(sourcepackage, None)],
152 get_ubuntu_sharing_info(
153 productseries=productseries, templatename=templatename))
154
155 def test_ubuntu_one_template(self):
156 # With a sourcepackage template the sharing information on a
157 # source package will return that.
158 sourcepackage = self._makeSourcePackage()
159 productseries = self._makeUpstreamProductSeries(sourcepackage)
160 potemplate = self.factory.makePOTemplate(sourcepackage=sourcepackage)
161 self.assertContentEqual(
162 [(sourcepackage, potemplate)],
163 get_ubuntu_sharing_info(
164 productseries=productseries))
165
166 def test_ubuntu_one_template_with_name(self):
167 # With a sourcepackage template the sharing information on a
168 # productseries will return that, even when searching for a
169 # specific template name.
170 sourcepackage = self._makeSourcePackage()
171 productseries = self._makeUpstreamProductSeries(sourcepackage)
172 templatename = self.factory.getUniqueString()
173 potemplate = self.factory.makePOTemplate(
174 sourcepackage=sourcepackage,
175 name=templatename)
176 self.assertContentEqual(
177 [(sourcepackage, potemplate)],
178 get_ubuntu_sharing_info(
179 productseries=productseries, templatename=templatename))
180
181 def test_ubuntu_one_template_with_different_name(self):
182 # With a sourcepackage template the sharing information on a
183 # productseries will be empty if a different name is queried.
184 sourcepackage = self._makeSourcePackage()
185 productseries = self._makeUpstreamProductSeries(sourcepackage)
186 templatename = self.factory.getUniqueString()
187 self.factory.makePOTemplate(
188 sourcepackage=sourcepackage,
189 name=templatename)
190 different_templatename = self.factory.getUniqueString()
191 self.assertContentEqual(
192 [(sourcepackage, None)],
193 get_ubuntu_sharing_info(
194 productseries=productseries,
195 templatename=different_templatename))
196
197 def test_has_upstream_template_no_productseries(self):
198 # Without an upstream project, no upstream templates won't be
199 # available either.
200 sourcepackage = self._makeSourcePackage()
201 templatename = self.factory.getUniqueString()
202
203 self.assertFalse(
204 has_upstream_template(sourcepackage, templatename))
205
206 def test_has_upstream_template_no_template(self):
207 # No template exists on the upstream project.
208 sourcepackage = self._makeSourcePackage()
209 productseries = self._makeUpstreamProductSeries(sourcepackage)
210 templatename = self.factory.getUniqueString()
211
212 self.assertFalse(
213 has_upstream_template(sourcepackage, templatename))
214
215 def test_has_upstream_template_one_template(self):
216 # There is one template on the upstream project that matches the
217 # name.
218 sourcepackage = self._makeSourcePackage()
219 productseries = self._makeUpstreamProductSeries(sourcepackage)
220 templatename = self.factory.getUniqueString()
221 self.factory.makePOTemplate(
222 productseries=productseries, name=templatename)
223
224 self.assertTrue(
225 has_upstream_template(sourcepackage, templatename))
226
227 def test_has_upstream_template_one_template_wrong_name(self):
228 # There is one template on the upstream project but it matches not
229 # the requested name.
230 sourcepackage = self._makeSourcePackage()
231 productseries = self._makeUpstreamProductSeries(sourcepackage)
232 self.factory.makePOTemplate(productseries=productseries)
233 different_templatename = self.factory.getUniqueString()
234
235 self.assertFalse(
236 has_upstream_template(sourcepackage, different_templatename))
237
238 def test_has_upstream_template_any_template(self):
239 # There is one template on the upstream project, not specifying
240 # a template name still indicates that there is a template.
241 sourcepackage = self._makeSourcePackage()
242 productseries = self._makeUpstreamProductSeries(sourcepackage)
243 self.factory.makePOTemplate(productseries=productseries)
244
245 self.assertTrue(has_upstream_template(sourcepackage))
246
247 def test_has_upstream_template_any_template_none(self):
248 # There is no template on the upstream project.
249 sourcepackage = self._makeSourcePackage()
250 self._makeUpstreamProductSeries(sourcepackage)
251
252 self.assertFalse(has_upstream_template(sourcepackage))
253
254 def test_has_ubuntu_template_no_sourcepackage(self):
255 # There is no Ubuntu source package, so no Ubuntu template can be
256 # found.
257 productseries = self.factory.makeProductSeries()
258 templatename = self.factory.getUniqueString()
259
260 self.assertFalse(has_ubuntu_template(productseries, templatename))
261
262 def test_has_ubuntu_template_no_template(self):
263 # The Ubuntu source package has no template.
264 sourcepackage = self._makeSourcePackage()
265 productseries = self._makeUpstreamProductSeries(sourcepackage)
266 templatename = self.factory.getUniqueString()
267
268 self.assertFalse(has_ubuntu_template(productseries, templatename))
269
270 def test_has_ubuntu_template_one_template(self):
271 # There is one template on the Ubuntu source package that matches
272 # the name.
273 sourcepackage = self._makeSourcePackage()
274 productseries = self._makeUpstreamProductSeries(sourcepackage)
275 templatename = self.factory.getUniqueString()
276 self.factory.makePOTemplate(
277 sourcepackage=sourcepackage, name=templatename)
278
279 self.assertTrue(has_ubuntu_template(productseries, templatename))
280
281 def test_has_ubuntu_template_one_template_wrong_name(self):
282 # There is one template on the Ubuntu source package but it matches
283 # not the requested name.
284 sourcepackage = self._makeSourcePackage()
285 productseries = self._makeUpstreamProductSeries(sourcepackage)
286 templatename = self.factory.getUniqueString()
287 self.factory.makePOTemplate(
288 sourcepackage=sourcepackage, name=templatename)
289 different_templatename = self.factory.getUniqueString()
290
291 self.assertFalse(
292 has_ubuntu_template(productseries, different_templatename))
293
294 def test_has_ubuntu_template_any_template(self):
295 # There is one template on the Ubuntu source package, not specifying
296 # a template name still indicates that there is a template.
297 sourcepackage= self._makeSourcePackage()
298 productseries = self._makeUpstreamProductSeries(sourcepackage)
299 self.factory.makePOTemplate(sourcepackage=sourcepackage)
300
301 self.assertTrue(has_ubuntu_template(productseries))
302
303 def test_has_ubuntu_template_any_template_none(self):
304 # There is no template on the Ubuntu source package.
305 sourcepackage = self._makeSourcePackage()
306 productseries = self._makeUpstreamProductSeries(sourcepackage)
307
308 self.assertFalse(has_ubuntu_template(productseries))
3090
=== modified file 'lib/lp/translations/utilities/translation_import.py'
--- lib/lp/translations/utilities/translation_import.py 2011-02-23 12:02:36 +0000
+++ lib/lp/translations/utilities/translation_import.py 2011-03-23 12:25:33 +0000
@@ -444,9 +444,11 @@
444 sourcepackage = getUtility(ISourcePackageFactory).new(444 sourcepackage = getUtility(ISourcePackageFactory).new(
445 self.translation_import_queue_entry.sourcepackagename,445 self.translation_import_queue_entry.sourcepackagename,
446 self.translation_import_queue_entry.distroseries)446 self.translation_import_queue_entry.distroseries)
447 from lp.translations.utilities.translationsharinginfo import (447 productseries = sourcepackage.productseries
448 has_upstream_template)448 if productseries is None:
449 return not has_upstream_template(sourcepackage)449 return True
450 collection = productseries.getTemplatesCollection().restrictCurrent()
451 return not bool(collection.select().any())
450452
451 @cachedproperty453 @cachedproperty
452 def translations_are_msgids(self):454 def translations_are_msgids(self):
453455
=== removed file 'lib/lp/translations/utilities/translationsharinginfo.py'
--- lib/lp/translations/utilities/translationsharinginfo.py 2011-02-24 17:33:35 +0000
+++ lib/lp/translations/utilities/translationsharinginfo.py 1970-01-01 00:00:00 +0000
@@ -1,177 +0,0 @@
1# Copyright 2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Provide sharing information.
5
6This module defines two different types of functions that provide
7information about what sharing options are available on the other side of a
8packaging link. Since they perform similar but slightly different complex
9database queries combining them in any way will usually be wrong.
10
11get_ubuntu_sharing_info and get_upstream_sharing_info will give you
12information about the source package or productseries respectively,
13combined with possibly available templates. You can restrict the search
14by specifying a template name.
15
16has_ubuntu_template and has_upstream_template make a direct search for a
17template of the given name on the other side. They do not search for
18source package or productseries but will only return True if an actual
19template exists. That is a significant difference to the get_* functions.
20"""
21
22__metaclass__ = type
23__all__ = [
24 'get_ubuntu_sharing_info',
25 'get_upstream_sharing_info',
26 'has_ubuntu_template',
27 'has_upstream_template',
28 ]
29
30from storm.expr import (\
31 And,
32 Join,
33 LeftJoin,
34 )
35
36from canonical.launchpad.interfaces.lpstorm import IStore
37from lp.registry.model.distroseries import DistroSeries
38from lp.registry.model.packaging import Packaging
39from lp.registry.model.productseries import ProductSeries
40from lp.registry.model.sourcepackage import SourcePackage
41from lp.registry.model.sourcepackagename import SourcePackageName
42from lp.translations.model.potemplate import POTemplate
43
44
45def find_ubuntu_sharing_info(productseries, templatename=None,
46 template_only=False):
47 """Return a `ResultSet` of sharing information for this productseries.
48
49 Target is either a productseries or a source package.
50 :param productseries: The target productseries or None.
51 :param templatename: The name of the template to find information for or
52 None to get information about any sharing template in any series.
53 :param template_only: Return only `POTemplate` instances.
54 :returns: A result set of ('Distroseries', SourcePackageName, POTemplate)
55 tuples.
56 """
57
58 # SELECT *
59 # FROM Packaging
60 # JOIN Distroseries
61 # ON Packaging.distroseries = Distroseries.id
62 # JOIN SourcePackageName
63 # ON Packaging.sourcepackagename = SourcePackageName.id
64 # LEFT JOIN POTemplate
65 # ON Packaging.distroseries = POTemplate.distroseries AND
66 # Packaging.sourcepackagename = POTemplate.sourcepackagename AND
67 # POTemplate.name = templatename
68 # WHERE Packaging.productseries = productseries
69 #
70 if templatename is None:
71 potemplate_condition = And(
72 Packaging.distroseriesID == POTemplate.distroseriesID,
73 Packaging.sourcepackagenameID == POTemplate.sourcepackagenameID)
74 else:
75 potemplate_condition = And(
76 Packaging.distroseriesID == POTemplate.distroseriesID,
77 Packaging.sourcepackagenameID ==
78 POTemplate.sourcepackagenameID,
79 POTemplate.name == templatename)
80 if template_only:
81 prejoin = Join(
82 Packaging,
83 POTemplate,
84 potemplate_condition)
85 result_classes = POTemplate
86 else:
87 prejoin = LeftJoin(
88 Join(
89 Join(
90 Packaging, DistroSeries,
91 Packaging.distroseriesID == DistroSeries.id),
92 SourcePackageName,
93 Packaging.sourcepackagenameID == SourcePackageName.id),
94 POTemplate,
95 potemplate_condition)
96 result_classes = (DistroSeries, SourcePackageName, POTemplate)
97 conditions = [
98 Packaging.productseries == productseries,
99 ]
100 return IStore(Packaging).using(prejoin).find(
101 result_classes, *conditions)
102
103
104def find_upstream_sharing_info(sourcepackage,
105 templatename=None, template_only=False):
106 """Return a `ResultSet` of sharing information for this sourcepackage.
107
108 :param distroseries: The target distroseries or None.
109 :param sourcepackagename: The target sourcepackagename or None.
110 :param templatename: The name of the template to find information for or
111 None to get information about any sharing template in any series.
112 :param template_only: Return only `POTemplate` instances.
113 :returns: A ResultSet of (ProductSeries, POTemplate) tuples.
114 """
115 # SELECT *
116 # FROM Packaging
117 # JOIN ProductSeries
118 # ON Packaging.productseries = Productseris.id
119 # LEFT JOIN POTemplate
120 # ON Packaging.productseries = POTemplate.productseries AND
121 # POTemplate.name = templatename
122 # WHERE Packaging.distroseries = distroseries AND
123 # Packaging.sourcepackagename = sourcepackagename
124 #
125 if templatename is None:
126 potemplate_condition = (
127 Packaging.productseriesID == POTemplate.productseriesID)
128 else:
129 potemplate_condition = And(
130 Packaging.productseriesID == POTemplate.productseriesID,
131 POTemplate.name == templatename)
132 if template_only:
133 prejoin = Join(
134 Packaging, POTemplate, potemplate_condition)
135 result_classes = POTemplate
136 else:
137 prejoin = LeftJoin(
138 Join(
139 Packaging, ProductSeries,
140 Packaging.productseriesID == ProductSeries.id),
141 POTemplate,
142 potemplate_condition)
143 result_classes = (ProductSeries, POTemplate)
144 conditions = [
145 Packaging.distroseries == sourcepackage.distroseries,
146 Packaging.sourcepackagename == sourcepackage.sourcepackagename,
147 ]
148
149 return IStore(Packaging).using(prejoin).find(
150 result_classes, *conditions)
151
152
153def get_ubuntu_sharing_info(productseries, templatename=None):
154 """Return a list of sharing information for the given target."""
155 return [
156 (SourcePackage(packagename, series), name)
157 for series, packagename, name in find_ubuntu_sharing_info(
158 productseries, templatename)]
159
160
161def get_upstream_sharing_info(sourcepackage, templatename=None):
162 """Return a list of sharing information for the given target."""
163 return list(find_upstream_sharing_info(sourcepackage, templatename))
164
165
166def has_ubuntu_template(productseries, templatename=None):
167 """Check for existence of ubuntu template."""
168 result = find_ubuntu_sharing_info(
169 productseries, templatename, template_only=True)
170 return not result.is_empty()
171
172
173def has_upstream_template(sourcepackage, templatename=None):
174 """Check for existence of upstream template."""
175 result = find_upstream_sharing_info(
176 sourcepackage, templatename, template_only=True)
177 return not result.is_empty()