Merge ~cjwatson/launchpad:stormify-translations-queries into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: fe326b3b9c807e9d722aa179cf1c9036a4bc43b6
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:stormify-translations-queries
Merge into: launchpad:master
Prerequisite: ~cjwatson/launchpad:stormify-potranslation
Diff against target: 639 lines (+131/-117)
18 files modified
lib/lp/registry/model/distroseries.py (+3/-1)
lib/lp/translations/doc/poexport-request-productseries.txt (+9/-10)
lib/lp/translations/doc/poexport-request.txt (+4/-2)
lib/lp/translations/doc/pofile.txt (+2/-4)
lib/lp/translations/doc/potmsgset.txt (+4/-10)
lib/lp/translations/doc/translationmessage-destroy.txt (+5/-4)
lib/lp/translations/doc/translationrelicensingagreement.txt (+7/-3)
lib/lp/translations/interfaces/translationmessage.py (+0/-11)
lib/lp/translations/model/pofiletranslator.py (+31/-15)
lib/lp/translations/model/potemplate.py (+6/-5)
lib/lp/translations/model/translationgroup.py (+12/-9)
lib/lp/translations/model/translationmessage.py (+0/-4)
lib/lp/translations/model/translationsperson.py (+12/-11)
lib/lp/translations/scripts/fix_plural_forms.py (+8/-9)
lib/lp/translations/scripts/gettext_check_messages.py (+8/-6)
lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt (+5/-5)
lib/lp/translations/stories/standalone/xx-potemplate-admin.txt (+4/-2)
lib/lp/translations/stories/standalone/xx-translation-access-display.txt (+11/-6)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+395062@code.launchpad.net

Commit message

Convert SQLObject-style queries in lp.translations to Storm

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) wrote :

looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
2index 2811a42..e83a7dc 100644
3--- a/lib/lp/registry/model/distroseries.py
4+++ b/lib/lp/registry/model/distroseries.py
5@@ -178,7 +178,6 @@ from lp.translations.model.hastranslationtemplates import (
6 )
7 from lp.translations.model.languagepack import LanguagePack
8 from lp.translations.model.pofile import POFile
9-from lp.translations.model.pofiletranslator import POFileTranslator
10 from lp.translations.model.potemplate import (
11 POTemplate,
12 TranslationTemplatesCollection,
13@@ -1362,6 +1361,9 @@ class DistroSeries(SQLBase, BugTargetBase, HasSpecificationsMixin,
14
15 def getPOFileContributorsByLanguage(self, language):
16 """See `IDistroSeries`."""
17+ # Circular import.
18+ from lp.translations.model.pofiletranslator import POFileTranslator
19+
20 contributors = IStore(Person).find(
21 Person,
22 POFileTranslator.personID == Person.id,
23diff --git a/lib/lp/translations/doc/poexport-request-productseries.txt b/lib/lp/translations/doc/poexport-request-productseries.txt
24index 1978e3e..53303a2 100644
25--- a/lib/lp/translations/doc/poexport-request-productseries.txt
26+++ b/lib/lp/translations/doc/poexport-request-productseries.txt
27@@ -7,9 +7,9 @@
28
29 This is a dummy logger class to capture the export's log messages.
30
31- >>> from lp.registry.model.person import Person
32+ >>> from lp.registry.interfaces.person import IPersonSet
33 >>> from lp.services.log.logger import FakeLogger
34- >>> person = Person.selectOneBy(name='name12')
35+ >>> person = getUtility(IPersonSet).getByName('name12')
36
37 An arbitrary logged-in user requests an export of all translations for
38 Evolution series trunk.
39@@ -18,16 +18,15 @@ At the UI level, this is easy. At the level we are looking at now, this
40 consists of a series of requests for all templates and translations attached
41 to the product series.
42
43- >>> from lp.registry.model.product import Product
44- >>> from lp.registry.model.productseries import ProductSeries
45- >>> from lp.translations.model.potemplate import POTemplate
46- >>> evolution_product = Product.selectOneBy(name='evolution')
47- >>> evolution_trunk = ProductSeries.selectOneBy(
48- ... product=evolution_product, name='trunk')
49- >>> potemplates = list(POTemplate.selectBy(productseries=evolution_trunk))
50+ >>> from lp.registry.interfaces.product import IProductSet
51+ >>> from lp.translations.interfaces.potemplate import IPOTemplateSet
52+ >>> evolution_product = getUtility(IProductSet).getByName('evolution')
53+ >>> evolution_trunk = evolution_product.getSeries('trunk')
54+ >>> potemplates = list(getUtility(IPOTemplateSet).getSubset(
55+ ... productseries=evolution_trunk))
56 >>> pofiles = []
57 >>> for template in potemplates:
58- ... pofiles += template.pofiles
59+ ... pofiles.extend(template.pofiles)
60
61 >>> request_set = getUtility(IPOExportRequestSet)
62 >>> request_set.addRequest(person, potemplates, pofiles)
63diff --git a/lib/lp/translations/doc/poexport-request.txt b/lib/lp/translations/doc/poexport-request.txt
64index cf6d13f..8e87314 100644
65--- a/lib/lp/translations/doc/poexport-request.txt
66+++ b/lib/lp/translations/doc/poexport-request.txt
67@@ -233,9 +233,11 @@ just PO files.
68 >>> product_template.productseries is None
69 False
70 >>> request_set.addRequest(person, product_template)
71- >>> alsa_template = POTemplate.selectOneBy(path='po/alsa-utils.pot')
72+ >>> alsa_template = IStore(POTemplate).find(
73+ ... POTemplate, path='po/alsa-utils.pot').one()
74 >>> alsa_es = alsa_template.getPOFileByLang('es')
75- >>> netapplet_template = POTemplate.selectOneBy(path='po/netapplet.pot')
76+ >>> netapplet_template = IStore(POTemplate).find(
77+ ... POTemplate, path='po/netapplet.pot').one()
78 >>> request_set.addRequest(
79 ... person, [alsa_template, netapplet_template], [alsa_es])
80 >>> transaction.commit()
81diff --git a/lib/lp/translations/doc/pofile.txt b/lib/lp/translations/doc/pofile.txt
82index 9caf91d..286080b 100644
83--- a/lib/lp/translations/doc/pofile.txt
84+++ b/lib/lp/translations/doc/pofile.txt
85@@ -611,10 +611,8 @@ If you have a distroseries and want to know all the people who
86 contributed translations on a given language for that distroseries, you
87 can use the getPOFileContributorsByLanguage() method of IDistroSeries.
88
89- >>> from lp.registry.model.distroseries import DistroSeries
90- >>> from lp.services.worlddata.model.language import Language
91- >>> hoary = DistroSeries.selectOneBy(name="hoary")
92- >>> spanish = Language.selectOneBy(code="es")
93+ >>> hoary = distribution.getSeries("hoary")
94+ >>> spanish = getUtility(ILanguageSet)["es"]
95 >>> print_names(hoary.getPOFileContributorsByLanguage(spanish))
96 jorge-gonzalez-gonzalez
97 carlos
98diff --git a/lib/lp/translations/doc/potmsgset.txt b/lib/lp/translations/doc/potmsgset.txt
99index ade9470..d07038c 100644
100--- a/lib/lp/translations/doc/potmsgset.txt
101+++ b/lib/lp/translations/doc/potmsgset.txt
102@@ -612,20 +612,14 @@ POTMsgSet.setSequence
103 Finally, the new `IPOTMsgSet` should have an entry in the
104 `TranslationTemplateItem` table once we assign a sequence number.
105
106- >>> from lp.translations.model.translationtemplateitem import (
107- ... TranslationTemplateItem)
108-
109 First, we need a helper function to check whether the potmsgset exists
110 in the table or not.
111
112-
113 >>> def is_potmsgset_in_potemplate(potmsgset, potemplate):
114- ... items = [
115- ... item.potmsgset.id
116- ... for item in TranslationTemplateItem.selectBy(
117- ... potemplate=potemplate, potmsgset=potmsgset)
118- ... if item.sequence > 0
119- ... ]
120+ ... items = {
121+ ... potmsgset.id
122+ ... for potmsgset in potemplate.getPOTMsgSets(prefetch=False)
123+ ... }
124 ... return potmsgset.id in items
125
126 Let's create a new potmsgset object.
127diff --git a/lib/lp/translations/doc/translationmessage-destroy.txt b/lib/lp/translations/doc/translationmessage-destroy.txt
128index 8b52fcf..6709859 100644
129--- a/lib/lp/translations/doc/translationmessage-destroy.txt
130+++ b/lib/lp/translations/doc/translationmessage-destroy.txt
131@@ -36,7 +36,7 @@ translation, we get two POFileTranslator records for each of the POFiles.
132 # We need to be able to create persons and projects so let's just use
133 # a global 'postgres' permission which allows everything.
134 >>> switch_dbuser('postgres')
135- >>> from lp.services.database.sqlbase import sqlvalues
136+ >>> from lp.services.database.interfaces import IStore
137 >>> from lp.app.enums import ServiceUsage
138 >>> from lp.testing.factory import LaunchpadObjectFactory
139 >>> from lp.translations.model.pofiletranslator import POFileTranslator
140@@ -62,7 +62,8 @@ translation, we get two POFileTranslator records for each of the POFiles.
141 ... pofile=devel_sr_pofile,
142 ... potmsgset=potmsgset,
143 ... translations=[u"blah"])
144- >>> print(POFileTranslator.select(
145- ... "pofile IN (%s, %s)"
146- ... % sqlvalues(devel_sr_pofile, stable_sr_pofile)).count())
147+ >>> print(IStore(POFileTranslator).find(
148+ ... POFileTranslator,
149+ ... POFileTranslator.pofileID.is_in(
150+ ... (devel_sr_pofile.id, stable_sr_pofile.id))).count())
151 2
152diff --git a/lib/lp/translations/doc/translationrelicensingagreement.txt b/lib/lp/translations/doc/translationrelicensingagreement.txt
153index ad6156d..c40f41b 100644
154--- a/lib/lp/translations/doc/translationrelicensingagreement.txt
155+++ b/lib/lp/translations/doc/translationrelicensingagreement.txt
156@@ -5,6 +5,7 @@ Launchpad can decide whether they want their translations relicensed
157 under BSD or not.
158
159 >>> from zope.component import getUtility
160+ >>> from lp.services.database.interfaces import IStore
161 >>> from lp.testing import verifyObject
162 >>> from lp.translations.model.translationrelicensingagreement \
163 ... import TranslationRelicensingAgreement
164@@ -23,7 +24,8 @@ When Karl has not made his selection yet, it is marked as None.
165
166 >>> print(translations_person.translations_relicensing_agreement)
167 None
168- >>> choice = TranslationRelicensingAgreement.selectOneBy(person=person)
169+ >>> choice = IStore(TranslationRelicensingAgreement).find(
170+ ... TranslationRelicensingAgreement, person=person).one()
171 >>> print(choice)
172 None
173
174@@ -33,7 +35,8 @@ object.
175 >>> translations_person.translations_relicensing_agreement = True
176 >>> print(translations_person.translations_relicensing_agreement)
177 True
178- >>> choice = TranslationRelicensingAgreement.selectOneBy(person=person)
179+ >>> choice = IStore(TranslationRelicensingAgreement).find(
180+ ... TranslationRelicensingAgreement, person=person).one()
181 >>> print(choice.allow_relicensing)
182 True
183
184@@ -47,6 +50,7 @@ A translator can also change their mind later.
185 >>> translations_person.translations_relicensing_agreement = False
186 >>> print(translations_person.translations_relicensing_agreement)
187 False
188- >>> choice = TranslationRelicensingAgreement.selectOneBy(person=person)
189+ >>> choice = IStore(TranslationRelicensingAgreement).find(
190+ ... TranslationRelicensingAgreement, person=person).one()
191 >>> print(choice.allow_relicensing)
192 False
193diff --git a/lib/lp/translations/interfaces/translationmessage.py b/lib/lp/translations/interfaces/translationmessage.py
194index f06c9e6..5b66292 100644
195--- a/lib/lp/translations/interfaces/translationmessage.py
196+++ b/lib/lp/translations/interfaces/translationmessage.py
197@@ -333,17 +333,6 @@ class ITranslationMessageSet(Interface):
198 def getByID(id):
199 """Return the TranslationMessage with the given ID or None."""
200
201- def selectDirect(where=None, order_by=None):
202- """Return sequence of `TranslationMessage`s matching arguments.
203-
204- This is meant for maintenance use. If you find yourself using
205- it anywhere except in a manually-run script, try something else.
206-
207- :param where: An SQL WHERE clause describing which messages to
208- return.
209- :param order_by: An SQL ORDER BY clause.
210- """
211-
212 def preloadDetails(messages, pofile=None, need_pofile=False,
213 need_potemplate=False, need_potemplate_context=False,
214 need_potranslation=False, need_potmsgset=False,
215diff --git a/lib/lp/translations/model/pofiletranslator.py b/lib/lp/translations/model/pofiletranslator.py
216index 3f1bf02..a8ea10a 100644
217--- a/lib/lp/translations/model/pofiletranslator.py
218+++ b/lib/lp/translations/model/pofiletranslator.py
219@@ -7,23 +7,32 @@ __all__ = [
220 'POFileTranslatorSet',
221 ]
222
223+from operator import itemgetter
224
225 from sqlobject import ForeignKey
226-from storm.expr import And
227+from storm.expr import (
228+ And,
229+ Join,
230+ LeftJoin,
231+ )
232 from storm.store import Store
233 from zope.interface import implementer
234
235 from lp.registry.interfaces.person import validate_public_person
236+from lp.registry.model.distroseries import DistroSeries
237+from lp.registry.model.product import Product
238+from lp.registry.model.productseries import ProductSeries
239+from lp.registry.model.sourcepackagename import SourcePackageName
240 from lp.services.database.datetimecol import UtcDateTimeCol
241-from lp.services.database.sqlbase import (
242- SQLBase,
243- sqlvalues,
244- )
245+from lp.services.database.decoratedresultset import DecoratedResultSet
246+from lp.services.database.interfaces import IStore
247+from lp.services.database.sqlbase import SQLBase
248 from lp.translations.interfaces.pofiletranslator import (
249 IPOFileTranslator,
250 IPOFileTranslatorSet,
251 )
252 from lp.translations.model.pofile import POFile
253+from lp.translations.model.potemplate import POTemplate
254
255
256 @implementer(IPOFileTranslator)
257@@ -47,17 +56,24 @@ class POFileTranslatorSet:
258 if not ids:
259 return None
260
261+ origin = [
262+ POFileTranslator,
263+ Join(POFile, POFileTranslator.pofile == POFile.id),
264+ Join(POTemplate, POFile.potemplate == POTemplate.id),
265+ LeftJoin(
266+ ProductSeries, POTemplate.productseries == ProductSeries.id),
267+ LeftJoin(Product, ProductSeries.product == Product.id),
268+ LeftJoin(DistroSeries, POTemplate.distroseries == DistroSeries.id),
269+ LeftJoin(
270+ SourcePackageName,
271+ POTemplate.sourcepackagename == SourcePackageName.id),
272+ ]
273+ rows = IStore(POFileTranslator).using(*origin).find(
274+ (POFileTranslator, POFile, POTemplate,
275+ ProductSeries, Product, DistroSeries, SourcePackageName),
276+ POFileTranslator.id.is_in(ids))
277 # Listify prefetch query to force its execution here.
278- return list(POFileTranslator.select(
279- "POFileTranslator.id IN %s" % sqlvalues(ids),
280- prejoins=[
281- 'pofile',
282- 'pofile.potemplate',
283- 'pofile.potemplate.productseries',
284- 'pofile.potemplate.productseries.product',
285- 'pofile.potemplate.distroseries',
286- 'pofile.potemplate.sourcepackagename',
287- ]))
288+ return list(DecoratedResultSet(rows, itemgetter(0)))
289
290 def getForPersonPOFile(self, person, pofile):
291 """See `IPOFileTranslatorSet`."""
292diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py
293index b0b5e2a..ebdbc42 100644
294--- a/lib/lp/translations/model/potemplate.py
295+++ b/lib/lp/translations/model/potemplate.py
296@@ -542,7 +542,7 @@ class POTemplate(SQLBase, RosettaStats):
297
298 def getPOFileByPath(self, path):
299 """See `IPOTemplate`."""
300- return POFile.selectOneBy(potemplate=self, path=path)
301+ return IStore(POFile).find(POFile, potemplate=self, path=path).one()
302
303 def getPOFileByLang(self, language_code):
304 """See `IPOTemplate`."""
305@@ -1281,17 +1281,18 @@ class POTemplateSet:
306
307 def __iter__(self):
308 """See `IPOTemplateSet`."""
309- res = POTemplate.select()
310- for potemplate in res:
311+ for potemplate in IStore(POTemplate).find(POTemplate):
312 yield potemplate
313
314 def getAllByName(self, name):
315 """See `IPOTemplateSet`."""
316- return POTemplate.selectBy(name=name, orderBy=['name', 'id'])
317+ return IStore(POTemplate).find(POTemplate, name=name).order_by(
318+ POTemplate.name, POTemplate.id)
319
320 def getAllOrderByDateLastUpdated(self):
321 """See `IPOTemplateSet`."""
322- return POTemplate.select(orderBy=['-date_last_updated'])
323+ return IStore(POTemplate).find(POTemplate).order_by(
324+ Desc(POTemplate.date_last_updated))
325
326 def getSubset(self, distroseries=None, sourcepackagename=None,
327 productseries=None, iscurrent=None,
328diff --git a/lib/lp/translations/model/translationgroup.py b/lib/lp/translations/model/translationgroup.py
329index 994172d..80267ba 100644
330--- a/lib/lp/translations/model/translationgroup.py
331+++ b/lib/lp/translations/model/translationgroup.py
332@@ -17,6 +17,7 @@ from sqlobject import (
333 StringCol,
334 )
335 from storm.expr import (
336+ Desc,
337 Join,
338 LeftJoin,
339 )
340@@ -100,8 +101,8 @@ class TranslationGroup(SQLBase):
341 # get a translator by language or code
342 def query_translator(self, language):
343 """See ITranslationGroup."""
344- return Translator.selectOneBy(language=language,
345- translationgroup=self)
346+ return IStore(Translator).find(
347+ Translator, language=language, translationgroup=self).one()
348
349 @property
350 def products(self):
351@@ -109,7 +110,8 @@ class TranslationGroup(SQLBase):
352 # Avoid circular imports.
353 from lp.registry.model.product import Product
354
355- return Product.selectBy(translationgroup=self.id, active=True)
356+ return IStore(Product).find(
357+ Product, translationgroup=self, active=True)
358
359 @property
360 def projects(self):
361@@ -117,7 +119,8 @@ class TranslationGroup(SQLBase):
362 # Avoid circular imports.
363 from lp.registry.model.projectgroup import ProjectGroup
364
365- return ProjectGroup.selectBy(translationgroup=self.id, active=True)
366+ return IStore(ProjectGroup).find(
367+ ProjectGroup, translationgroup=self, active=True)
368
369 # A limit of projects to get for the `top_projects`.
370 TOP_PROJECTS_LIMIT = 6
371@@ -260,10 +263,10 @@ class TranslationGroupSet:
372 # group names from their respective celebrities. For now,
373 # just hard-code them so they show up at the top of the
374 # listing of all translation groups.
375- for group in TranslationGroup.select(
376- orderBy=[
377- "-(name in ('launchpad-translators', 'ubuntu-translators'))",
378- "title"]):
379+ for group in IStore(TranslationGroup).find(TranslationGroup).order_by(
380+ Desc(TranslationGroup.name.is_in((
381+ 'launchpad-translators', 'ubuntu-translators'))),
382+ TranslationGroup.title):
383 yield group
384
385 def __getitem__(self, name):
386@@ -306,4 +309,4 @@ class TranslationGroupSet:
387
388 def getGroupsCount(self):
389 """See ITranslationGroupSet."""
390- return TranslationGroup.select().count()
391+ return IStore(TranslationGroup).find(TranslationGroup).count()
392diff --git a/lib/lp/translations/model/translationmessage.py b/lib/lp/translations/model/translationmessage.py
393index b323a20..cdbdca6 100644
394--- a/lib/lp/translations/model/translationmessage.py
395+++ b/lib/lp/translations/model/translationmessage.py
396@@ -546,10 +546,6 @@ class TranslationMessageSet:
397 except SQLObjectNotFound:
398 return None
399
400- def selectDirect(self, where=None, order_by=None):
401- """See `ITranslationMessageSet`."""
402- return TranslationMessage.select(where, orderBy=order_by)
403-
404 def preloadDetails(self, messages, pofile=None, need_pofile=False,
405 need_potemplate=False, need_potemplate_context=False,
406 need_potranslation=False, need_potmsgset=False,
407diff --git a/lib/lp/translations/model/translationsperson.py b/lib/lp/translations/model/translationsperson.py
408index 0fa28d9..6c28d7b 100644
409--- a/lib/lp/translations/model/translationsperson.py
410+++ b/lib/lp/translations/model/translationsperson.py
411@@ -30,11 +30,12 @@ from lp.app.interfaces.launchpad import ILaunchpadCelebrities
412 from lp.registry.interfaces.person import IPerson
413 from lp.registry.model.distribution import Distribution
414 from lp.registry.model.distroseries import DistroSeries
415+from lp.registry.model.person import PersonLanguage
416 from lp.registry.model.product import Product
417 from lp.registry.model.productseries import ProductSeries
418 from lp.registry.model.projectgroup import ProjectGroup
419 from lp.registry.model.teammembership import TeamParticipation
420-from lp.services.database.sqlbase import sqlvalues
421+from lp.services.database.interfaces import IStore
422 from lp.services.propertycache import (
423 cachedproperty,
424 get_property_cache,
425@@ -64,12 +65,12 @@ class TranslationsPerson:
426 @property
427 def translatable_languages(self):
428 """See `ITranslationsPerson`."""
429- return Language.select("""
430- Language.id = PersonLanguage.language AND
431- PersonLanguage.person = %s AND
432- Language.code <> 'en' AND
433- Language.visible""" % sqlvalues(self.person),
434- clauseTables=['PersonLanguage'], orderBy='englishname')
435+ return IStore(Language).find(
436+ Language,
437+ PersonLanguage.language == Language.id,
438+ PersonLanguage.person == self.person,
439+ Language.code != 'en',
440+ Language.visible).order_by(Language.englishname)
441
442 def getTranslationHistory(self, no_older_than=None):
443 """See `ITranslationsPerson`."""
444@@ -108,8 +109,8 @@ class TranslationsPerson:
445
446 If they have made no explicit decision yet, return None.
447 """
448- relicensing_agreement = TranslationRelicensingAgreement.selectOneBy(
449- person=self.person)
450+ relicensing_agreement = IStore(TranslationRelicensingAgreement).find(
451+ TranslationRelicensingAgreement, person=self.person).one()
452 if relicensing_agreement is None:
453 return None
454 else:
455@@ -123,8 +124,8 @@ class TranslationsPerson:
456
457 If they have already made a decision, overrides it with the new one.
458 """
459- relicensing_agreement = TranslationRelicensingAgreement.selectOneBy(
460- person=self.person)
461+ relicensing_agreement = IStore(TranslationRelicensingAgreement).find(
462+ TranslationRelicensingAgreement, person=self.person).one()
463 if relicensing_agreement is None:
464 relicensing_agreement = TranslationRelicensingAgreement(
465 person=self.person,
466diff --git a/lib/lp/translations/scripts/fix_plural_forms.py b/lib/lp/translations/scripts/fix_plural_forms.py
467index 8d264ae..df8e25c 100644
468--- a/lib/lp/translations/scripts/fix_plural_forms.py
469+++ b/lib/lp/translations/scripts/fix_plural_forms.py
470@@ -11,12 +11,11 @@ __all__ = [
471
472 from sqlobject import SQLObjectNotFound
473
474-from lp.services.database.sqlbase import (
475- cursor,
476- sqlvalues,
477- )
478+from lp.services.database.interfaces import IStore
479+from lp.services.database.sqlbase import cursor
480 from lp.translations.interfaces.translations import TranslationConstants
481 from lp.translations.model.pofile import POFile
482+from lp.translations.model.potmsgset import POTMsgSet
483 from lp.translations.model.translationmessage import TranslationMessage
484 from lp.translations.utilities.gettext_po_parser import POHeader
485 from lp.translations.utilities.pluralforms import plural_form_mapper
486@@ -49,11 +48,11 @@ def fix_pofile_plurals(pofile, logger, ztm):
487 plural_forms_mapping = get_mapping_for_pofile_plurals(pofile)
488 if plural_forms_mapping is not None:
489 logger.info("Fixing PO file %s" % pofile.title)
490- pluralmessages = TranslationMessage.select("""
491- POTMsgSet.id = TranslationMessage.potmsgset AND
492- POTMsgSet.msgid_plural IS NOT NULL AND
493- TranslationMessage.pofile = %s""" % sqlvalues(pofile),
494- clauseTables=["POTMsgSet"])
495+ pluralmessages = IStore(TranslationMessage).find(
496+ TranslationMessage,
497+ TranslationMessage.potmsgset == POTMsgSet.id,
498+ POTMsgSet.msgid_plural != None,
499+ TranslationMessage.pofile == pofile)
500 for message in pluralmessages:
501 logger.debug("\tFixing translations for '%s'" % (
502 message.potmsgset.singular_text))
503diff --git a/lib/lp/translations/scripts/gettext_check_messages.py b/lib/lp/translations/scripts/gettext_check_messages.py
504index fa6a388..b4e4345 100644
505--- a/lib/lp/translations/scripts/gettext_check_messages.py
506+++ b/lib/lp/translations/scripts/gettext_check_messages.py
507@@ -11,13 +11,12 @@ from datetime import (
508 )
509
510 import six
511-from zope.component import getUtility
512+from storm.locals import SQL
513 from zope.security.proxy import removeSecurityProxy
514
515+from lp.services.database.interfaces import IStore
516 from lp.services.scripts.base import LaunchpadScript
517-from lp.translations.interfaces.translationmessage import (
518- ITranslationMessageSet,
519- )
520+from lp.translations.model.translationmessage import TranslationMessage
521 from lp.translations.utilities.validate import (
522 GettextValidationError,
523 validate_translation,
524@@ -66,8 +65,11 @@ class GettextCheckMessages(LaunchpadScript):
525 self.logger.debug(
526 "Checking messages matching: %s" % self.options.where)
527
528- messages = getUtility(ITranslationMessageSet).selectDirect(
529- self.options.where, order_by=self.options.order_by)
530+ messages = IStore(TranslationMessage).find(TranslationMessage)
531+ if self.options.where is not None:
532+ messages = messages.find(SQL(self.options.where))
533+ if self.options.order_by is not None:
534+ messages = messages.order_by(SQL(self.options.order_by))
535 self._iterate(messages)
536
537 self.logger.info("Done.")
538diff --git a/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt b/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
539index 8e9f427..9c15385 100644
540--- a/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
541+++ b/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
542@@ -294,12 +294,13 @@ Ubuntu uploads
543 As a special case, the owners of Ubuntu's translation group are allowed
544 to manage Ubuntu uploads.
545
546- >>> from lp.registry.model.distribution import Distribution
547+ >>> from zope.component import getUtility
548+ >>> from lp.registry.interfaces.distribution import IDistributionSet
549 >>> from lp.translations.model.translationimportqueue import (
550 ... TranslationImportQueue)
551 >>> login('admin@canonical.com')
552 >>> queue = TranslationImportQueue()
553- >>> ubuntu = Distribution.selectOneBy(name='ubuntu')
554+ >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
555 >>> hoary = ubuntu['hoary']
556
557 There is a translation group for Ubuntu. Its owner has no special
558@@ -307,17 +308,16 @@ privileges or roles other than running the group.
559
560 Somebody else has uploaded a translation template for an Ubuntu package.
561
562- >>> login(ANONYMOUS)
563-
564 >>> package = factory.makeSourcePackageName()
565 >>> group_owner = factory.makePerson(
566 ... email='go@example.com', name='groupowner')
567 >>> uploader = factory.makePerson()
568 >>> ubuntu.translationgroup = factory.makeTranslationGroup(group_owner)
569+
570+ >>> login(ANONYMOUS)
571 >>> ubuntu_upload = queue.addOrUpdateEntry(
572 ... 'messages.pot', b'(content)', False, uploader,
573 ... sourcepackagename=package, distroseries=hoary)
574-
575 >>> logout()
576
577 The owner of Ubuntu's translation group, despite not being the owner or
578diff --git a/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt b/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
579index bf9852a..59a9600 100644
580--- a/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
581+++ b/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
582@@ -186,10 +186,11 @@ Distribution templates
583 Distributions get slightly wider permissions to manage their templates
584 autonomously.
585
586- >>> from lp.registry.model.distribution import Distribution
587+ >>> from zope.component import getUtility
588+ >>> from lp.registry.interfaces.distribution import IDistributionSet
589 >>> from lp.translations.model.potemplate import POTemplateSet
590 >>> login('admin@canonical.com')
591- >>> ubuntu = Distribution.selectOneBy(name='ubuntu')
592+ >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
593 >>> hoary = ubuntu['hoary']
594 >>> templateset = POTemplateSet()
595
596@@ -201,6 +202,7 @@ autonomously.
597 >>> template = templatesubset.new(
598 ... 'foo', 'foo', 'foo.pot', template_owner)
599
600+ >>> login('admin@canonical.com')
601 >>> distro_owner = factory.makePerson('do@example.com')
602 >>> ubuntu.owner = distro_owner
603
604diff --git a/lib/lp/translations/stories/standalone/xx-translation-access-display.txt b/lib/lp/translations/stories/standalone/xx-translation-access-display.txt
605index d374966..adcc0bd 100644
606--- a/lib/lp/translations/stories/standalone/xx-translation-access-display.txt
607+++ b/lib/lp/translations/stories/standalone/xx-translation-access-display.txt
608@@ -38,20 +38,25 @@ translation group of its own, that too is shown here.
609
610 >>> import re
611
612+ >>> from zope.component import getUtility
613+ >>> from zope.security.proxy import removeSecurityProxy
614+
615 >>> from lp.services.database.constants import UTC_NOW
616- >>> from lp.registry.model.person import Person
617- >>> from lp.registry.model.product import Product
618- >>> from lp.services.worlddata.model.language import Language
619+ >>> from lp.registry.interfaces.person import IPersonSet
620+ >>> from lp.registry.interfaces.product import IProductSet
621+ >>> from lp.services.worlddata.interfaces.language import ILanguageSet
622 >>> from lp.translations.model.translationgroup import (
623 ... TranslationGroup)
624
625- >>> spanish = Language.selectOneBy(code='es')
626- >>> evolution = Product.selectOneBy(name='evolution')
627- >>> foobar = Person.selectOneBy(name='name16')
628+ >>> login('admin@canonical.com')
629+ >>> spanish = getUtility(ILanguageSet)['es']
630+ >>> evolution = removeSecurityProxy(getUtility(IProductSet)['evolution'])
631+ >>> foobar = getUtility(IPersonSet).getByName('name16')
632 >>> gnomegroup = TranslationGroup(name='gnomegroup',
633 ... title="Gnome translation group", summary="Testing group",
634 ... datecreated=UTC_NOW, owner=foobar)
635 >>> evolution.projectgroup.translationgroup = gnomegroup
636+ >>> logout()
637
638 >>> admin_browser.open(
639 ... 'http://translations.launchpad.test/'

Subscribers

People subscribed via source and target branches

to status/vote changes: