Merge lp:~jtv/launchpad/bug-664327 into lp:launchpad

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 11780
Proposed branch: lp:~jtv/launchpad/bug-664327
Merge into: lp:launchpad
Diff against target: 178 lines (+67/-13)
4 files modified
lib/canonical/launchpad/interfaces/_schema_circular_imports.py (+9/-0)
lib/lp/translations/interfaces/translationimportqueue.py (+18/-4)
lib/lp/translations/model/translationimportqueue.py (+4/-4)
lib/lp/translations/stories/webservice/xx-translationimportqueue.txt (+36/-5)
To merge this branch: bzr merge lp:~jtv/launchpad/bug-664327
Reviewer Review Type Date Requested Status
Gavin Panella (community) code Approve
Review via email: mp+39036@code.launchpad.net

Commit message

API: IHasTranslationImports.getTranslationImportQueueEntries

Description of the change

= Bug 664327 =

David, the Ubuntu translations man, has asked us for this new bit of functionality on the web service API: "get the translations import queue for a specific distribution, distroseries, or source package." This will allow him to get more done without bothering us developers, and without us developers bothering the LOSAs. So it's all in a good cause.

We were already exporting a method that could do this: ITranslationsImportQueue.getAllEntries. But we decided against exporting the filter parameters to this method since they erode the naming: when you filter for a specific translation target, you're not getting "all" entries.

Instead, we chose to export a method that's already on the distribution, distroseries, source package etc. (and in an interface that's already exported for other reasons) called IHasTranslationImports.getTranslationImportQueueEntries.

A quick test verifies its presence on the API. To run it:
{{{
./bin/test -vvc lp.translations -t "webservice.*import"
}}}

For Q/A, it will be fun to explore some import queues for existing translation targets.

No lint,

Jeroen

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

Looks good, +1

[1]

+ @operation_parameters(
+ import_status=Choice(
+ title=_("Status"),
+ description=_("Show only entries with this status"),
+ values=RosettaImportStatus.items,
+ required=False),

I think you can use vocabulary=RosettaImportStatus instead of values.

[2]

+ >>> print target_queue['entries'][0]['path']
+ matching-entry.pot

Unless it's done elsewhere, it would be nice to document what is
returned by this method, rather than just a the path property of the
first entry.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/interfaces/_schema_circular_imports.py'
2--- lib/canonical/launchpad/interfaces/_schema_circular_imports.py 2010-10-18 06:14:10 +0000
3+++ lib/canonical/launchpad/interfaces/_schema_circular_imports.py 2010-10-22 04:26:21 +0000
4@@ -120,6 +120,10 @@
5 IPOTemplateSharingSubset,
6 IPOTemplateSubset,
7 )
8+from lp.translations.interfaces.translationimportqueue import (
9+ IHasTranslationImports,
10+ ITranslationImportQueueEntry,
11+ )
12
13
14 IBranch['bug_branches'].value_type.schema = IBugBranch
15@@ -437,6 +441,11 @@
16 # IBugWatch
17 patch_reference_property(IBugWatch, 'owner', IPerson)
18
19+# IHasTranslationImports
20+patch_collection_return_type(
21+ IHasTranslationImports, 'getTranslationImportQueueEntries',
22+ ITranslationImportQueueEntry)
23+
24 # IIndexedMessage
25 patch_reference_property(IIndexedMessage, 'inside', IBugTask)
26
27
28=== modified file 'lib/lp/translations/interfaces/translationimportqueue.py'
29--- lib/lp/translations/interfaces/translationimportqueue.py 2010-08-20 20:31:18 +0000
30+++ lib/lp/translations/interfaces/translationimportqueue.py 2010-10-22 04:26:21 +0000
31@@ -175,8 +175,8 @@
32 class IHasTranslationImports(Interface):
33 """An entity on which a translation import queue entry is attached.
34
35- Examples include an IProductSeries, ISourcePackage, IDistroSeries and
36- IPerson.
37+ Examples include ProductSeries, SourcePackage, DistroSeries, and
38+ Person.
39 """
40 export_as_webservice_entry(
41 singular_name='object_with_translation_imports',
42@@ -185,7 +185,21 @@
43 def getFirstEntryToImport():
44 """Return the first entry of the queue ready to be imported."""
45
46- def getTranslationImportQueueEntries(imports_status=None,
47+ @operation_parameters(
48+ import_status=Choice(
49+ title=_("Status"),
50+ description=_("Show only entries with this status"),
51+ vocabulary=RosettaImportStatus,
52+ required=False),
53+ file_extension=TextLine(
54+ title=_("Filename extension"),
55+ description=_("Show only entries with this filename suffix"),
56+ required=False))
57+ # Really ITranslationImportQueueEntry. Fixed up in
58+ # _schema_circular_imports.py.
59+ @operation_returns_collection_of(Interface)
60+ @export_read_operation()
61+ def getTranslationImportQueueEntries(import_status=None,
62 file_extension=None):
63 """Return entries in the translation import queue for this entity.
64
65@@ -273,7 +287,7 @@
66 status = exported(
67 Choice(
68 title=_("The status of the import."),
69- values=RosettaImportStatus.items,
70+ vocabulary=RosettaImportStatus,
71 required=True,
72 readonly=True))
73
74
75=== modified file 'lib/lp/translations/model/translationimportqueue.py'
76--- lib/lp/translations/model/translationimportqueue.py 2010-08-20 20:31:18 +0000
77+++ lib/lp/translations/model/translationimportqueue.py 2010-10-22 04:26:21 +0000
78@@ -1284,8 +1284,7 @@
79 importer = getUtility(ITranslationImporter)
80 template_patterns = "(%s)" % ' OR '.join([
81 "path LIKE ('%%' || %s)" % quote_like(suffix)
82- for suffix in importer.template_suffixes
83- ])
84+ for suffix in importer.template_suffixes])
85
86 store = self._getSlaveStore()
87 result = store.execute("""
88@@ -1445,6 +1444,7 @@
89 extensions = None
90 else:
91 extensions = [file_extension]
92- translation_import_queue = TranslationImportQueue()
93+ translation_import_queue = getUtility(ITranslationImportQueue)
94 return translation_import_queue.getAllEntries(
95- self, import_status=import_status, file_extensions=extensions)
96+ target=self, import_status=import_status,
97+ file_extensions=extensions)
98
99=== modified file 'lib/lp/translations/stories/webservice/xx-translationimportqueue.txt'
100--- lib/lp/translations/stories/webservice/xx-translationimportqueue.txt 2009-11-17 09:50:33 +0000
101+++ lib/lp/translations/stories/webservice/xx-translationimportqueue.txt 2010-10-22 04:26:21 +0000
102@@ -1,4 +1,5 @@
103-= Translation Import Queue =
104+Translation Import Queue
105+========================
106
107 The queue of uploaded translation files is quite large. It contains not
108 just files waiting to be imported, but also blocked or failed uploads,
109@@ -38,7 +39,8 @@
110 ... print_dict_entries(entry, shown_keys=shown_keys)
111
112
113-== Enumerating the queue ==
114+Enumerating the queue
115+---------------------
116
117 >>> queue = webservice.get("/+imports").jsonBody()
118 >>> queue['total_size']
119@@ -73,7 +75,8 @@
120 uploader_link http://.../~name16
121
122
123-== Entry fields ==
124+Entry fields
125+------------
126
127 Most of the fields in a translation import queue entry are immutable
128 from the web service's point of view.
129@@ -81,7 +84,8 @@
130 >>> from simplejson import dumps
131
132
133-=== Path ===
134+Path
135+....
136
137 An entry's file path can be changed by the entry's owner or an admin.
138
139@@ -103,7 +107,8 @@
140 ...
141
142
143-=== Status ===
144+Status
145+......
146
147 For now, it is not possible to set an entry's status through the API.
148
149@@ -134,3 +139,29 @@
150 HTTP/1.1 401 Unauthorized
151 ...
152
153+
154+Target-specific import queues
155+-----------------------------
156+
157+Objects that implement IHasTranslationImports (also known as "translation
158+targets") expose their specific sub-sets of the import queue through
159+getTranslationImportQueueEntries.
160+
161+In this example, a person:
162+
163+ >>> login(ANONYMOUS)
164+ >>> target = factory.makePerson()
165+ >>> target_url = '/~%s' % target.name
166+ >>> matching_entry = factory.makeTranslationImportQueueEntry(
167+ ... 'matching-entry.pot', uploader=target)
168+ >>> other_entry = factory.makeTranslationImportQueueEntry(
169+ ... 'other-entry.pot')
170+ >>> logout()
171+
172+ >>> target_queue = webservice.named_get(
173+ ... target_url, 'getTranslationImportQueueEntries').jsonBody()
174+ >>> print target_queue['total_size']
175+ 1
176+
177+ >>> print target_queue['entries'][0]['path']
178+ matching-entry.pot