Merge lp:~edwin-grubbs/launchpad/bug-577492-needspackaging-duplicates into lp:launchpad
- bug-577492-needspackaging-duplicates
- Merge into devel
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Jelmer Vernooij | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | 11248 | ||||||||
Proposed branch: | lp:~edwin-grubbs/launchpad/bug-577492-needspackaging-duplicates | ||||||||
Merge into: | lp:launchpad | ||||||||
Diff against target: |
1009 lines (+386/-327) 8 files modified
lib/lp/registry/browser/distroseries.py (+3/-6) lib/lp/registry/browser/tests/test_distroseries_views.py (+52/-0) lib/lp/registry/doc/distroseries.txt (+286/-284) lib/lp/registry/interfaces/distroseries.py (+5/-4) lib/lp/registry/model/distroseries.py (+25/-23) lib/lp/registry/stories/distroseries/xx-distroseries-index.txt (+6/-1) lib/lp/registry/templates/distroseries-portlet-packaging.pt (+1/-1) lib/lp/registry/tests/test_distroseries.py (+8/-8) |
||||||||
To merge this branch: | bzr merge lp:~edwin-grubbs/launchpad/bug-577492-needspackaging-duplicates | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij (community) | code | Approve | |
Review via email: mp+31112@code.launchpad.net |
Commit message
Description of the change
Summary
-------
Sped up +needs-packaging page and the needs-packaging portlet on the
distroseries +index page by making getPrioritizedU
return a result set, so that batching will result in a limited query.
Previously, the result set was turned into a list in order to format
each item as a dictionary. Therefore, it would load 13,000 source
packages, and then iterate just over the first batch.
I also fixed the name of getPrioritizedP
return a result set instead of a list.
Tests
-----
./bin/test -vv -t 'test_distroser
Demo and Q/A
------------
* Open https:/
* It should not timeout.
* Open https:/
* The "Upstream packaging" portlet should say
"Needs more information or linking to upstream" and list some source
packages.
Lint
----
There are over 700 lint errors due to bad indentation in doctests, so I
will add those changes later, so that reviewers aren't scared away.
Preview Diff
1 | === modified file 'lib/lp/registry/browser/distroseries.py' | |||
2 | --- lib/lp/registry/browser/distroseries.py 2010-05-24 22:04:19 +0000 | |||
3 | +++ lib/lp/registry/browser/distroseries.py 2010-07-28 19:11:08 +0000 | |||
4 | @@ -180,7 +180,6 @@ | |||
5 | 180 | 180 | ||
6 | 181 | # A search link isn't needed because the distro series overview | 181 | # A search link isn't needed because the distro series overview |
7 | 182 | # has a search form. | 182 | # has a search form. |
8 | 183 | |||
9 | 184 | def answers(self): | 183 | def answers(self): |
10 | 185 | text = 'Ask a question' | 184 | text = 'Ask a question' |
11 | 186 | url = canonical_url(self.context.distribution) + '/+addquestion' | 185 | url = canonical_url(self.context.distribution) + '/+addquestion' |
12 | @@ -332,10 +331,8 @@ | |||
13 | 332 | 331 | ||
14 | 333 | @cachedproperty | 332 | @cachedproperty |
15 | 334 | def needs_linking(self): | 333 | def needs_linking(self): |
20 | 335 | """Return a list of 10 packages most in need of upstream linking.""" | 334 | """Return a list of 10 packages most in need of upstream linking.""" |
21 | 336 | # XXX sinzui 2010-02-26 bug=528648: This method causes a timeout. | 335 | return self.context.getPrioritizedUnlinkedSourcePackages()[:10] |
18 | 337 | # return self.context.getPrioritizedUnlinkedSourcePackages()[:10] | ||
19 | 338 | return None | ||
22 | 339 | 336 | ||
23 | 340 | milestone_can_release = False | 337 | milestone_can_release = False |
24 | 341 | 338 | ||
25 | @@ -481,7 +478,7 @@ | |||
26 | 481 | @cachedproperty | 478 | @cachedproperty |
27 | 482 | def cached_packagings(self): | 479 | def cached_packagings(self): |
28 | 483 | """The batched upstream packaging links.""" | 480 | """The batched upstream packaging links.""" |
30 | 484 | packagings = self.context.getPrioritizedlPackagings() | 481 | packagings = self.context.getPrioritizedPackagings() |
31 | 485 | navigator = BatchNavigator(packagings, self.request, size=20) | 482 | navigator = BatchNavigator(packagings, self.request, size=20) |
32 | 486 | navigator.setHeadings('packaging', 'packagings') | 483 | navigator.setHeadings('packaging', 'packagings') |
33 | 487 | return navigator | 484 | return navigator |
34 | 488 | 485 | ||
35 | === added file 'lib/lp/registry/browser/tests/test_distroseries_views.py' | |||
36 | --- lib/lp/registry/browser/tests/test_distroseries_views.py 1970-01-01 00:00:00 +0000 | |||
37 | +++ lib/lp/registry/browser/tests/test_distroseries_views.py 2010-07-28 19:11:08 +0000 | |||
38 | @@ -0,0 +1,52 @@ | |||
39 | 1 | # Copyright 2010 Canonical Ltd. This software is licensed under the | ||
40 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
41 | 3 | |||
42 | 4 | __metaclass__ = type | ||
43 | 5 | |||
44 | 6 | import unittest | ||
45 | 7 | |||
46 | 8 | from storm.zope.interfaces import IResultSet | ||
47 | 9 | |||
48 | 10 | from zope.component import getUtility | ||
49 | 11 | from zope.security.proxy import removeSecurityProxy | ||
50 | 12 | |||
51 | 13 | from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities | ||
52 | 14 | from canonical.testing import LaunchpadZopelessLayer | ||
53 | 15 | from lp.testing import TestCaseWithFactory | ||
54 | 16 | from lp.testing.views import create_initialized_view | ||
55 | 17 | |||
56 | 18 | |||
57 | 19 | class TestDistroSeriesNeedsPackagesView(TestCaseWithFactory): | ||
58 | 20 | """Test the distroseries +needs-packaging view.""" | ||
59 | 21 | |||
60 | 22 | layer = LaunchpadZopelessLayer | ||
61 | 23 | |||
62 | 24 | def test_cached_unlinked_packages(self): | ||
63 | 25 | ubuntu = getUtility(ILaunchpadCelebrities).ubuntu | ||
64 | 26 | distroseries = self.factory.makeDistroSeries(distribution=ubuntu) | ||
65 | 27 | view = create_initialized_view(distroseries, '+needs-packaging') | ||
66 | 28 | naked_packages = removeSecurityProxy(view.cached_unlinked_packages) | ||
67 | 29 | self.assertTrue( | ||
68 | 30 | IResultSet.providedBy( | ||
69 | 31 | view.cached_unlinked_packages.currentBatch().list), | ||
70 | 32 | '%s should batch IResultSet so that slicing will limit the ' | ||
71 | 33 | 'query' % view.cached_unlinked_packages.currentBatch().list) | ||
72 | 34 | |||
73 | 35 | |||
74 | 36 | class TestDistroSeriesView(TestCaseWithFactory): | ||
75 | 37 | """Test the distroseries +index view.""" | ||
76 | 38 | |||
77 | 39 | layer = LaunchpadZopelessLayer | ||
78 | 40 | |||
79 | 41 | def test_needs_linking(self): | ||
80 | 42 | ubuntu = getUtility(ILaunchpadCelebrities).ubuntu | ||
81 | 43 | distroseries = self.factory.makeDistroSeries(distribution=ubuntu) | ||
82 | 44 | view = create_initialized_view(distroseries, '+index') | ||
83 | 45 | self.assertTrue( | ||
84 | 46 | IResultSet.providedBy(view.needs_linking), | ||
85 | 47 | '%s should implement IResultSet so that slicing will limit the ' | ||
86 | 48 | 'query' % view.needs_linking) | ||
87 | 49 | |||
88 | 50 | |||
89 | 51 | def test_suite(): | ||
90 | 52 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
91 | 0 | 53 | ||
92 | === modified file 'lib/lp/registry/doc/distroseries.txt' | |||
93 | --- lib/lp/registry/doc/distroseries.txt 2010-07-20 09:36:17 +0000 | |||
94 | +++ lib/lp/registry/doc/distroseries.txt 2010-07-28 19:11:08 +0000 | |||
95 | @@ -4,9 +4,10 @@ | |||
96 | 4 | From the DerivationOverview spec | 4 | From the DerivationOverview spec |
97 | 5 | <https://launchpad.canonical.com/DerivationOverview>: | 5 | <https://launchpad.canonical.com/DerivationOverview>: |
98 | 6 | 6 | ||
102 | 7 | A distribution of GNU/Linux comprises a set of packages, an installer, | 7 | A distribution of GNU/Linux comprises a set of packages, an |
103 | 8 | possibly a live-CD, some amount of metadata associated with the arrangement | 8 | installer, possibly a live-CD, some amount of metadata associated |
104 | 9 | of those elements and also a lot of information on managing it. | 9 | with the arrangement of those elements and also a lot of information |
105 | 10 | on managing it. | ||
106 | 10 | 11 | ||
107 | 11 | A distro series is a given version of a distribution. So, for Ubuntu, there | 12 | A distro series is a given version of a distribution. So, for Ubuntu, there |
108 | 12 | are releases (or planned releases) like "warty", "hoary" and "bendy". | 13 | are releases (or planned releases) like "warty", "hoary" and "bendy". |
109 | @@ -165,40 +166,40 @@ | |||
110 | 165 | canUploadToPocket method helps us to decide if an upload is allowed or | 166 | canUploadToPocket method helps us to decide if an upload is allowed or |
111 | 166 | not, according the distroseries status and the upload target pocket. | 167 | not, according the distroseries status and the upload target pocket. |
112 | 167 | 168 | ||
134 | 168 | >>> from canonical.launchpad.interfaces import IDistributionSet | 169 | >>> from canonical.launchpad.interfaces import IDistributionSet |
135 | 169 | >>> ubuntu = getUtility(IDistributionSet)['ubuntu'] | 170 | >>> ubuntu = getUtility(IDistributionSet)['ubuntu'] |
136 | 170 | >>> breezy_autotest = ubuntu['breezy-autotest'] | 171 | >>> breezy_autotest = ubuntu['breezy-autotest'] |
137 | 171 | >>> hoary = ubuntu['hoary'] | 172 | >>> hoary = ubuntu['hoary'] |
138 | 172 | 173 | ||
139 | 173 | >>> from lp.registry.interfaces.pocket import PackagePublishingPocket | 174 | >>> from lp.registry.interfaces.pocket import PackagePublishingPocket |
140 | 174 | >>> from canonical.launchpad.interfaces import SeriesStatus | 175 | >>> from canonical.launchpad.interfaces import SeriesStatus |
141 | 175 | 176 | ||
142 | 176 | >>> warty.status.name | 177 | >>> warty.status.name |
143 | 177 | 'CURRENT' | 178 | 'CURRENT' |
144 | 178 | >>> warty.canUploadToPocket(PackagePublishingPocket.RELEASE) | 179 | >>> warty.canUploadToPocket(PackagePublishingPocket.RELEASE) |
145 | 179 | False | 180 | False |
146 | 180 | >>> warty.canUploadToPocket(PackagePublishingPocket.SECURITY) | 181 | >>> warty.canUploadToPocket(PackagePublishingPocket.SECURITY) |
147 | 181 | True | 182 | True |
148 | 182 | 183 | ||
149 | 183 | >>> breezy_autotest.status.name | 184 | >>> breezy_autotest.status.name |
150 | 184 | 'EXPERIMENTAL' | 185 | 'EXPERIMENTAL' |
151 | 185 | >>> breezy_autotest.canUploadToPocket(PackagePublishingPocket.RELEASE) | 186 | >>> breezy_autotest.canUploadToPocket(PackagePublishingPocket.RELEASE) |
152 | 186 | True | 187 | True |
153 | 187 | >>> breezy_autotest.canUploadToPocket(PackagePublishingPocket.SECURITY) | 188 | >>> breezy_autotest.canUploadToPocket(PackagePublishingPocket.SECURITY) |
154 | 188 | False | 189 | False |
155 | 189 | 190 | ||
156 | 190 | The FROZEN status is special. Uploads are allowed for all pockets as | 191 | The FROZEN status is special. Uploads are allowed for all pockets as |
157 | 191 | the upload will have to wait for manual approval anyway: | 192 | the upload will have to wait for manual approval anyway: |
158 | 192 | 193 | ||
161 | 193 | >>> from zope.security.proxy import removeSecurityProxy | 194 | >>> from zope.security.proxy import removeSecurityProxy |
162 | 194 | >>> removeSecurityProxy(hoary).status = SeriesStatus.FROZEN | 195 | >>> removeSecurityProxy(hoary).status = SeriesStatus.FROZEN |
163 | 195 | 196 | ||
170 | 196 | >>> hoary.status.name | 197 | >>> hoary.status.name |
171 | 197 | 'FROZEN' | 198 | 'FROZEN' |
172 | 198 | >>> hoary.canUploadToPocket(PackagePublishingPocket.RELEASE) | 199 | >>> hoary.canUploadToPocket(PackagePublishingPocket.RELEASE) |
173 | 199 | True | 200 | True |
174 | 200 | >>> hoary.canUploadToPocket(PackagePublishingPocket.SECURITY) | 201 | >>> hoary.canUploadToPocket(PackagePublishingPocket.SECURITY) |
175 | 201 | True | 202 | True |
176 | 202 | 203 | ||
177 | 203 | 204 | ||
178 | 204 | Package searching | 205 | Package searching |
179 | @@ -232,44 +233,45 @@ | |||
180 | 232 | are valid for that distroseries. These selections are used by (among | 233 | are valid for that distroseries. These selections are used by (among |
181 | 233 | other things) the uploader for validating incoming uploads. | 234 | other things) the uploader for validating incoming uploads. |
182 | 234 | 235 | ||
217 | 235 | >>> hoary = distroseriesset.get(3) | 236 | >>> hoary = distroseriesset.get(3) |
218 | 236 | >>> for c in hoary.components: | 237 | >>> for c in hoary.components: |
219 | 237 | ... print c.name | 238 | ... print c.name |
220 | 238 | main | 239 | main |
221 | 239 | restricted | 240 | restricted |
222 | 240 | >>> for s in hoary.sections: | 241 | >>> for s in hoary.sections: |
223 | 241 | ... print s.name | 242 | ... print s.name |
224 | 242 | base | 243 | base |
225 | 243 | web | 244 | web |
226 | 244 | editors | 245 | editors |
227 | 245 | admin | 246 | admin |
228 | 246 | devel | 247 | devel |
229 | 247 | translations | 248 | translations |
230 | 248 | 249 | ||
231 | 249 | >>> from canonical.launchpad.interfaces import ( | 250 | >>> from canonical.launchpad.interfaces import ( |
232 | 250 | ... IComponentSet, ISectionSet) | 251 | ... IComponentSet, ISectionSet) |
233 | 251 | >>> python = getUtility(ISectionSet).ensure('python') | 252 | >>> python = getUtility(ISectionSet).ensure('python') |
234 | 252 | 253 | ||
235 | 253 | >>> hoary.addSection(python) | 254 | >>> hoary.addSection(python) |
236 | 254 | 255 | ||
237 | 255 | >>> for c in hoary.components: | 256 | >>> for c in hoary.components: |
238 | 256 | ... print c.name | 257 | ... print c.name |
239 | 257 | main | 258 | main |
240 | 258 | restricted | 259 | restricted |
241 | 259 | 260 | ||
242 | 260 | >>> for s in hoary.sections: | 261 | >>> for s in hoary.sections: |
243 | 261 | ... print s.name | 262 | ... print s.name |
244 | 262 | base | 263 | base |
245 | 263 | web | 264 | web |
246 | 264 | editors | 265 | editors |
247 | 265 | admin | 266 | admin |
248 | 266 | devel | 267 | devel |
249 | 267 | python | 268 | python |
250 | 268 | translations | 269 | translations |
251 | 269 | 270 | ||
252 | 270 | Breezy-autotest has got a partner component, which is not reported: | 271 | Breezy-autotest has got a partner component, which is not reported: |
253 | 271 | 272 | ||
255 | 272 | >>> breezyautotest = distroseriesset.queryByName(ubuntu, "breezy-autotest") | 273 | >>> breezyautotest = distroseriesset.queryByName( |
256 | 274 | ... ubuntu, "breezy-autotest") | ||
257 | 273 | >>> for c in breezyautotest.components: | 275 | >>> for c in breezyautotest.components: |
258 | 274 | ... print c.name | 276 | ... print c.name |
259 | 275 | main | 277 | main |
260 | @@ -307,22 +309,22 @@ | |||
261 | 307 | publishing records etc. Essentially this is a "Do not push this button | 309 | publishing records etc. Essentially this is a "Do not push this button |
262 | 308 | again" type set of assertions. | 310 | again" type set of assertions. |
263 | 309 | 311 | ||
280 | 310 | >>> login("foo.bar@canonical.com") | 312 | >>> login("foo.bar@canonical.com") |
281 | 311 | >>> humpy = ubuntu.newSeries('humpy', 'Humpy Hippo', | 313 | >>> humpy = ubuntu.newSeries('humpy', 'Humpy Hippo', |
282 | 312 | ... 'The Humpy Hippo', 'Fat', 'Yo Momma', | 314 | ... 'The Humpy Hippo', 'Fat', 'Yo Momma', |
283 | 313 | ... '99.2',hoary, hoary.owner) | 315 | ... '99.2',hoary, hoary.owner) |
284 | 314 | >>> humpy_i386 = humpy.newArch('i386', hoary['i386'].processorfamily, | 316 | >>> humpy_i386 = humpy.newArch('i386', hoary['i386'].processorfamily, |
285 | 315 | ... True, humpy.owner) | 317 | ... True, humpy.owner) |
286 | 316 | >>> humpy.nominatedarchindep = humpy_i386 | 318 | >>> humpy.nominatedarchindep = humpy_i386 |
287 | 317 | >>> humpy.initialiseFromParent() | 319 | >>> humpy.initialiseFromParent() |
288 | 318 | >>> len(hoary.getPublishedReleases('pmount')) | 320 | >>> len(hoary.getPublishedReleases('pmount')) |
289 | 319 | 1 | 321 | 1 |
290 | 320 | >>> len(humpy.getPublishedReleases('pmount')) | 322 | >>> len(humpy.getPublishedReleases('pmount')) |
291 | 321 | 1 | 323 | 1 |
292 | 322 | >>> len(hoary['i386'].getReleasedPackages('pmount')) | 324 | >>> len(hoary['i386'].getReleasedPackages('pmount')) |
293 | 323 | 1 | 325 | 1 |
294 | 324 | >>> len(humpy_i386.getReleasedPackages('pmount')) | 326 | >>> len(humpy_i386.getReleasedPackages('pmount')) |
295 | 325 | 1 | 327 | 1 |
296 | 326 | 328 | ||
297 | 327 | Check if the attributes of an DRSPR instance for the just initialised | 329 | Check if the attributes of an DRSPR instance for the just initialised |
298 | 328 | distroseries are sane. A DRSPR instance should filter attributes of | 330 | distroseries are sane. A DRSPR instance should filter attributes of |
299 | @@ -344,42 +346,42 @@ | |||
300 | 344 | Initialise a new distroseries based on warty (since it has, at least | 346 | Initialise a new distroseries based on warty (since it has, at least |
301 | 345 | one coherent published source + binary, mozilla-firefox) | 347 | one coherent published source + binary, mozilla-firefox) |
302 | 346 | 348 | ||
306 | 347 | >>> bumpy = ubuntu.newSeries('bumpy', 'Bumpy', | 349 | >>> bumpy = ubuntu.newSeries('bumpy', 'Bumpy', |
307 | 348 | ... 'The Bumpy', 'Fat', 'Boom', | 350 | ... 'The Bumpy', 'Fat', 'Boom', |
308 | 349 | ... '99.3', warty, warty.owner) | 351 | ... '99.3', warty, warty.owner) |
309 | 350 | 352 | ||
314 | 351 | >>> bumpy_i386 = bumpy.newArch('i386', warty['i386'].processorfamily, | 353 | >>> bumpy_i386 = bumpy.newArch('i386', warty['i386'].processorfamily, |
315 | 352 | ... True, bumpy.owner) | 354 | ... True, bumpy.owner) |
316 | 353 | >>> bumpy.nominatedarchindep = bumpy_i386 | 355 | >>> bumpy.nominatedarchindep = bumpy_i386 |
317 | 354 | >>> bumpy.initialiseFromParent() | 356 | >>> bumpy.initialiseFromParent() |
318 | 355 | 357 | ||
319 | 356 | Build a new ISourcePackage based in the new distroseries: | 358 | Build a new ISourcePackage based in the new distroseries: |
320 | 357 | 359 | ||
322 | 358 | >>> bumpy_firefox_sp = bumpy.getSourcePackage('mozilla-firefox') | 360 | >>> bumpy_firefox_sp = bumpy.getSourcePackage('mozilla-firefox') |
323 | 359 | 361 | ||
324 | 360 | Check the content IDRSPR binaries & builds attributes: | 362 | Check the content IDRSPR binaries & builds attributes: |
325 | 361 | 363 | ||
326 | 362 | 'binaries' should be inherited from parent release. | 364 | 'binaries' should be inherited from parent release. |
327 | 363 | 365 | ||
330 | 364 | >>> bumpy_firefox_sp.currentrelease.binaries.count() | 366 | >>> bumpy_firefox_sp.currentrelease.binaries.count() |
331 | 365 | 2 | 367 | 2 |
332 | 366 | 368 | ||
337 | 367 | >>> for bin in bumpy_firefox_sp.currentrelease.binaries: | 369 | >>> for bin in bumpy_firefox_sp.currentrelease.binaries: |
338 | 368 | ... print bin.id, bin.title, bin.build.distro_arch_series.title | 370 | ... print bin.id, bin.title, bin.build.distro_arch_series.title |
339 | 369 | 27 mozilla-firefox-data-0.9 The Warty Warthog Release for i386 (x86) | 371 | 27 mozilla-firefox-data-0.9 The Warty Warthog Release for i386 (x86) |
340 | 370 | 12 mozilla-firefox-0.9 The Warty Warthog Release for i386 (x86) | 372 | 12 mozilla-firefox-0.9 The Warty Warthog Release for i386 (x86) |
341 | 371 | 373 | ||
342 | 372 | 374 | ||
343 | 373 | 'builds' should be empty since it was built in parent (warty), not in this | 375 | 'builds' should be empty since it was built in parent (warty), not in this |
344 | 374 | distroseries (bumby. | 376 | distroseries (bumby. |
345 | 375 | 377 | ||
348 | 376 | >>> len(bumpy_firefox_sp.currentrelease.builds) | 378 | >>> len(bumpy_firefox_sp.currentrelease.builds) |
349 | 377 | 0 | 379 | 0 |
350 | 378 | 380 | ||
351 | 379 | the SPR returns all build records for it. | 381 | the SPR returns all build records for it. |
352 | 380 | 382 | ||
355 | 381 | >>> bumpy_firefox_sp.currentrelease.sourcepackagerelease.builds.count() | 383 | >>> bumpy_firefox_sp.currentrelease.sourcepackagerelease.builds.count() |
356 | 382 | 4 | 384 | 4 |
357 | 383 | 385 | ||
358 | 384 | The new series also has the same packaging links as its parent series. | 386 | The new series also has the same packaging links as its parent series. |
359 | 385 | 387 | ||
360 | @@ -406,22 +408,22 @@ | |||
361 | 406 | You can easily find out what packages are translatable in a | 408 | You can easily find out what packages are translatable in a |
362 | 407 | distribution release: | 409 | distribution release: |
363 | 408 | 410 | ||
370 | 409 | >>> translatables = hoary.getTranslatableSourcePackages() | 411 | >>> translatables = hoary.getTranslatableSourcePackages() |
371 | 410 | >>> for translatable in translatables: | 412 | >>> for translatable in translatables: |
372 | 411 | ... print translatable.name | 413 | ... print translatable.name |
373 | 412 | evolution | 414 | evolution |
374 | 413 | mozilla | 415 | mozilla |
375 | 414 | pmount | 416 | pmount |
376 | 415 | 417 | ||
377 | 416 | Packages can be linked to upstream productseries in specific | 418 | Packages can be linked to upstream productseries in specific |
378 | 417 | distribution releases. IDistroSeries offers a way to query translatable | 419 | distribution releases. IDistroSeries offers a way to query translatable |
379 | 418 | packages that are linked to upstream productseries. | 420 | packages that are linked to upstream productseries. |
380 | 419 | 421 | ||
386 | 420 | >>> unlinked_translatables = hoary.getUnlinkedTranslatableSourcePackages() | 422 | >>> unlinked_translatables = hoary.getUnlinkedTranslatableSourcePackages() |
387 | 421 | >>> for translatable in unlinked_translatables: | 423 | >>> for translatable in unlinked_translatables: |
388 | 422 | ... print translatable.name | 424 | ... print translatable.name |
389 | 423 | pmount | 425 | pmount |
390 | 424 | mozilla | 426 | mozilla |
391 | 425 | 427 | ||
392 | 426 | The links to upstream product series can be verified using the | 428 | The links to upstream product series can be verified using the |
393 | 427 | packagings property: | 429 | packagings property: |
394 | @@ -457,11 +459,11 @@ | |||
395 | 457 | linux-source-2.6.15 0 0 | 459 | linux-source-2.6.15 0 0 |
396 | 458 | 460 | ||
397 | 459 | 461 | ||
399 | 460 | The distroseries getPrioritizedlPackagings() method that returns a prioritized | 462 | The distroseries getPrioritizedPackagings() method that returns a prioritized |
400 | 461 | list of `IPackaging` that need more information about the upstream project to | 463 | list of `IPackaging` that need more information about the upstream project to |
401 | 462 | share bugs, translations, and code. | 464 | share bugs, translations, and code. |
402 | 463 | 465 | ||
404 | 464 | >>> for packaging in hoary.getPrioritizedlPackagings(): | 466 | >>> for packaging in hoary.getPrioritizedPackagings(): |
405 | 465 | ... print packaging.sourcepackagename.name | 467 | ... print packaging.sourcepackagename.name |
406 | 466 | netapplet | 468 | netapplet |
407 | 467 | evolution | 469 | evolution |
408 | @@ -502,109 +504,109 @@ | |||
409 | 502 | DistroSeries can build meta objects for packages | 504 | DistroSeries can build meta objects for packages |
410 | 503 | ------------------------------------------------ | 505 | ------------------------------------------------ |
411 | 504 | 506 | ||
441 | 505 | >>> from canonical.launchpad.interfaces import ( | 507 | >>> from canonical.launchpad.interfaces import ( |
442 | 506 | ... ISourcePackage, | 508 | ... ISourcePackage, |
443 | 507 | ... IDistroSeriesBinaryPackage, | 509 | ... IDistroSeriesBinaryPackage, |
444 | 508 | ... IDistroSeriesSourcePackageRelease) | 510 | ... IDistroSeriesSourcePackageRelease) |
445 | 509 | 511 | ||
446 | 510 | >>> pmount_src_name = SourcePackageName.byName('pmount') | 512 | >>> pmount_src_name = SourcePackageName.byName('pmount') |
447 | 511 | >>> pmount_source = hoary.getSourcePackage(pmount_src_name) | 513 | >>> pmount_source = hoary.getSourcePackage(pmount_src_name) |
448 | 512 | >>> ISourcePackage.providedBy(pmount_source) | 514 | >>> ISourcePackage.providedBy(pmount_source) |
449 | 513 | True | 515 | True |
450 | 514 | 516 | ||
451 | 515 | >>> from lp.soyuz.model.binarypackagename import ( | 517 | >>> from lp.soyuz.model.binarypackagename import ( |
452 | 516 | ... BinaryPackageName) | 518 | ... BinaryPackageName) |
453 | 517 | >>> pmount_bin_name = BinaryPackageName.byName('pmount') | 519 | >>> pmount_bin_name = BinaryPackageName.byName('pmount') |
454 | 518 | >>> pmount_drbp = hoary.getBinaryPackage(pmount_bin_name) | 520 | >>> pmount_drbp = hoary.getBinaryPackage(pmount_bin_name) |
455 | 519 | >>> IDistroSeriesBinaryPackage.providedBy(pmount_drbp) | 521 | >>> IDistroSeriesBinaryPackage.providedBy(pmount_drbp) |
456 | 520 | True | 522 | True |
457 | 521 | >>> len(pmount_drbp.current_publishings) | 523 | >>> len(pmount_drbp.current_publishings) |
458 | 522 | 3 | 524 | 3 |
459 | 523 | 525 | ||
460 | 524 | >>> from lp.soyuz.model.sourcepackagerelease import ( | 526 | >>> from lp.soyuz.model.sourcepackagerelease import ( |
461 | 525 | ... SourcePackageRelease) | 527 | ... SourcePackageRelease) |
462 | 526 | >>> pmount_rel = SourcePackageRelease.selectOneBy( | 528 | >>> pmount_rel = SourcePackageRelease.selectOneBy( |
463 | 527 | ... sourcepackagenameID=pmount_src_name.id, version='0.1-1') | 529 | ... sourcepackagenameID=pmount_src_name.id, version='0.1-1') |
464 | 528 | >>> pmount_rel.sourcepackagename.name | 530 | >>> pmount_rel.sourcepackagename.name |
465 | 529 | u'pmount' | 531 | u'pmount' |
466 | 530 | 532 | ||
467 | 531 | >>> pmount_srcrel = hoary.getSourcePackageRelease(pmount_rel) | 533 | >>> pmount_srcrel = hoary.getSourcePackageRelease(pmount_rel) |
468 | 532 | >>> IDistroSeriesSourcePackageRelease.providedBy(pmount_srcrel) | 534 | >>> IDistroSeriesSourcePackageRelease.providedBy(pmount_srcrel) |
469 | 533 | True | 535 | True |
470 | 534 | 536 | ||
471 | 535 | Check some properties of DRSPR meta class | 537 | Check some properties of DRSPR meta class |
472 | 536 | 538 | ||
473 | 537 | Entire publishing history: | 539 | Entire publishing history: |
474 | 538 | 540 | ||
477 | 539 | >>> pmount_srcrel.publishing_history.count() | 541 | >>> pmount_srcrel.publishing_history.count() |
478 | 540 | 1 | 542 | 1 |
479 | 541 | 543 | ||
480 | 542 | Most recent published history row: | 544 | Most recent published history row: |
481 | 543 | 545 | ||
490 | 544 | >>> pmount_srcrel.current_published is None | 546 | >>> pmount_srcrel.current_published is None |
491 | 545 | True | 547 | True |
492 | 546 | 548 | ||
493 | 547 | >>> netapplet_srcrel = hoary.getSourcePackage('netapplet').currentrelease | 549 | >>> netapplet_srcrel = hoary.getSourcePackage('netapplet').currentrelease |
494 | 548 | >>> spph = netapplet_srcrel.current_published | 550 | >>> spph = netapplet_srcrel.current_published |
495 | 549 | 551 | ||
496 | 550 | >>> spph.section.name | 552 | >>> spph.section.name |
497 | 551 | u'web' | 553 | u'web' |
498 | 552 | 554 | ||
499 | 553 | The changesfile attribute contains the package changelog. It is provided as | 555 | The changesfile attribute contains the package changelog. It is provided as |
500 | 554 | an ILibraryFileAlias: | 556 | an ILibraryFileAlias: |
501 | 555 | 557 | ||
506 | 556 | >>> firefox_srcrel = warty.getSourcePackage( | 558 | >>> firefox_srcrel = warty.getSourcePackage( |
507 | 557 | ... 'mozilla-firefox').currentrelease | 559 | ... 'mozilla-firefox').currentrelease |
508 | 558 | >>> print firefox_srcrel.title | 560 | >>> print firefox_srcrel.title |
509 | 559 | "mozilla-firefox" 0.9 source package in The Warty Warthog Release | 561 | "mozilla-firefox" 0.9 source package in The Warty Warthog Release |
510 | 560 | 562 | ||
513 | 561 | >>> firefox_srcrel.changesfile | 563 | >>> firefox_srcrel.changesfile |
514 | 562 | <LibraryFileAlias at ...> | 564 | <LibraryFileAlias at ...> |
515 | 563 | 565 | ||
516 | 564 | If the package changelog is not available, that attribute is None: | 566 | If the package changelog is not available, that attribute is None: |
517 | 565 | 567 | ||
520 | 566 | >>> netapplet_srcrel.changesfile is None | 568 | >>> netapplet_srcrel.changesfile is None |
521 | 567 | True | 569 | True |
522 | 568 | 570 | ||
523 | 569 | Perform `post publication` override: | 571 | Perform `post publication` override: |
524 | 570 | 572 | ||
538 | 571 | >>> new_section = getUtility(ISectionSet)['base'] | 573 | >>> new_section = getUtility(ISectionSet)['base'] |
539 | 572 | 574 | ||
540 | 573 | >>> override = netapplet_srcrel.current_published.changeOverride( | 575 | >>> override = netapplet_srcrel.current_published.changeOverride( |
541 | 574 | ... new_section=new_section) | 576 | ... new_section=new_section) |
542 | 575 | 577 | ||
543 | 576 | >>> override.section == new_section | 578 | >>> override.section == new_section |
544 | 577 | True | 579 | True |
545 | 578 | 580 | ||
546 | 579 | >>> print override.status.name | 581 | >>> print override.status.name |
547 | 580 | PENDING | 582 | PENDING |
548 | 581 | 583 | ||
549 | 582 | >>> netapplet_srcrel.publishing_history.count() | 584 | >>> netapplet_srcrel.publishing_history.count() |
550 | 583 | 2 | 585 | 2 |
551 | 584 | 586 | ||
552 | 585 | Override information about 'pmount' is pending publication: | 587 | Override information about 'pmount' is pending publication: |
553 | 586 | 588 | ||
556 | 587 | >>> print netapplet_srcrel.current_published.status.name | 589 | >>> print netapplet_srcrel.current_published.status.name |
557 | 588 | PENDING | 590 | PENDING |
558 | 589 | 591 | ||
561 | 590 | >>> print netapplet_srcrel.current_published.section.name | 592 | >>> print netapplet_srcrel.current_published.section.name |
562 | 591 | base | 593 | base |
563 | 592 | 594 | ||
564 | 593 | Supersede previous netapplet publication: | 595 | Supersede previous netapplet publication: |
565 | 594 | 596 | ||
579 | 595 | >>> last_published = netapplet_srcrel.publishing_history[1] | 597 | >>> last_published = netapplet_srcrel.publishing_history[1] |
580 | 596 | >>> last_published.supersede() | 598 | >>> last_published.supersede() |
581 | 597 | >>> flush_database_updates() | 599 | >>> flush_database_updates() |
582 | 598 | 600 | ||
583 | 599 | >>> netapplet_srcrel.publishing_history.count() | 601 | >>> netapplet_srcrel.publishing_history.count() |
584 | 600 | 2 | 602 | 2 |
585 | 601 | 603 | ||
586 | 602 | >>> print last_published.status.name | 604 | >>> print last_published.status.name |
587 | 603 | SUPERSEDED | 605 | SUPERSEDED |
588 | 604 | 606 | ||
589 | 605 | >>> from canonical.database.sqlbase import get_transaction_timestamp | 607 | >>> from canonical.database.sqlbase import get_transaction_timestamp |
590 | 606 | >>> last_published.datesuperseded == get_transaction_timestamp() | 608 | >>> last_published.datesuperseded == get_transaction_timestamp() |
591 | 607 | True | 609 | True |
592 | 608 | 610 | ||
593 | 609 | 611 | ||
594 | 610 | SourcePackagePublishingHistory | 612 | SourcePackagePublishingHistory |
595 | @@ -616,114 +618,114 @@ | |||
596 | 616 | instance. it can also be used to generate the archive packages list in | 618 | instance. it can also be used to generate the archive packages list in |
597 | 617 | the future. | 619 | the future. |
598 | 618 | 620 | ||
639 | 619 | >>> ubuntu = getUtility(IDistributionSet)['ubuntu'] | 621 | >>> ubuntu = getUtility(IDistributionSet)['ubuntu'] |
640 | 620 | >>> hoary = ubuntu['hoary'] | 622 | >>> hoary = ubuntu['hoary'] |
641 | 621 | 623 | ||
642 | 622 | >>> from canonical.launchpad.interfaces import ( | 624 | >>> from canonical.launchpad.interfaces import ( |
643 | 623 | ... PackagePublishingStatus) | 625 | ... PackagePublishingStatus) |
644 | 624 | 626 | ||
645 | 625 | >>> hoary_pub_sources = hoary.getSourcePackagePublishing( | 627 | >>> hoary_pub_sources = hoary.getSourcePackagePublishing( |
646 | 626 | ... PackagePublishingStatus.PUBLISHED, | 628 | ... PackagePublishingStatus.PUBLISHED, |
647 | 627 | ... PackagePublishingPocket.RELEASE) | 629 | ... PackagePublishingPocket.RELEASE) |
648 | 628 | 630 | ||
649 | 629 | >>> hoary_pub_sources.count() | 631 | >>> hoary_pub_sources.count() |
650 | 630 | 6 | 632 | 6 |
651 | 631 | 633 | ||
652 | 632 | >>> for pub in hoary_pub_sources: | 634 | >>> for pub in hoary_pub_sources: |
653 | 633 | ... print pub.displayname | 635 | ... print pub.displayname |
654 | 634 | alsa-utils 1.0.9a-4ubuntu1 in hoary | 636 | alsa-utils 1.0.9a-4ubuntu1 in hoary |
655 | 635 | cnews cr.g7-37 in hoary | 637 | cnews cr.g7-37 in hoary |
656 | 636 | evolution 1.0 in hoary | 638 | evolution 1.0 in hoary |
657 | 637 | libstdc++ b8p in hoary | 639 | libstdc++ b8p in hoary |
658 | 638 | linux-source-2.6.15 2.6.15.3 in hoary | 640 | linux-source-2.6.15 2.6.15.3 in hoary |
659 | 639 | pmount 0.1-2 in hoary | 641 | pmount 0.1-2 in hoary |
660 | 640 | 642 | ||
661 | 641 | >>> hoary_pub_source = hoary_pub_sources[0] | 643 | >>> hoary_pub_source = hoary_pub_sources[0] |
662 | 642 | 644 | ||
663 | 643 | >>> hoary_pub_source.sourcepackagerelease.name | 645 | >>> hoary_pub_source.sourcepackagerelease.name |
664 | 644 | u'alsa-utils' | 646 | u'alsa-utils' |
665 | 645 | 647 | ||
666 | 646 | >>> hoary_pub_source.sourcepackagerelease.version | 648 | >>> hoary_pub_source.sourcepackagerelease.version |
667 | 647 | u'1.0.9a-4ubuntu1' | 649 | u'1.0.9a-4ubuntu1' |
668 | 648 | 650 | ||
669 | 649 | >>> hoary_pub_source.component.name | 651 | >>> hoary_pub_source.component.name |
670 | 650 | u'main' | 652 | u'main' |
671 | 651 | 653 | ||
672 | 652 | >>> hoary_pub_source.section.name | 654 | >>> hoary_pub_source.section.name |
673 | 653 | u'base' | 655 | u'base' |
674 | 654 | 656 | ||
675 | 655 | >>> hoary.getSourcePackagePublishing( | 657 | >>> hoary.getSourcePackagePublishing( |
676 | 656 | ... PackagePublishingStatus.PUBLISHED, | 658 | ... PackagePublishingStatus.PUBLISHED, |
677 | 657 | ... PackagePublishingPocket.UPDATES).count() | 659 | ... PackagePublishingPocket.UPDATES).count() |
678 | 658 | 0 | 660 | 0 |
679 | 659 | 661 | ||
680 | 660 | This method also allow us to restrict the results to a given | 662 | This method also allow us to restrict the results to a given |
681 | 661 | component: | 663 | component: |
682 | 662 | 664 | ||
689 | 663 | >>> component_main = getUtility(IComponentSet)['main'] | 665 | >>> component_main = getUtility(IComponentSet)['main'] |
690 | 664 | >>> hoary.getSourcePackagePublishing( | 666 | >>> hoary.getSourcePackagePublishing( |
691 | 665 | ... PackagePublishingStatus.PUBLISHED, | 667 | ... PackagePublishingStatus.PUBLISHED, |
692 | 666 | ... PackagePublishingPocket.RELEASE, | 668 | ... PackagePublishingPocket.RELEASE, |
693 | 667 | ... component=component_main).count() | 669 | ... component=component_main).count() |
694 | 668 | 5 | 670 | 5 |
695 | 669 | 671 | ||
702 | 670 | >>> component_multiverse = getUtility(IComponentSet)['multiverse'] | 672 | >>> component_multiverse = getUtility(IComponentSet)['multiverse'] |
703 | 671 | >>> hoary.getSourcePackagePublishing( | 673 | >>> hoary.getSourcePackagePublishing( |
704 | 672 | ... PackagePublishingStatus.PUBLISHED, | 674 | ... PackagePublishingStatus.PUBLISHED, |
705 | 673 | ... PackagePublishingPocket.RELEASE, | 675 | ... PackagePublishingPocket.RELEASE, |
706 | 674 | ... component=component_multiverse).count() | 676 | ... component=component_multiverse).count() |
707 | 675 | 0 | 677 | 0 |
708 | 676 | 678 | ||
709 | 677 | By default the IDistribution 'main_archive' is considered, but It also | 679 | By default the IDistribution 'main_archive' is considered, but It also |
710 | 678 | allows the callsite to specify one and then the result will be | 680 | allows the callsite to specify one and then the result will be |
711 | 679 | restricted to it. | 681 | restricted to it. |
712 | 680 | 682 | ||
716 | 681 | >>> debian_archive = getUtility(IDistributionSet)['debian'].main_archive | 683 | >>> debian_archive = getUtility(IDistributionSet)['debian'].main_archive |
717 | 682 | >>> print debian_archive.purpose.title | 684 | >>> print debian_archive.purpose.title |
718 | 683 | Primary Archive | 685 | Primary Archive |
719 | 684 | 686 | ||
725 | 685 | >>> hoary.getSourcePackagePublishing( | 687 | >>> hoary.getSourcePackagePublishing( |
726 | 686 | ... PackagePublishingStatus.PUBLISHED, | 688 | ... PackagePublishingStatus.PUBLISHED, |
727 | 687 | ... PackagePublishingPocket.RELEASE, | 689 | ... PackagePublishingPocket.RELEASE, |
728 | 688 | ... component=component_main, archive=debian_archive).count() | 690 | ... component=component_main, archive=debian_archive).count() |
729 | 689 | 0 | 691 | 0 |
730 | 690 | 692 | ||
731 | 691 | ISPP.getPublishedBinaries returns all the binaries generated by the | 693 | ISPP.getPublishedBinaries returns all the binaries generated by the |
732 | 692 | publication in question: | 694 | publication in question: |
733 | 693 | 695 | ||
767 | 694 | >>> warty = ubuntu['warty'] | 696 | >>> warty = ubuntu['warty'] |
768 | 695 | >>> warty_pub_sources = warty.getSourcePackagePublishing( | 697 | >>> warty_pub_sources = warty.getSourcePackagePublishing( |
769 | 696 | ... PackagePublishingStatus.PUBLISHED, | 698 | ... PackagePublishingStatus.PUBLISHED, |
770 | 697 | ... PackagePublishingPocket.RELEASE) | 699 | ... PackagePublishingPocket.RELEASE) |
771 | 698 | 700 | ||
772 | 699 | >>> warty_pub_source = warty_pub_sources[4] | 701 | >>> warty_pub_source = warty_pub_sources[4] |
773 | 700 | >>> warty_pub_source.sourcepackagerelease.name | 702 | >>> warty_pub_source.sourcepackagerelease.name |
774 | 701 | u'mozilla-firefox' | 703 | u'mozilla-firefox' |
775 | 702 | >>> warty_pub_source.sourcepackagerelease.version | 704 | >>> warty_pub_source.sourcepackagerelease.version |
776 | 703 | u'0.9' | 705 | u'0.9' |
777 | 704 | >>> warty_pub_source.component.name | 706 | >>> warty_pub_source.component.name |
778 | 705 | u'main' | 707 | u'main' |
779 | 706 | >>> warty_pub_source.section.name | 708 | >>> warty_pub_source.section.name |
780 | 707 | u'web' | 709 | u'web' |
781 | 708 | 710 | ||
782 | 709 | >>> warty_mozilla_pub_binaries = warty_pub_source.getPublishedBinaries() | 711 | >>> warty_mozilla_pub_binaries = warty_pub_source.getPublishedBinaries() |
783 | 710 | >>> len(warty_mozilla_pub_binaries) | 712 | >>> len(warty_mozilla_pub_binaries) |
784 | 711 | 4 | 713 | 4 |
785 | 712 | >>> warty_mozilla_pub_bin = warty_mozilla_pub_binaries[0] | 714 | >>> warty_mozilla_pub_bin = warty_mozilla_pub_binaries[0] |
786 | 713 | 715 | ||
787 | 714 | >>> from canonical.launchpad.interfaces import ( | 716 | >>> from canonical.launchpad.interfaces import ( |
788 | 715 | ... IBinaryPackagePublishingHistory) | 717 | ... IBinaryPackagePublishingHistory) |
789 | 716 | >>> verifyObject(IBinaryPackagePublishingHistory, warty_mozilla_pub_bin) | 718 | >>> verifyObject(IBinaryPackagePublishingHistory, warty_mozilla_pub_bin) |
790 | 717 | True | 719 | True |
791 | 718 | 720 | ||
792 | 719 | >>> warty_mozilla_pub_bin.binarypackagerelease.name | 721 | >>> warty_mozilla_pub_bin.binarypackagerelease.name |
793 | 720 | u'mozilla-firefox' | 722 | u'mozilla-firefox' |
794 | 721 | >>> warty_mozilla_pub_bin.binarypackagerelease.version | 723 | >>> warty_mozilla_pub_bin.binarypackagerelease.version |
795 | 722 | u'0.9' | 724 | u'0.9' |
796 | 723 | >>> warty_mozilla_pub_bin.component.name | 725 | >>> warty_mozilla_pub_bin.component.name |
797 | 724 | u'main' | 726 | u'main' |
798 | 725 | >>> warty_mozilla_pub_bin.section.name | 727 | >>> warty_mozilla_pub_bin.section.name |
799 | 726 | u'base' | 728 | u'base' |
800 | 727 | 729 | ||
801 | 728 | DistroSeries.getBinaryPackagePublishing will return | 730 | DistroSeries.getBinaryPackagePublishing will return |
802 | 729 | BinaryPackagePublishingHistory objects for the DistroSeries: | 731 | BinaryPackagePublishingHistory objects for the DistroSeries: |
803 | 730 | 732 | ||
804 | === modified file 'lib/lp/registry/interfaces/distroseries.py' | |||
805 | --- lib/lp/registry/interfaces/distroseries.py 2010-06-08 15:58:04 +0000 | |||
806 | +++ lib/lp/registry/interfaces/distroseries.py 2010-07-28 19:11:08 +0000 | |||
807 | @@ -414,7 +414,7 @@ | |||
808 | 414 | and total_messages (translatable messages). | 414 | and total_messages (translatable messages). |
809 | 415 | """ | 415 | """ |
810 | 416 | 416 | ||
812 | 417 | def getPrioritizedlPackagings(): | 417 | def getPrioritizedPackagings(): |
813 | 418 | """Return a list of packagings that need more upstream information.""" | 418 | """Return a list of packagings that need more upstream information.""" |
814 | 419 | 419 | ||
815 | 420 | def getMostRecentlyLinkedPackagings(): | 420 | def getMostRecentlyLinkedPackagings(): |
816 | @@ -514,15 +514,16 @@ | |||
817 | 514 | 514 | ||
818 | 515 | If version is not specified, return packages with any version. | 515 | If version is not specified, return packages with any version. |
819 | 516 | 516 | ||
821 | 517 | if exclude_pocket is specified we exclude results matching that pocket. | 517 | If exclude_pocket is specified we exclude results matching that |
822 | 518 | pocket. | ||
823 | 518 | 519 | ||
824 | 519 | If 'include_pending' is True, we return also the pending publication | 520 | If 'include_pending' is True, we return also the pending publication |
825 | 520 | records, those packages that will get published in the next publisher | 521 | records, those packages that will get published in the next publisher |
826 | 521 | run (it's only useful when we need to know if a given package is | 522 | run (it's only useful when we need to know if a given package is |
827 | 522 | known during a publisher run, mostly in pre-upload checks) | 523 | known during a publisher run, mostly in pre-upload checks) |
828 | 523 | 524 | ||
831 | 524 | If 'archive' is not specified consider publication in the main_archive, | 525 | If 'archive' is not specified consider publication in the |
832 | 525 | otherwise respect the given value. | 526 | main_archive, otherwise respect the given value. |
833 | 526 | """ | 527 | """ |
834 | 527 | 528 | ||
835 | 528 | def getAllPublishedSources(): | 529 | def getAllPublishedSources(): |
836 | 529 | 530 | ||
837 | === modified file 'lib/lp/registry/model/distroseries.py' | |||
838 | --- lib/lp/registry/model/distroseries.py 2010-07-15 15:01:18 +0000 | |||
839 | +++ lib/lp/registry/model/distroseries.py 2010-07-28 19:11:08 +0000 | |||
840 | @@ -19,7 +19,7 @@ | |||
841 | 19 | BoolCol, StringCol, ForeignKey, SQLMultipleJoin, IntCol, | 19 | BoolCol, StringCol, ForeignKey, SQLMultipleJoin, IntCol, |
842 | 20 | SQLObjectNotFound, SQLRelatedJoin) | 20 | SQLObjectNotFound, SQLRelatedJoin) |
843 | 21 | 21 | ||
845 | 22 | from storm.locals import And, Desc, Join, SQL | 22 | from storm.locals import Desc, Join, SQL |
846 | 23 | from storm.store import Store | 23 | from storm.store import Store |
847 | 24 | 24 | ||
848 | 25 | from zope.component import getUtility | 25 | from zope.component import getUtility |
849 | @@ -335,14 +335,19 @@ | |||
850 | 335 | condition = SQL(conditions + "AND packaging.id IS NULL") | 335 | condition = SQL(conditions + "AND packaging.id IS NULL") |
851 | 336 | results = IStore(self).using(origin).find(find_spec, condition) | 336 | results = IStore(self).using(origin).find(find_spec, condition) |
852 | 337 | results = results.order_by('score DESC', SourcePackageName.name) | 337 | results = results.order_by('score DESC', SourcePackageName.name) |
855 | 338 | return [{ | 338 | results = results.config(distinct=True) |
856 | 339 | 'package': SourcePackage( | 339 | |
857 | 340 | def decorator(result): | ||
858 | 341 | spn, score, bug_count, total_messages = result | ||
859 | 342 | return { | ||
860 | 343 | 'package': SourcePackage( | ||
861 | 340 | sourcepackagename=spn, distroseries=self), | 344 | sourcepackagename=spn, distroseries=self), |
865 | 341 | 'bug_count': bug_count, | 345 | 'bug_count': bug_count, |
866 | 342 | 'total_messages': total_messages} | 346 | 'total_messages': total_messages, |
867 | 343 | for (spn, score, bug_count, total_messages) in results] | 347 | } |
868 | 348 | return DecoratedResultSet(results, decorator) | ||
869 | 344 | 349 | ||
871 | 345 | def getPrioritizedlPackagings(self): | 350 | def getPrioritizedPackagings(self): |
872 | 346 | """See `IDistroSeries`. | 351 | """See `IDistroSeries`. |
873 | 347 | 352 | ||
874 | 348 | The prioritization is a heuristic rule using the branch, bug heat, | 353 | The prioritization is a heuristic rule using the branch, bug heat, |
875 | @@ -352,18 +357,6 @@ | |||
876 | 352 | # the objects that are implcitly needed to work with a | 357 | # the objects that are implcitly needed to work with a |
877 | 353 | # Packaging object. | 358 | # Packaging object. |
878 | 354 | # Avoid circular import failures. | 359 | # Avoid circular import failures. |
879 | 355 | from lp.registry.model.product import Product | ||
880 | 356 | from lp.registry.model.productseries import ProductSeries | ||
881 | 357 | find_spec = ( | ||
882 | 358 | Packaging, SourcePackageName, ProductSeries, Product, | ||
883 | 359 | SQL(""" | ||
884 | 360 | CASE WHEN spr.component = 1 THEN 1000 ELSE 0 END + | ||
885 | 361 | CASE WHEN Product.bugtracker IS NULL | ||
886 | 362 | THEN coalesce(total_bug_heat, 10) ELSE 0 END + | ||
887 | 363 | CASE WHEN ProductSeries.translations_autoimport_mode = 1 | ||
888 | 364 | THEN coalesce(po_messages, 10) ELSE 0 END + | ||
889 | 365 | CASE WHEN ProductSeries.branch IS NULL THEN 500 | ||
890 | 366 | ELSE 0 END AS score""")) | ||
891 | 367 | joins, conditions = self._current_sourcepackage_joins_and_conditions | 360 | joins, conditions = self._current_sourcepackage_joins_and_conditions |
892 | 368 | origin = SQL(joins + """ | 361 | origin = SQL(joins + """ |
893 | 369 | JOIN ProductSeries | 362 | JOIN ProductSeries |
894 | @@ -372,10 +365,19 @@ | |||
895 | 372 | ON ProductSeries.product = Product.id | 365 | ON ProductSeries.product = Product.id |
896 | 373 | """) | 366 | """) |
897 | 374 | condition = SQL(conditions + "AND packaging.id IS NOT NULL") | 367 | condition = SQL(conditions + "AND packaging.id IS NOT NULL") |
902 | 375 | results = IStore(self).using(origin).find(find_spec, condition) | 368 | results = IStore(self).using(origin).find(Packaging, condition) |
903 | 376 | results = results.order_by('score DESC, SourcePackageName.name ASC') | 369 | return results.order_by(""" |
904 | 377 | return [packaging | 370 | ( |
905 | 378 | for (packaging, spn, series, product, score) in results] | 371 | CASE WHEN spr.component = 1 THEN 1000 ELSE 0 END |
906 | 372 | + CASE WHEN Product.bugtracker IS NULL | ||
907 | 373 | THEN coalesce(total_bug_heat, 10) ELSE 0 END | ||
908 | 374 | + CASE WHEN ProductSeries.translations_autoimport_mode = 1 | ||
909 | 375 | THEN coalesce(po_messages, 10) ELSE 0 END | ||
910 | 376 | + CASE WHEN ProductSeries.branch IS NULL THEN 500 | ||
911 | 377 | ELSE 0 END | ||
912 | 378 | ) DESC, | ||
913 | 379 | SourcePackageName.name ASC | ||
914 | 380 | """) | ||
915 | 379 | 381 | ||
916 | 380 | @property | 382 | @property |
917 | 381 | def _current_sourcepackage_joins_and_conditions(self): | 383 | def _current_sourcepackage_joins_and_conditions(self): |
918 | 382 | 384 | ||
919 | === modified file 'lib/lp/registry/stories/distroseries/xx-distroseries-index.txt' | |||
920 | --- lib/lp/registry/stories/distroseries/xx-distroseries-index.txt 2010-02-26 19:18:37 +0000 | |||
921 | +++ lib/lp/registry/stories/distroseries/xx-distroseries-index.txt 2010-07-28 19:11:08 +0000 | |||
922 | @@ -100,4 +100,9 @@ | |||
923 | 100 | evolution linked... | 100 | evolution linked... |
924 | 101 | mozilla-firefox linked... | 101 | mozilla-firefox linked... |
925 | 102 | netapplet linked 2005-07-05 | 102 | netapplet linked 2005-07-05 |
927 | 103 | Needs upstream links All upstream links | 103 | Needs more information or linking to upstream: |
928 | 104 | cdrkit | ||
929 | 105 | iceweasel | ||
930 | 106 | linux-source-2.6.15 | ||
931 | 107 | Needs upstream links | ||
932 | 108 | All upstream links | ||
933 | 104 | 109 | ||
934 | === modified file 'lib/lp/registry/templates/distroseries-portlet-packaging.pt' | |||
935 | --- lib/lp/registry/templates/distroseries-portlet-packaging.pt 2010-05-27 04:10:17 +0000 | |||
936 | +++ lib/lp/registry/templates/distroseries-portlet-packaging.pt 2010-07-28 19:11:08 +0000 | |||
937 | @@ -56,7 +56,7 @@ | |||
938 | 56 | </dt> | 56 | </dt> |
939 | 57 | <dd tal:condition="view/needs_linking"> | 57 | <dd tal:condition="view/needs_linking"> |
940 | 58 | <ul class="horizontal"> | 58 | <ul class="horizontal"> |
942 | 59 | <li repeat="package view/needs_linking"> | 59 | <li tal:repeat="package view/needs_linking"> |
943 | 60 | <a class="sprite package-source" | 60 | <a class="sprite package-source" |
944 | 61 | tal:attributes="href package/package/fmt:url" | 61 | tal:attributes="href package/package/fmt:url" |
945 | 62 | tal:content="package/package/name">evolution</a> | 62 | tal:content="package/package/name">evolution</a> |
946 | 63 | 63 | ||
947 | === modified file 'lib/lp/registry/tests/test_distroseries.py' | |||
948 | --- lib/lp/registry/tests/test_distroseries.py 2010-07-20 17:50:45 +0000 | |||
949 | +++ lib/lp/registry/tests/test_distroseries.py 2010-07-28 19:11:08 +0000 | |||
950 | @@ -271,17 +271,17 @@ | |||
951 | 271 | u'main', u'hot-translatable', u'hot', u'translatable', u'normal'] | 271 | u'main', u'hot-translatable', u'hot', u'translatable', u'normal'] |
952 | 272 | self.assertEqual(expected, names) | 272 | self.assertEqual(expected, names) |
953 | 273 | 273 | ||
955 | 274 | def test_getPrioritizedlPackagings(self): | 274 | def test_getPrioritizedPackagings(self): |
956 | 275 | # Verify the ordering of packagings that need more upstream info. | 275 | # Verify the ordering of packagings that need more upstream info. |
957 | 276 | for name in ['main', 'hot-translatable', 'hot', 'translatable']: | 276 | for name in ['main', 'hot-translatable', 'hot', 'translatable']: |
958 | 277 | self.linkPackage(name) | 277 | self.linkPackage(name) |
960 | 278 | packagings = self.series.getPrioritizedlPackagings() | 278 | packagings = self.series.getPrioritizedPackagings() |
961 | 279 | names = [packaging.sourcepackagename.name for packaging in packagings] | 279 | names = [packaging.sourcepackagename.name for packaging in packagings] |
962 | 280 | expected = [ | 280 | expected = [ |
963 | 281 | u'main', u'hot-translatable', u'hot', u'translatable', u'linked'] | 281 | u'main', u'hot-translatable', u'hot', u'translatable', u'linked'] |
964 | 282 | self.assertEqual(expected, names) | 282 | self.assertEqual(expected, names) |
965 | 283 | 283 | ||
967 | 284 | def test_getPrioritizedlPackagings_bug_tracker(self): | 284 | def test_getPrioritizedPackagings_bug_tracker(self): |
968 | 285 | # Verify the ordering of packagings with and without a bug tracker. | 285 | # Verify the ordering of packagings with and without a bug tracker. |
969 | 286 | self.linkPackage('hot') | 286 | self.linkPackage('hot') |
970 | 287 | self.makeSeriesPackage('cold') | 287 | self.makeSeriesPackage('cold') |
971 | @@ -289,12 +289,12 @@ | |||
972 | 289 | naked_product_series = remove_security_proxy_and_shout_at_engineer( | 289 | naked_product_series = remove_security_proxy_and_shout_at_engineer( |
973 | 290 | product_series) | 290 | product_series) |
974 | 291 | naked_product_series.product.bugtraker = self.factory.makeBugTracker() | 291 | naked_product_series.product.bugtraker = self.factory.makeBugTracker() |
976 | 292 | packagings = self.series.getPrioritizedlPackagings() | 292 | packagings = self.series.getPrioritizedPackagings() |
977 | 293 | names = [packaging.sourcepackagename.name for packaging in packagings] | 293 | names = [packaging.sourcepackagename.name for packaging in packagings] |
978 | 294 | expected = [u'hot', u'cold', u'linked'] | 294 | expected = [u'hot', u'cold', u'linked'] |
979 | 295 | self.assertEqual(expected, names) | 295 | self.assertEqual(expected, names) |
980 | 296 | 296 | ||
982 | 297 | def test_getPrioritizedlPackagings_branch(self): | 297 | def test_getPrioritizedPackagings_branch(self): |
983 | 298 | # Verify the ordering of packagings with and without a branch. | 298 | # Verify the ordering of packagings with and without a branch. |
984 | 299 | self.linkPackage('translatable') | 299 | self.linkPackage('translatable') |
985 | 300 | self.makeSeriesPackage('withbranch') | 300 | self.makeSeriesPackage('withbranch') |
986 | @@ -302,12 +302,12 @@ | |||
987 | 302 | naked_product_series = remove_security_proxy_and_shout_at_engineer( | 302 | naked_product_series = remove_security_proxy_and_shout_at_engineer( |
988 | 303 | product_series) | 303 | product_series) |
989 | 304 | naked_product_series.branch = self.factory.makeBranch() | 304 | naked_product_series.branch = self.factory.makeBranch() |
991 | 305 | packagings = self.series.getPrioritizedlPackagings() | 305 | packagings = self.series.getPrioritizedPackagings() |
992 | 306 | names = [packaging.sourcepackagename.name for packaging in packagings] | 306 | names = [packaging.sourcepackagename.name for packaging in packagings] |
993 | 307 | expected = [u'translatable', u'linked', u'withbranch'] | 307 | expected = [u'translatable', u'linked', u'withbranch'] |
994 | 308 | self.assertEqual(expected, names) | 308 | self.assertEqual(expected, names) |
995 | 309 | 309 | ||
997 | 310 | def test_getPrioritizedlPackagings_translation(self): | 310 | def test_getPrioritizedPackagings_translation(self): |
998 | 311 | # Verify the ordering of translatable packagings that are and are not | 311 | # Verify the ordering of translatable packagings that are and are not |
999 | 312 | # configured to import. | 312 | # configured to import. |
1000 | 313 | self.linkPackage('translatable') | 313 | self.linkPackage('translatable') |
1001 | @@ -318,7 +318,7 @@ | |||
1002 | 318 | naked_product_series.branch = self.factory.makeBranch() | 318 | naked_product_series.branch = self.factory.makeBranch() |
1003 | 319 | naked_product_series.translations_autoimport_mode = ( | 319 | naked_product_series.translations_autoimport_mode = ( |
1004 | 320 | TranslationsBranchImportMode.IMPORT_TEMPLATES) | 320 | TranslationsBranchImportMode.IMPORT_TEMPLATES) |
1006 | 321 | packagings = self.series.getPrioritizedlPackagings() | 321 | packagings = self.series.getPrioritizedPackagings() |
1007 | 322 | names = [packaging.sourcepackagename.name for packaging in packagings] | 322 | names = [packaging.sourcepackagename.name for packaging in packagings] |
1008 | 323 | expected = [u'translatable', u'linked', u'importabletranslatable'] | 323 | expected = [u'translatable', u'linked', u'importabletranslatable'] |
1009 | 324 | self.assertEqual(expected, names) | 324 | self.assertEqual(expected, names) |
Nice, I'm looking forward to seeing this land!
One minor comment: lib/lp/ registry/ browser/ tests/test_ distroseries_ views.py mentions 2009 as the copyright year, that probably should be 2010..