Merge lp:~jcsackett/launchpad/filter-in-getRequestTargets into lp:launchpad

Proposed by j.c.sackett on 2012-11-21
Status: Merged
Approved by: j.c.sackett on 2012-11-21
Approved revision: no longer in the source branch.
Merged at revision: 16304
Proposed branch: lp:~jcsackett/launchpad/filter-in-getRequestTargets
Merge into: lp:launchpad
Diff against target: 192 lines (+38/-14)
6 files modified
lib/lp/translations/browser/translationimportqueue.py (+7/-2)
lib/lp/translations/doc/translationimportqueue.txt (+2/-1)
lib/lp/translations/interfaces/translationimportqueue.py (+2/-1)
lib/lp/translations/model/translationimportqueue.py (+8/-5)
lib/lp/translations/scripts/po_import.py (+1/-1)
lib/lp/translations/tests/test_translationimportqueue.py (+18/-4)
To merge this branch: bzr merge lp:~jcsackett/launchpad/filter-in-getRequestTargets
Reviewer Review Type Date Requested Status
Aaron Bentley (community) 2012-11-21 Approve on 2012-11-21
Review via email: mp+135457@code.launchpad.net

Commit Message

Adds private product filtering to getRequestTargets in the translations import queue.

Description of the Change

Summary
=======
The import queue isn't aware of private products, because the function driving
it, get_product_request_targets, is unaware. That function should be updated
to use the privacy filter provided by ProductSet.

Preimp
======
Spoke with Rick Harding about alternatives to ILaunchBag use.

Implementation
==============
getRequestTargets is updated to take a user argument, which it passes to
get_product_request_targets. The view provides this to the call.

get_product_request_targets is updated to get the privacy filter clause from
ProductSet.getProductPrivacyFilter, using the supplied user.

The interface is updated to include the new user argument, and supply the
REQUEST_USER as the argument for the API export.

Tests
=====
bin/test -vvct test_list_product_request_filters_private_products

QA
==
Ensure private products do not appear in the import queue.

LoC
===
Part of private projects.

Lint
====

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/translations/model/translationimportqueue.py
  lib/lp/translations/browser/translationimportqueue.py
  lib/lp/translations/tests/test_translationimportqueue.py
  lib/lp/translations/interfaces/translationimportqueue.py

To post a comment you must log in.
Aaron Bentley (abentley) wrote :

In getRequestTargets and list_product_request_targets, having the user default to None means that calling code can accidentally omit it. I think it should be a non-optional parameter, even though this means changing parameter order.

Other than that, this looks good to land.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/translations/browser/translationimportqueue.py'
2--- lib/lp/translations/browser/translationimportqueue.py 2011-12-30 06:14:56 +0000
3+++ lib/lp/translations/browser/translationimportqueue.py 2012-11-21 23:48:21 +0000
4@@ -617,7 +617,11 @@
5
6 def __call__(self, context):
7 import_queue = getUtility(ITranslationImportQueue)
8- targets = import_queue.getRequestTargets()
9+ if hasattr(self, 'view'):
10+ user = self.view.user
11+ else:
12+ user = None
13+ targets = import_queue.getRequestTargets(user)
14 filtered_targets = set()
15
16 # Read filter_status, in order to mark targets that have requests with
17@@ -634,7 +638,8 @@
18 try:
19 status = RosettaImportStatus.items[status_filter]
20 filtered_targets = set(
21- import_queue.getRequestTargets(status))
22+ import_queue.getRequestTargets(
23+ user=None, status=status))
24 except LookupError:
25 # Unknown status. Ignore.
26 pass
27
28=== modified file 'lib/lp/translations/doc/translationimportqueue.txt'
29--- lib/lp/translations/doc/translationimportqueue.txt 2011-12-30 06:14:56 +0000
30+++ lib/lp/translations/doc/translationimportqueue.txt 2012-11-21 23:48:21 +0000
31@@ -22,7 +22,8 @@
32 >>> def get_target_names(status=None):
33 ... """Call getRequestTargets, return list of names/titles."""
34 ... result = []
35- ... queue = translationimportqueue.getRequestTargets(status)
36+ ... queue = translationimportqueue.getRequestTargets(
37+ ... user=None,status=status)
38 ... for object in queue:
39 ... if IDistroSeries.providedBy(object):
40 ... name = "%s/%s" % (object.distribution.name, object.name)
41
42=== modified file 'lib/lp/translations/interfaces/translationimportqueue.py'
43--- lib/lp/translations/interfaces/translationimportqueue.py 2011-12-24 16:54:44 +0000
44+++ lib/lp/translations/interfaces/translationimportqueue.py 2012-11-21 23:48:21 +0000
45@@ -400,7 +400,8 @@
46 @operation_parameters(
47 status=copy_field(ITranslationImportQueueEntry['status']))
48 @operation_returns_collection_of(IHasTranslationImports)
49- def getRequestTargets(status=None):
50+ @call_with(user=REQUEST_USER)
51+ def getRequestTargets(user, status=None):
52 """List `Product`s and `DistroSeries` with pending imports.
53
54 :arg status: Filter by `RosettaImportStatus`.
55
56=== modified file 'lib/lp/translations/model/translationimportqueue.py'
57--- lib/lp/translations/model/translationimportqueue.py 2011-12-30 06:14:56 +0000
58+++ lib/lp/translations/model/translationimportqueue.py 2012-11-21 23:48:21 +0000
59@@ -848,7 +848,7 @@
60 return elapsedtime_text
61
62
63-def list_product_request_targets(status_condition):
64+def list_product_request_targets(user, status_condition):
65 """Return list of Products with import queue entries.
66
67 :param status_condition: Storm conditional restricting the
68@@ -856,9 +856,11 @@
69 :return: A list of `Product`, distinct and ordered by name.
70 """
71 # Avoid circular imports.
72- from lp.registry.model.product import Product
73+ from lp.registry.model.product import Product, ProductSet
74 from lp.registry.model.productseries import ProductSeries
75
76+ privacy_filter = ProductSet.getProductPrivacyFilter(user)
77+
78 products = IStore(Product).find(
79 Product,
80 Product.id == ProductSeries.productID,
81@@ -868,7 +870,8 @@
82 And(
83 TranslationImportQueueEntry.productseries_id != None,
84 status_condition),
85- distinct=True)))
86+ distinct=True)),
87+ privacy_filter)
88
89 # Products may occur multiple times due to the join with
90 # ProductSeries.
91@@ -1281,7 +1284,7 @@
92 " AND ".join(queries), clauseTables=clause_tables,
93 orderBy=['dateimported'])
94
95- def getRequestTargets(self, status=None):
96+ def getRequestTargets(self, user, status=None):
97 """See `ITranslationImportQueue`."""
98
99 if status is None:
100@@ -1290,7 +1293,7 @@
101 status_clause = (TranslationImportQueueEntry.status == status)
102
103 distroseries = list_distroseries_request_targets(status_clause)
104- products = list_product_request_targets(status_clause)
105+ products = list_product_request_targets(user, status_clause)
106
107 return distroseries + products
108
109
110=== modified file 'lib/lp/translations/scripts/po_import.py'
111--- lib/lp/translations/scripts/po_import.py 2012-06-29 08:40:05 +0000
112+++ lib/lp/translations/scripts/po_import.py 2012-11-21 23:48:21 +0000
113@@ -163,7 +163,7 @@
114 # We'll serve these queues in turn, one request each, until either the
115 # queue is drained or our time is up.
116 importqueues = translation_import_queue.getRequestTargets(
117- RosettaImportStatus.APPROVED)
118+ user=None, status=RosettaImportStatus.APPROVED)
119
120 if not importqueues:
121 self.logger.info("No requests pending.")
122
123=== modified file 'lib/lp/translations/tests/test_translationimportqueue.py'
124--- lib/lp/translations/tests/test_translationimportqueue.py 2012-01-20 15:42:44 +0000
125+++ lib/lp/translations/tests/test_translationimportqueue.py 2012-11-21 23:48:21 +0000
126@@ -10,6 +10,7 @@
127 from zope.component import getUtility
128 from zope.security.proxy import removeSecurityProxy
129
130+from lp.app.enums import InformationType
131 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
132 from lp.services.database.lpstorm import (
133 ISlaveStore,
134@@ -571,14 +572,25 @@
135 sorted(names),
136 [
137 product.name
138- for product in list_product_request_targets(True)])
139+ for product in list_product_request_targets(None, True)])
140+
141+ def test_list_product_request_filters_private_products(self):
142+ self.clearQueue()
143+ self.useFixture(FakeLibrarian())
144+ owner = self.factory.makePerson()
145+ product = self.factory.makeProduct(owner=owner,
146+ information_type=InformationType.PROPRIETARY)
147+ self.factory.makeTranslationImportQueueEntry(
148+ productseries=self.factory.makeProductSeries(product=product))
149+ self.assertEqual([], list_product_request_targets(None, True))
150+ self.assertEqual([product], list_product_request_targets(owner, True))
151
152 def test_list_product_request_targets_ignores_distro_uploads(self):
153 self.clearQueue()
154 self.useFixture(FakeLibrarian())
155 self.factory.makeTranslationImportQueueEntry(
156 distroseries=self.factory.makeDistroSeries())
157- self.assertEqual([], list_product_request_targets(True))
158+ self.assertEqual([], list_product_request_targets(None, True))
159
160 def test_list_product_request_targets_ignores_inactive_products(self):
161 self.clearQueue()
162@@ -587,7 +599,7 @@
163 product.active = False
164 self.factory.makeTranslationImportQueueEntry(
165 productseries=self.factory.makeProductSeries(product=product))
166- self.assertEqual([], list_product_request_targets(False))
167+ self.assertEqual([], list_product_request_targets(None, False))
168
169 def test_list_product_request_targets_does_not_duplicate(self):
170 # list_product_request_targets will list a product only once.
171@@ -601,7 +613,7 @@
172 for counter in range(2):
173 self.factory.makeTranslationImportQueueEntry(
174 productseries=series)
175- self.assertEqual([product], list_product_request_targets(True))
176+ self.assertEqual([product], list_product_request_targets(None, True))
177
178 def test_list_product_request_targets_filters_status(self):
179 self.clearQueue()
180@@ -614,10 +626,12 @@
181 self.assertEqual(
182 [],
183 list_product_request_targets(
184+ None,
185 TranslationImportQueueEntry.status == other_status))
186 self.assertEqual(
187 [entry.productseries.product],
188 list_product_request_targets(
189+ None,
190 TranslationImportQueueEntry.status == entry_status))
191
192 def test_list_distroseries_request_targets_orders_by_names(self):