Merge lp:~danilo/launchpad/no-dummy-psl into lp:launchpad

Proposed by Данило Шеган
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 11182
Proposed branch: lp:~danilo/launchpad/no-dummy-psl
Merge into: lp:launchpad
Diff against target: 409 lines (+61/-85)
7 files modified
lib/lp/translations/browser/productseries.py (+7/-7)
lib/lp/translations/browser/tests/test_breadcrumbs.py (+26/-12)
lib/lp/translations/configure.zcml (+1/-6)
lib/lp/translations/doc/canonical_url_examples.txt (+6/-5)
lib/lp/translations/interfaces/productserieslanguage.py (+2/-7)
lib/lp/translations/model/productserieslanguage.py (+12/-44)
lib/lp/translations/tests/test_productserieslanguage.py (+7/-4)
To merge this branch: bzr merge lp:~danilo/launchpad/no-dummy-psl
Reviewer Review Type Date Requested Status
Robert Collins (community) Approve
Review via email: mp+30293@code.launchpad.net

Commit message

Get rid of DummyProductSeriesLanguage.

Description of the change

= Get rid of dummy ProductSeriesLanguage =

When ProductSeriesLanguage was introduced, it was modelled after DistroSeriesLanguage. DistroSeriesLanguage is backed by persistent storage (it's an actual table in the DB), while ProductSeriesLanguage is only an in-memory object. As such, it is basically always a "dummy".

As part of reworking ISeriesLanguage interface to be more generic and re-usable, this is a refactoring branch that gets rid of the DummyProductSeriesLanguage and related methods.

= Tests =

bin/test -cvvt productserieslanguage

(we just confirm everything works as it used to: existing tests cover all the cases where we were using dummies, and the dummy_ProductSeriesLanguage test is explicit in unit-testing the "dummy" behaviour)

= QA =

https://translations.launchpad.dev/evolution/trunk/+lang/es (no-dummy version)
https://translations.launchpad.dev/evolution/trunk/+lang/sr (dummy version)

Both work in identical way to how they work today, but we've got less code for a net win.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/translations/configure.zcml
  lib/lp/translations/browser/productseries.py
  lib/lp/translations/browser/tests/test_breadcrumbs.py
  lib/lp/translations/doc/canonical_url_examples.txt
  lib/lp/translations/interfaces/productserieslanguage.py
  lib/lp/translations/model/productserieslanguage.py
  lib/lp/translations/tests/test_productserieslanguage.py

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) :
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/productseries.py'
2--- lib/lp/translations/browser/productseries.py 2010-06-17 03:29:53 +0000
3+++ lib/lp/translations/browser/productseries.py 2010-07-21 09:39:56 +0000
4@@ -344,9 +344,7 @@
5
6 Produces a list containing a ProductSeriesLanguage object for
7 each language this product has been translated into, and for each
8- of the user's preferred languages. Where the series has no
9- ProductSeriesLanguage for that language, we use a
10- DummyProductSeriesLanguage.
11+ of the user's preferred languages.
12 """
13
14 if self.context.potemplate_count == 0:
15@@ -369,11 +367,13 @@
16 pofile = pot.getPOFileByLang(lang.code)
17 if pofile is None:
18 pofile = pot.getDummyPOFile(lang.code)
19- productserieslang = productserieslangset.getDummy(
20- self.context, lang, pofile=pofile)
21+ productserieslang = (
22+ productserieslangset.getProductSeriesLanguage(
23+ self.context, lang, pofile=pofile))
24 else:
25- productserieslang = productserieslangset.getDummy(
26- self.context, lang)
27+ productserieslang = (
28+ productserieslangset.getProductSeriesLanguage(
29+ self.context, lang))
30 productserieslangs.append(
31 productserieslang)
32
33
34=== modified file 'lib/lp/translations/browser/tests/test_breadcrumbs.py'
35--- lib/lp/translations/browser/tests/test_breadcrumbs.py 2010-04-28 10:13:00 +0000
36+++ lib/lp/translations/browser/tests/test_breadcrumbs.py 2010-07-21 09:39:56 +0000
37@@ -23,7 +23,8 @@
38 name='crumb-tester', displayname="Crumb Tester")
39 self.assertBreadcrumbs(
40 [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
41- ("Translations", 'http://translations.launchpad.dev/crumb-tester')],
42+ ("Translations",
43+ 'http://translations.launchpad.dev/crumb-tester')],
44 product, rootsite='translations')
45
46 def test_productseries(self):
47@@ -33,7 +34,8 @@
48 self.assertBreadcrumbs(
49 [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
50 ("Series test", 'http://launchpad.dev/crumb-tester/test'),
51- ("Translations", 'http://translations.launchpad.dev/crumb-tester/test')],
52+ ("Translations",
53+ 'http://translations.launchpad.dev/crumb-tester/test')],
54 series, rootsite='translations')
55
56 def test_distribution(self):
57@@ -41,7 +43,8 @@
58 name='crumb-tester', displayname="Crumb Tester")
59 self.assertBreadcrumbs(
60 [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
61- ("Translations", 'http://translations.launchpad.dev/crumb-tester')],
62+ ("Translations",
63+ 'http://translations.launchpad.dev/crumb-tester')],
64 distribution, rootsite='translations')
65
66 def test_distroseries(self):
67@@ -52,7 +55,8 @@
68 self.assertBreadcrumbs(
69 [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
70 ("Test (1.0)", 'http://launchpad.dev/crumb-tester/test'),
71- ("Translations", 'http://translations.launchpad.dev/crumb-tester/test')],
72+ ("Translations",
73+ 'http://translations.launchpad.dev/crumb-tester/test')],
74 series, rootsite='translations')
75
76 def test_project(self):
77@@ -60,7 +64,8 @@
78 name='crumb-tester', displayname="Crumb Tester")
79 self.assertBreadcrumbs(
80 [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
81- ("Translations", 'http://translations.launchpad.dev/crumb-tester')],
82+ ("Translations",
83+ 'http://translations.launchpad.dev/crumb-tester')],
84 project, rootsite='translations')
85
86 def test_person(self):
87@@ -68,7 +73,8 @@
88 name='crumb-tester', displayname="Crumb Tester")
89 self.assertBreadcrumbs(
90 [("Crumb Tester", 'http://launchpad.dev/~crumb-tester'),
91- ("Translations", 'http://translations.launchpad.dev/~crumb-tester')],
92+ ("Translations",
93+ 'http://translations.launchpad.dev/~crumb-tester')],
94 person, rootsite='translations')
95
96
97@@ -77,14 +83,16 @@
98 def test_translationgroupset(self):
99 group_set = getUtility(ITranslationGroupSet)
100 self.assertBreadcrumbs(
101- [("Translation groups", 'http://translations.launchpad.dev/+groups')],
102+ [("Translation groups",
103+ 'http://translations.launchpad.dev/+groups')],
104 group_set, rootsite='translations')
105
106 def test_translationgroup(self):
107 group = self.factory.makeTranslationGroup(
108 name='test-translators', title='Test translators')
109 self.assertBreadcrumbs(
110- [("Translation groups", 'http://translations.launchpad.dev/+groups'),
111+ [("Translation groups",
112+ 'http://translations.launchpad.dev/+groups'),
113 ("Test translators",
114 'http://translations.launchpad.dev/+groups/test-translators')],
115 group, rootsite='translations')
116@@ -111,7 +119,8 @@
117 ("Translations",
118 "http://translations.launchpad.dev/crumb-tester/test"),
119 ("Serbian (sr)",
120- "http://translations.launchpad.dev/crumb-tester/test/+lang/sr")],
121+ "http://translations.launchpad.dev/"
122+ "crumb-tester/test/+lang/sr")],
123 serieslanguage)
124
125 def test_productserieslanguage(self):
126@@ -119,7 +128,8 @@
127 name='crumb-tester', displayname="Crumb Tester")
128 series = self.factory.makeProductSeries(
129 name="test", product=product)
130- serieslanguage = getUtility(IProductSeriesLanguageSet).getDummy(
131+ psl_set = getUtility(IProductSeriesLanguageSet)
132+ serieslanguage = psl_set.getProductSeriesLanguage(
133 series, self.language)
134
135 self.assertBreadcrumbs(
136@@ -128,11 +138,14 @@
137 ("Translations",
138 "http://translations.launchpad.dev/crumb-tester/test"),
139 ("Serbian (sr)",
140- "http://translations.launchpad.dev/crumb-tester/test/+lang/sr")],
141+ "http://translations.launchpad.dev/"
142+ "crumb-tester/test/+lang/sr")],
143 serieslanguage)
144
145
146 class TestPOTemplateBreadcrumbs(BaseBreadcrumbTestCase):
147+ """Test POTemplate breadcrumbs."""
148+
149 def test_potemplate(self):
150 product = self.factory.makeProduct(
151 name='crumb-tester', displayname="Crumb Tester",
152@@ -147,7 +160,8 @@
153 ("Translations",
154 "http://translations.launchpad.dev/crumb-tester/test"),
155 (smartquote('Template "template"'),
156- "http://translations.launchpad.dev/crumb-tester/test/+pots/template")],
157+ "http://translations.launchpad.dev/"
158+ "crumb-tester/test/+pots/template")],
159 potemplate)
160
161
162
163=== modified file 'lib/lp/translations/configure.zcml'
164--- lib/lp/translations/configure.zcml 2010-05-04 13:42:25 +0000
165+++ lib/lp/translations/configure.zcml 2010-07-21 09:39:56 +0000
166@@ -372,7 +372,7 @@
167 interface="lp.translations.interfaces.translationtemplateitem.ITranslationTemplateItem"/>
168 </class>
169
170- <!-- ProductSeriesLanguage and Dummy -->
171+ <!-- ProductSeriesLanguage -->
172
173 <adapter
174 provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"
175@@ -385,11 +385,6 @@
176 <allow
177 interface="lp.translations.interfaces.productserieslanguage.IProductSeriesLanguage"/>
178 </class>
179- <class
180- class="lp.translations.model.productserieslanguage.DummyProductSeriesLanguage">
181- <allow
182- interface="lp.translations.interfaces.productserieslanguage.IProductSeriesLanguage"/>
183- </class>
184
185 <!-- ProductSeriesLanguageSet -->
186
187
188=== modified file 'lib/lp/translations/doc/canonical_url_examples.txt'
189--- lib/lp/translations/doc/canonical_url_examples.txt 2009-09-17 16:22:32 +0000
190+++ lib/lp/translations/doc/canonical_url_examples.txt 2010-07-21 09:39:56 +0000
191@@ -50,13 +50,13 @@
192
193 >>> potemplate = potemplatesubset['evolution-2.2']
194 >>> canonical_url(potemplate)
195- u'http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2'
196+ u'http://translations.../hoary/+source/evolution/+pots/evolution-2.2'
197
198 And we can get a particular PO file for this PO template by its language code.
199
200 >>> pofile = potemplate.getPOFileByLang('es')
201 >>> canonical_url(pofile)
202- u'http://translations.../ubuntu/hoary/+source/evolution/+pots/evolution-2.2/es'
203+ u'http://translations.../hoary/+source/evolution/+pots/evolution-2.2/es'
204
205 Also, we can get the url to a translation message.
206
207@@ -65,7 +65,7 @@
208 ... pofile.potemplate, pofile.language)
209 >>> translationmessage.setPOFile(pofile)
210 >>> print canonical_url(translationmessage)
211- http://translations.../ubuntu/hoary/+source/evolution/+pots/evolution-2.2/es/1
212+ http://transl.../hoary/+source/evolution/+pots/evolution-2.2/es/1
213
214 Even for a dummy one.
215
216@@ -73,7 +73,7 @@
217 >>> translationmessage = potmsgset.getCurrentDummyTranslationMessage(
218 ... pofile.potemplate, pofile.language)
219 >>> print canonical_url(translationmessage)
220- http://translations.../ubuntu/hoary/+source/evolution/+pots/evolution-2.2/es/20
221+ http://transl.../hoary/+source/evolution/+pots/evolution-2.2/es/20
222
223 Upstream POTemplateSubsets work in much the same way, except they hang off a
224 product series. Let's get a product series.
225@@ -173,7 +173,8 @@
226 >>> from lp.translations.interfaces.productserieslanguage import (
227 ... IProductSeriesLanguageSet)
228
229- >>> coo_cah_serbian = getUtility(IProductSeriesLanguageSet).getDummy(
230+ >>> psl_set = getUtility(IProductSeriesLanguageSet)
231+ >>> coo_cah_serbian = psl_set.getProductSeriesLanguage(
232 ... productseries, serbian)
233 >>> canonical_url(coo_cah_serbian)
234 u'http://translations.launchpad.dev/coo/cah/+lang/sr'
235
236=== modified file 'lib/lp/translations/interfaces/productserieslanguage.py'
237--- lib/lp/translations/interfaces/productserieslanguage.py 2009-10-30 19:38:18 +0000
238+++ lib/lp/translations/interfaces/productserieslanguage.py 2010-07-21 09:39:56 +0000
239@@ -49,7 +49,6 @@
240 last_changed_date = Datetime(
241 title=_('When this file was last changed.'))
242
243-
244 def getPOFilesFor(potemplates):
245 """Return `POFiles` for each of `potemplates`, in the same order.
246
247@@ -67,10 +66,6 @@
248 class IProductSeriesLanguageSet(Interface):
249 """The set of productserieslanguages."""
250
251- def getDummy(productseries, language, variant=None):
252- """Return a new DummyProductSeriesLanguage for the given
253- productseries and language.
254- """
255-
256- def getProductSeriesLanguage(productseries, language, variant=None):
257+ def getProductSeriesLanguage(productseries, language, variant=None,
258+ pofile=None):
259 """Return a PSL for a productseries and a language."""
260
261=== modified file 'lib/lp/translations/model/productserieslanguage.py'
262--- lib/lp/translations/model/productserieslanguage.py 2009-10-30 19:39:58 +0000
263+++ lib/lp/translations/model/productserieslanguage.py 2010-07-21 09:39:56 +0000
264@@ -6,18 +6,17 @@
265 __metaclass__ = type
266
267 __all__ = [
268- 'DummyProductSeriesLanguage',
269 'ProductSeriesLanguage',
270 'ProductSeriesLanguageSet',
271 ]
272
273 from zope.interface import implements
274
275-from storm.expr import Sum
276+from storm.expr import Coalesce, Sum
277 from storm.store import Store
278
279 from lp.translations.utilities.rosettastats import RosettaStats
280-from lp.translations.model.pofile import DummyPOFile, POFile
281+from lp.translations.model.pofile import POFile
282 from lp.translations.model.potemplate import get_pofiles_for, POTemplate
283 from lp.translations.interfaces.productserieslanguage import (
284 IProductSeriesLanguage, IProductSeriesLanguageSet)
285@@ -41,8 +40,8 @@
286 # Reset all cached counts.
287 self.setCounts()
288
289- def setCounts(self, total=None, imported=None, changed=None, new=None,
290- unreviewed=None, last_changed=None):
291+ def setCounts(self, total=0, imported=0, changed=0, new=0,
292+ unreviewed=0, last_changed=None):
293 """See `IProductSeriesLanguage`."""
294 self._messagecount = total
295 # "currentcount" in RosettaStats conflicts our recent terminology
296@@ -55,7 +54,6 @@
297 if last_changed is not None:
298 self._last_changed_date = last_changed
299
300-
301 def _getMessageCount(self):
302 store = Store.of(self.language)
303 query = store.find(Sum(POTemplate.messagecount),
304@@ -70,20 +68,16 @@
305 """See `IProductSeriesLanguage`."""
306 store = Store.of(self.language)
307 query = store.find(
308- (Sum(POFile.currentcount),
309- Sum(POFile.updatescount),
310- Sum(POFile.rosettacount),
311- Sum(POFile.unreviewed_count)),
312+ (Coalesce(Sum(POFile.currentcount), 0),
313+ Coalesce(Sum(POFile.updatescount), 0),
314+ Coalesce(Sum(POFile.rosettacount), 0),
315+ Coalesce(Sum(POFile.unreviewed_count), 0)),
316 POFile.language==self.language,
317 POFile.variant==None,
318 POFile.potemplate==POTemplate.id,
319 POTemplate.productseries==self.productseries,
320 POTemplate.iscurrent==True)
321 imported, changed, new, unreviewed = query[0]
322- if (imported is None or changed is None or
323- new is None or unreviewed is None):
324- # Set all counts to zero.
325- imported = changed = new = unreviewed = 0
326 self.setCounts(self._getMessageCount(), imported, changed,
327 new, unreviewed)
328
329@@ -138,40 +132,14 @@
330 return get_pofiles_for(potemplates, self.language, self.variant)
331
332
333-class DummyProductSeriesLanguage(ProductSeriesLanguage):
334- """See `IProductSeriesLanguage`.
335-
336- Implementation of IProductSeriesLanguage for a language with no
337- translations.
338- """
339- implements(IProductSeriesLanguage)
340-
341- def __init__(self, productseries, language, variant=None, pofile=None):
342- ProductSeriesLanguage.__init__(
343- self, productseries, language, variant, pofile)
344- self.setCounts(self._getMessageCount(), 0, 0, 0, 0)
345-
346- def getPOFilesFor(self, potemplates):
347- """See `IProductSeriesLanguage`."""
348- return [
349- DummyPOFile(template, self.language, self.variant)
350- for template in potemplates
351- ]
352-
353-
354 class ProductSeriesLanguageSet:
355 """See `IProductSeriesLanguageSet`.
356
357- Provides a means to get a ProductSeriesLanguage or create a dummy.
358+ Provides a means to get a ProductSeriesLanguage.
359 """
360 implements(IProductSeriesLanguageSet)
361
362 def getProductSeriesLanguage(self, productseries, language,
363- variant=None):
364- """See `IProductSeriesLanguageSet`."""
365- return ProductSeriesLanguage(productseries, language, variant)
366-
367- def getDummy(self, productseries, language, variant=None, pofile=None):
368- """See `IProductSeriesLanguageSet`."""
369- return DummyProductSeriesLanguage(
370- productseries, language, variant, pofile)
371+ variant=None, pofile=None):
372+ """See `IProductSeriesLanguageSet`."""
373+ return ProductSeriesLanguage(productseries, language, variant, pofile)
374
375=== modified file 'lib/lp/translations/tests/test_productserieslanguage.py'
376--- lib/lp/translations/tests/test_productserieslanguage.py 2009-11-04 17:15:56 +0000
377+++ lib/lp/translations/tests/test_productserieslanguage.py 2010-07-21 09:39:56 +0000
378@@ -143,16 +143,19 @@
379 psl.last_changed_date),
380 stats)
381
382- def test_DummyProductSeriesLanguage(self):
383+ def test_dummy_ProductSeriesLanguage(self):
384 # With no templates all counts are zero.
385- psl = self.psl_set.getDummy(self.productseries, self.language)
386+ psl = self.psl_set.getProductSeriesLanguage(
387+ self.productseries, self.language)
388 self.failUnless(verifyObject(IProductSeriesLanguage, psl))
389 self.assertPSLStatistics(psl, (0, 0, 0, 0, 0, 0, None))
390
391 # Adding a single template with 10 messages makes the total
392 # count of messages go up to 10.
393 potemplate = self.createPOTemplateWithPOTMsgSets(10)
394- psl = self.psl_set.getDummy(self.productseries, self.language)
395+ psl = self.psl_set.getProductSeriesLanguage(
396+ self.productseries, self.language)
397+ psl.recalculateCounts()
398 self.assertPSLStatistics(
399 psl, (10, 0, 0, 0, 0, 0, None))
400
401@@ -168,7 +171,7 @@
402 # Getting PSL through PSLSet gives an uninitialized object.
403 psl = self.psl_set.getProductSeriesLanguage(
404 self.productseries, self.language)
405- self.assertEquals(psl.messageCount(), None)
406+ self.assertEquals(psl.messageCount(), 0)
407
408 # So, we need to get it through productseries.productserieslanguages.
409 psl = self.productseries.productserieslanguages[0]