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
diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
index 2811a42..e83a7dc 100644
--- a/lib/lp/registry/model/distroseries.py
+++ b/lib/lp/registry/model/distroseries.py
@@ -178,7 +178,6 @@ from lp.translations.model.hastranslationtemplates import (
178 )178 )
179from lp.translations.model.languagepack import LanguagePack179from lp.translations.model.languagepack import LanguagePack
180from lp.translations.model.pofile import POFile180from lp.translations.model.pofile import POFile
181from lp.translations.model.pofiletranslator import POFileTranslator
182from lp.translations.model.potemplate import (181from lp.translations.model.potemplate import (
183 POTemplate,182 POTemplate,
184 TranslationTemplatesCollection,183 TranslationTemplatesCollection,
@@ -1362,6 +1361,9 @@ class DistroSeries(SQLBase, BugTargetBase, HasSpecificationsMixin,
13621361
1363 def getPOFileContributorsByLanguage(self, language):1362 def getPOFileContributorsByLanguage(self, language):
1364 """See `IDistroSeries`."""1363 """See `IDistroSeries`."""
1364 # Circular import.
1365 from lp.translations.model.pofiletranslator import POFileTranslator
1366
1365 contributors = IStore(Person).find(1367 contributors = IStore(Person).find(
1366 Person,1368 Person,
1367 POFileTranslator.personID == Person.id,1369 POFileTranslator.personID == Person.id,
diff --git a/lib/lp/translations/doc/poexport-request-productseries.txt b/lib/lp/translations/doc/poexport-request-productseries.txt
index 1978e3e..53303a2 100644
--- a/lib/lp/translations/doc/poexport-request-productseries.txt
+++ b/lib/lp/translations/doc/poexport-request-productseries.txt
@@ -7,9 +7,9 @@
77
8This is a dummy logger class to capture the export's log messages.8This is a dummy logger class to capture the export's log messages.
99
10 >>> from lp.registry.model.person import Person10 >>> from lp.registry.interfaces.person import IPersonSet
11 >>> from lp.services.log.logger import FakeLogger11 >>> from lp.services.log.logger import FakeLogger
12 >>> person = Person.selectOneBy(name='name12')12 >>> person = getUtility(IPersonSet).getByName('name12')
1313
14An arbitrary logged-in user requests an export of all translations for14An arbitrary logged-in user requests an export of all translations for
15Evolution series trunk.15Evolution series trunk.
@@ -18,16 +18,15 @@ At the UI level, this is easy. At the level we are looking at now, this
18consists of a series of requests for all templates and translations attached18consists of a series of requests for all templates and translations attached
19to the product series.19to the product series.
2020
21 >>> from lp.registry.model.product import Product21 >>> from lp.registry.interfaces.product import IProductSet
22 >>> from lp.registry.model.productseries import ProductSeries22 >>> from lp.translations.interfaces.potemplate import IPOTemplateSet
23 >>> from lp.translations.model.potemplate import POTemplate23 >>> evolution_product = getUtility(IProductSet).getByName('evolution')
24 >>> evolution_product = Product.selectOneBy(name='evolution')24 >>> evolution_trunk = evolution_product.getSeries('trunk')
25 >>> evolution_trunk = ProductSeries.selectOneBy(25 >>> potemplates = list(getUtility(IPOTemplateSet).getSubset(
26 ... product=evolution_product, name='trunk')26 ... productseries=evolution_trunk))
27 >>> potemplates = list(POTemplate.selectBy(productseries=evolution_trunk))
28 >>> pofiles = []27 >>> pofiles = []
29 >>> for template in potemplates:28 >>> for template in potemplates:
30 ... pofiles += template.pofiles29 ... pofiles.extend(template.pofiles)
3130
32 >>> request_set = getUtility(IPOExportRequestSet)31 >>> request_set = getUtility(IPOExportRequestSet)
33 >>> request_set.addRequest(person, potemplates, pofiles)32 >>> request_set.addRequest(person, potemplates, pofiles)
diff --git a/lib/lp/translations/doc/poexport-request.txt b/lib/lp/translations/doc/poexport-request.txt
index cf6d13f..8e87314 100644
--- a/lib/lp/translations/doc/poexport-request.txt
+++ b/lib/lp/translations/doc/poexport-request.txt
@@ -233,9 +233,11 @@ just PO files.
233 >>> product_template.productseries is None233 >>> product_template.productseries is None
234 False234 False
235 >>> request_set.addRequest(person, product_template)235 >>> request_set.addRequest(person, product_template)
236 >>> alsa_template = POTemplate.selectOneBy(path='po/alsa-utils.pot')236 >>> alsa_template = IStore(POTemplate).find(
237 ... POTemplate, path='po/alsa-utils.pot').one()
237 >>> alsa_es = alsa_template.getPOFileByLang('es')238 >>> alsa_es = alsa_template.getPOFileByLang('es')
238 >>> netapplet_template = POTemplate.selectOneBy(path='po/netapplet.pot')239 >>> netapplet_template = IStore(POTemplate).find(
240 ... POTemplate, path='po/netapplet.pot').one()
239 >>> request_set.addRequest(241 >>> request_set.addRequest(
240 ... person, [alsa_template, netapplet_template], [alsa_es])242 ... person, [alsa_template, netapplet_template], [alsa_es])
241 >>> transaction.commit()243 >>> transaction.commit()
diff --git a/lib/lp/translations/doc/pofile.txt b/lib/lp/translations/doc/pofile.txt
index 9caf91d..286080b 100644
--- a/lib/lp/translations/doc/pofile.txt
+++ b/lib/lp/translations/doc/pofile.txt
@@ -611,10 +611,8 @@ If you have a distroseries and want to know all the people who
611contributed translations on a given language for that distroseries, you611contributed translations on a given language for that distroseries, you
612can use the getPOFileContributorsByLanguage() method of IDistroSeries.612can use the getPOFileContributorsByLanguage() method of IDistroSeries.
613613
614 >>> from lp.registry.model.distroseries import DistroSeries614 >>> hoary = distribution.getSeries("hoary")
615 >>> from lp.services.worlddata.model.language import Language615 >>> spanish = getUtility(ILanguageSet)["es"]
616 >>> hoary = DistroSeries.selectOneBy(name="hoary")
617 >>> spanish = Language.selectOneBy(code="es")
618 >>> print_names(hoary.getPOFileContributorsByLanguage(spanish))616 >>> print_names(hoary.getPOFileContributorsByLanguage(spanish))
619 jorge-gonzalez-gonzalez617 jorge-gonzalez-gonzalez
620 carlos618 carlos
diff --git a/lib/lp/translations/doc/potmsgset.txt b/lib/lp/translations/doc/potmsgset.txt
index ade9470..d07038c 100644
--- a/lib/lp/translations/doc/potmsgset.txt
+++ b/lib/lp/translations/doc/potmsgset.txt
@@ -612,20 +612,14 @@ POTMsgSet.setSequence
612Finally, the new `IPOTMsgSet` should have an entry in the612Finally, the new `IPOTMsgSet` should have an entry in the
613`TranslationTemplateItem` table once we assign a sequence number.613`TranslationTemplateItem` table once we assign a sequence number.
614614
615 >>> from lp.translations.model.translationtemplateitem import (
616 ... TranslationTemplateItem)
617
618First, we need a helper function to check whether the potmsgset exists615First, we need a helper function to check whether the potmsgset exists
619in the table or not.616in the table or not.
620617
621
622 >>> def is_potmsgset_in_potemplate(potmsgset, potemplate):618 >>> def is_potmsgset_in_potemplate(potmsgset, potemplate):
623 ... items = [619 ... items = {
624 ... item.potmsgset.id620 ... potmsgset.id
625 ... for item in TranslationTemplateItem.selectBy(621 ... for potmsgset in potemplate.getPOTMsgSets(prefetch=False)
626 ... potemplate=potemplate, potmsgset=potmsgset)622 ... }
627 ... if item.sequence > 0
628 ... ]
629 ... return potmsgset.id in items623 ... return potmsgset.id in items
630624
631Let's create a new potmsgset object.625Let's create a new potmsgset object.
diff --git a/lib/lp/translations/doc/translationmessage-destroy.txt b/lib/lp/translations/doc/translationmessage-destroy.txt
index 8b52fcf..6709859 100644
--- a/lib/lp/translations/doc/translationmessage-destroy.txt
+++ b/lib/lp/translations/doc/translationmessage-destroy.txt
@@ -36,7 +36,7 @@ translation, we get two POFileTranslator records for each of the POFiles.
36 # We need to be able to create persons and projects so let's just use36 # We need to be able to create persons and projects so let's just use
37 # a global 'postgres' permission which allows everything.37 # a global 'postgres' permission which allows everything.
38 >>> switch_dbuser('postgres')38 >>> switch_dbuser('postgres')
39 >>> from lp.services.database.sqlbase import sqlvalues39 >>> from lp.services.database.interfaces import IStore
40 >>> from lp.app.enums import ServiceUsage40 >>> from lp.app.enums import ServiceUsage
41 >>> from lp.testing.factory import LaunchpadObjectFactory41 >>> from lp.testing.factory import LaunchpadObjectFactory
42 >>> from lp.translations.model.pofiletranslator import POFileTranslator42 >>> from lp.translations.model.pofiletranslator import POFileTranslator
@@ -62,7 +62,8 @@ translation, we get two POFileTranslator records for each of the POFiles.
62 ... pofile=devel_sr_pofile,62 ... pofile=devel_sr_pofile,
63 ... potmsgset=potmsgset,63 ... potmsgset=potmsgset,
64 ... translations=[u"blah"])64 ... translations=[u"blah"])
65 >>> print(POFileTranslator.select(65 >>> print(IStore(POFileTranslator).find(
66 ... "pofile IN (%s, %s)"66 ... POFileTranslator,
67 ... % sqlvalues(devel_sr_pofile, stable_sr_pofile)).count())67 ... POFileTranslator.pofileID.is_in(
68 ... (devel_sr_pofile.id, stable_sr_pofile.id))).count())
68 269 2
diff --git a/lib/lp/translations/doc/translationrelicensingagreement.txt b/lib/lp/translations/doc/translationrelicensingagreement.txt
index ad6156d..c40f41b 100644
--- a/lib/lp/translations/doc/translationrelicensingagreement.txt
+++ b/lib/lp/translations/doc/translationrelicensingagreement.txt
@@ -5,6 +5,7 @@ Launchpad can decide whether they want their translations relicensed
5under BSD or not.5under BSD or not.
66
7 >>> from zope.component import getUtility7 >>> from zope.component import getUtility
8 >>> from lp.services.database.interfaces import IStore
8 >>> from lp.testing import verifyObject9 >>> from lp.testing import verifyObject
9 >>> from lp.translations.model.translationrelicensingagreement \10 >>> from lp.translations.model.translationrelicensingagreement \
10 ... import TranslationRelicensingAgreement11 ... import TranslationRelicensingAgreement
@@ -23,7 +24,8 @@ When Karl has not made his selection yet, it is marked as None.
2324
24 >>> print(translations_person.translations_relicensing_agreement)25 >>> print(translations_person.translations_relicensing_agreement)
25 None26 None
26 >>> choice = TranslationRelicensingAgreement.selectOneBy(person=person)27 >>> choice = IStore(TranslationRelicensingAgreement).find(
28 ... TranslationRelicensingAgreement, person=person).one()
27 >>> print(choice)29 >>> print(choice)
28 None30 None
2931
@@ -33,7 +35,8 @@ object.
33 >>> translations_person.translations_relicensing_agreement = True35 >>> translations_person.translations_relicensing_agreement = True
34 >>> print(translations_person.translations_relicensing_agreement)36 >>> print(translations_person.translations_relicensing_agreement)
35 True37 True
36 >>> choice = TranslationRelicensingAgreement.selectOneBy(person=person)38 >>> choice = IStore(TranslationRelicensingAgreement).find(
39 ... TranslationRelicensingAgreement, person=person).one()
37 >>> print(choice.allow_relicensing)40 >>> print(choice.allow_relicensing)
38 True41 True
3942
@@ -47,6 +50,7 @@ A translator can also change their mind later.
47 >>> translations_person.translations_relicensing_agreement = False50 >>> translations_person.translations_relicensing_agreement = False
48 >>> print(translations_person.translations_relicensing_agreement)51 >>> print(translations_person.translations_relicensing_agreement)
49 False52 False
50 >>> choice = TranslationRelicensingAgreement.selectOneBy(person=person)53 >>> choice = IStore(TranslationRelicensingAgreement).find(
54 ... TranslationRelicensingAgreement, person=person).one()
51 >>> print(choice.allow_relicensing)55 >>> print(choice.allow_relicensing)
52 False56 False
diff --git a/lib/lp/translations/interfaces/translationmessage.py b/lib/lp/translations/interfaces/translationmessage.py
index f06c9e6..5b66292 100644
--- a/lib/lp/translations/interfaces/translationmessage.py
+++ b/lib/lp/translations/interfaces/translationmessage.py
@@ -333,17 +333,6 @@ class ITranslationMessageSet(Interface):
333 def getByID(id):333 def getByID(id):
334 """Return the TranslationMessage with the given ID or None."""334 """Return the TranslationMessage with the given ID or None."""
335335
336 def selectDirect(where=None, order_by=None):
337 """Return sequence of `TranslationMessage`s matching arguments.
338
339 This is meant for maintenance use. If you find yourself using
340 it anywhere except in a manually-run script, try something else.
341
342 :param where: An SQL WHERE clause describing which messages to
343 return.
344 :param order_by: An SQL ORDER BY clause.
345 """
346
347 def preloadDetails(messages, pofile=None, need_pofile=False,336 def preloadDetails(messages, pofile=None, need_pofile=False,
348 need_potemplate=False, need_potemplate_context=False,337 need_potemplate=False, need_potemplate_context=False,
349 need_potranslation=False, need_potmsgset=False,338 need_potranslation=False, need_potmsgset=False,
diff --git a/lib/lp/translations/model/pofiletranslator.py b/lib/lp/translations/model/pofiletranslator.py
index 3f1bf02..a8ea10a 100644
--- a/lib/lp/translations/model/pofiletranslator.py
+++ b/lib/lp/translations/model/pofiletranslator.py
@@ -7,23 +7,32 @@ __all__ = [
7 'POFileTranslatorSet',7 'POFileTranslatorSet',
8 ]8 ]
99
10from operator import itemgetter
1011
11from sqlobject import ForeignKey12from sqlobject import ForeignKey
12from storm.expr import And13from storm.expr import (
14 And,
15 Join,
16 LeftJoin,
17 )
13from storm.store import Store18from storm.store import Store
14from zope.interface import implementer19from zope.interface import implementer
1520
16from lp.registry.interfaces.person import validate_public_person21from lp.registry.interfaces.person import validate_public_person
22from lp.registry.model.distroseries import DistroSeries
23from lp.registry.model.product import Product
24from lp.registry.model.productseries import ProductSeries
25from lp.registry.model.sourcepackagename import SourcePackageName
17from lp.services.database.datetimecol import UtcDateTimeCol26from lp.services.database.datetimecol import UtcDateTimeCol
18from lp.services.database.sqlbase import (27from lp.services.database.decoratedresultset import DecoratedResultSet
19 SQLBase,28from lp.services.database.interfaces import IStore
20 sqlvalues,29from lp.services.database.sqlbase import SQLBase
21 )
22from lp.translations.interfaces.pofiletranslator import (30from lp.translations.interfaces.pofiletranslator import (
23 IPOFileTranslator,31 IPOFileTranslator,
24 IPOFileTranslatorSet,32 IPOFileTranslatorSet,
25 )33 )
26from lp.translations.model.pofile import POFile34from lp.translations.model.pofile import POFile
35from lp.translations.model.potemplate import POTemplate
2736
2837
29@implementer(IPOFileTranslator)38@implementer(IPOFileTranslator)
@@ -47,17 +56,24 @@ class POFileTranslatorSet:
47 if not ids:56 if not ids:
48 return None57 return None
4958
59 origin = [
60 POFileTranslator,
61 Join(POFile, POFileTranslator.pofile == POFile.id),
62 Join(POTemplate, POFile.potemplate == POTemplate.id),
63 LeftJoin(
64 ProductSeries, POTemplate.productseries == ProductSeries.id),
65 LeftJoin(Product, ProductSeries.product == Product.id),
66 LeftJoin(DistroSeries, POTemplate.distroseries == DistroSeries.id),
67 LeftJoin(
68 SourcePackageName,
69 POTemplate.sourcepackagename == SourcePackageName.id),
70 ]
71 rows = IStore(POFileTranslator).using(*origin).find(
72 (POFileTranslator, POFile, POTemplate,
73 ProductSeries, Product, DistroSeries, SourcePackageName),
74 POFileTranslator.id.is_in(ids))
50 # Listify prefetch query to force its execution here.75 # Listify prefetch query to force its execution here.
51 return list(POFileTranslator.select(76 return list(DecoratedResultSet(rows, itemgetter(0)))
52 "POFileTranslator.id IN %s" % sqlvalues(ids),
53 prejoins=[
54 'pofile',
55 'pofile.potemplate',
56 'pofile.potemplate.productseries',
57 'pofile.potemplate.productseries.product',
58 'pofile.potemplate.distroseries',
59 'pofile.potemplate.sourcepackagename',
60 ]))
6177
62 def getForPersonPOFile(self, person, pofile):78 def getForPersonPOFile(self, person, pofile):
63 """See `IPOFileTranslatorSet`."""79 """See `IPOFileTranslatorSet`."""
diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py
index b0b5e2a..ebdbc42 100644
--- a/lib/lp/translations/model/potemplate.py
+++ b/lib/lp/translations/model/potemplate.py
@@ -542,7 +542,7 @@ class POTemplate(SQLBase, RosettaStats):
542542
543 def getPOFileByPath(self, path):543 def getPOFileByPath(self, path):
544 """See `IPOTemplate`."""544 """See `IPOTemplate`."""
545 return POFile.selectOneBy(potemplate=self, path=path)545 return IStore(POFile).find(POFile, potemplate=self, path=path).one()
546546
547 def getPOFileByLang(self, language_code):547 def getPOFileByLang(self, language_code):
548 """See `IPOTemplate`."""548 """See `IPOTemplate`."""
@@ -1281,17 +1281,18 @@ class POTemplateSet:
12811281
1282 def __iter__(self):1282 def __iter__(self):
1283 """See `IPOTemplateSet`."""1283 """See `IPOTemplateSet`."""
1284 res = POTemplate.select()1284 for potemplate in IStore(POTemplate).find(POTemplate):
1285 for potemplate in res:
1286 yield potemplate1285 yield potemplate
12871286
1288 def getAllByName(self, name):1287 def getAllByName(self, name):
1289 """See `IPOTemplateSet`."""1288 """See `IPOTemplateSet`."""
1290 return POTemplate.selectBy(name=name, orderBy=['name', 'id'])1289 return IStore(POTemplate).find(POTemplate, name=name).order_by(
1290 POTemplate.name, POTemplate.id)
12911291
1292 def getAllOrderByDateLastUpdated(self):1292 def getAllOrderByDateLastUpdated(self):
1293 """See `IPOTemplateSet`."""1293 """See `IPOTemplateSet`."""
1294 return POTemplate.select(orderBy=['-date_last_updated'])1294 return IStore(POTemplate).find(POTemplate).order_by(
1295 Desc(POTemplate.date_last_updated))
12951296
1296 def getSubset(self, distroseries=None, sourcepackagename=None,1297 def getSubset(self, distroseries=None, sourcepackagename=None,
1297 productseries=None, iscurrent=None,1298 productseries=None, iscurrent=None,
diff --git a/lib/lp/translations/model/translationgroup.py b/lib/lp/translations/model/translationgroup.py
index 994172d..80267ba 100644
--- a/lib/lp/translations/model/translationgroup.py
+++ b/lib/lp/translations/model/translationgroup.py
@@ -17,6 +17,7 @@ from sqlobject import (
17 StringCol,17 StringCol,
18 )18 )
19from storm.expr import (19from storm.expr import (
20 Desc,
20 Join,21 Join,
21 LeftJoin,22 LeftJoin,
22 )23 )
@@ -100,8 +101,8 @@ class TranslationGroup(SQLBase):
100 # get a translator by language or code101 # get a translator by language or code
101 def query_translator(self, language):102 def query_translator(self, language):
102 """See ITranslationGroup."""103 """See ITranslationGroup."""
103 return Translator.selectOneBy(language=language,104 return IStore(Translator).find(
104 translationgroup=self)105 Translator, language=language, translationgroup=self).one()
105106
106 @property107 @property
107 def products(self):108 def products(self):
@@ -109,7 +110,8 @@ class TranslationGroup(SQLBase):
109 # Avoid circular imports.110 # Avoid circular imports.
110 from lp.registry.model.product import Product111 from lp.registry.model.product import Product
111112
112 return Product.selectBy(translationgroup=self.id, active=True)113 return IStore(Product).find(
114 Product, translationgroup=self, active=True)
113115
114 @property116 @property
115 def projects(self):117 def projects(self):
@@ -117,7 +119,8 @@ class TranslationGroup(SQLBase):
117 # Avoid circular imports.119 # Avoid circular imports.
118 from lp.registry.model.projectgroup import ProjectGroup120 from lp.registry.model.projectgroup import ProjectGroup
119121
120 return ProjectGroup.selectBy(translationgroup=self.id, active=True)122 return IStore(ProjectGroup).find(
123 ProjectGroup, translationgroup=self, active=True)
121124
122 # A limit of projects to get for the `top_projects`.125 # A limit of projects to get for the `top_projects`.
123 TOP_PROJECTS_LIMIT = 6126 TOP_PROJECTS_LIMIT = 6
@@ -260,10 +263,10 @@ class TranslationGroupSet:
260 # group names from their respective celebrities. For now,263 # group names from their respective celebrities. For now,
261 # just hard-code them so they show up at the top of the264 # just hard-code them so they show up at the top of the
262 # listing of all translation groups.265 # listing of all translation groups.
263 for group in TranslationGroup.select(266 for group in IStore(TranslationGroup).find(TranslationGroup).order_by(
264 orderBy=[267 Desc(TranslationGroup.name.is_in((
265 "-(name in ('launchpad-translators', 'ubuntu-translators'))",268 'launchpad-translators', 'ubuntu-translators'))),
266 "title"]):269 TranslationGroup.title):
267 yield group270 yield group
268271
269 def __getitem__(self, name):272 def __getitem__(self, name):
@@ -306,4 +309,4 @@ class TranslationGroupSet:
306309
307 def getGroupsCount(self):310 def getGroupsCount(self):
308 """See ITranslationGroupSet."""311 """See ITranslationGroupSet."""
309 return TranslationGroup.select().count()312 return IStore(TranslationGroup).find(TranslationGroup).count()
diff --git a/lib/lp/translations/model/translationmessage.py b/lib/lp/translations/model/translationmessage.py
index b323a20..cdbdca6 100644
--- a/lib/lp/translations/model/translationmessage.py
+++ b/lib/lp/translations/model/translationmessage.py
@@ -546,10 +546,6 @@ class TranslationMessageSet:
546 except SQLObjectNotFound:546 except SQLObjectNotFound:
547 return None547 return None
548548
549 def selectDirect(self, where=None, order_by=None):
550 """See `ITranslationMessageSet`."""
551 return TranslationMessage.select(where, orderBy=order_by)
552
553 def preloadDetails(self, messages, pofile=None, need_pofile=False,549 def preloadDetails(self, messages, pofile=None, need_pofile=False,
554 need_potemplate=False, need_potemplate_context=False,550 need_potemplate=False, need_potemplate_context=False,
555 need_potranslation=False, need_potmsgset=False,551 need_potranslation=False, need_potmsgset=False,
diff --git a/lib/lp/translations/model/translationsperson.py b/lib/lp/translations/model/translationsperson.py
index 0fa28d9..6c28d7b 100644
--- a/lib/lp/translations/model/translationsperson.py
+++ b/lib/lp/translations/model/translationsperson.py
@@ -30,11 +30,12 @@ from lp.app.interfaces.launchpad import ILaunchpadCelebrities
30from lp.registry.interfaces.person import IPerson30from lp.registry.interfaces.person import IPerson
31from lp.registry.model.distribution import Distribution31from lp.registry.model.distribution import Distribution
32from lp.registry.model.distroseries import DistroSeries32from lp.registry.model.distroseries import DistroSeries
33from lp.registry.model.person import PersonLanguage
33from lp.registry.model.product import Product34from lp.registry.model.product import Product
34from lp.registry.model.productseries import ProductSeries35from lp.registry.model.productseries import ProductSeries
35from lp.registry.model.projectgroup import ProjectGroup36from lp.registry.model.projectgroup import ProjectGroup
36from lp.registry.model.teammembership import TeamParticipation37from lp.registry.model.teammembership import TeamParticipation
37from lp.services.database.sqlbase import sqlvalues38from lp.services.database.interfaces import IStore
38from lp.services.propertycache import (39from lp.services.propertycache import (
39 cachedproperty,40 cachedproperty,
40 get_property_cache,41 get_property_cache,
@@ -64,12 +65,12 @@ class TranslationsPerson:
64 @property65 @property
65 def translatable_languages(self):66 def translatable_languages(self):
66 """See `ITranslationsPerson`."""67 """See `ITranslationsPerson`."""
67 return Language.select("""68 return IStore(Language).find(
68 Language.id = PersonLanguage.language AND69 Language,
69 PersonLanguage.person = %s AND70 PersonLanguage.language == Language.id,
70 Language.code <> 'en' AND71 PersonLanguage.person == self.person,
71 Language.visible""" % sqlvalues(self.person),72 Language.code != 'en',
72 clauseTables=['PersonLanguage'], orderBy='englishname')73 Language.visible).order_by(Language.englishname)
7374
74 def getTranslationHistory(self, no_older_than=None):75 def getTranslationHistory(self, no_older_than=None):
75 """See `ITranslationsPerson`."""76 """See `ITranslationsPerson`."""
@@ -108,8 +109,8 @@ class TranslationsPerson:
108109
109 If they have made no explicit decision yet, return None.110 If they have made no explicit decision yet, return None.
110 """111 """
111 relicensing_agreement = TranslationRelicensingAgreement.selectOneBy(112 relicensing_agreement = IStore(TranslationRelicensingAgreement).find(
112 person=self.person)113 TranslationRelicensingAgreement, person=self.person).one()
113 if relicensing_agreement is None:114 if relicensing_agreement is None:
114 return None115 return None
115 else:116 else:
@@ -123,8 +124,8 @@ class TranslationsPerson:
123124
124 If they have already made a decision, overrides it with the new one.125 If they have already made a decision, overrides it with the new one.
125 """126 """
126 relicensing_agreement = TranslationRelicensingAgreement.selectOneBy(127 relicensing_agreement = IStore(TranslationRelicensingAgreement).find(
127 person=self.person)128 TranslationRelicensingAgreement, person=self.person).one()
128 if relicensing_agreement is None:129 if relicensing_agreement is None:
129 relicensing_agreement = TranslationRelicensingAgreement(130 relicensing_agreement = TranslationRelicensingAgreement(
130 person=self.person,131 person=self.person,
diff --git a/lib/lp/translations/scripts/fix_plural_forms.py b/lib/lp/translations/scripts/fix_plural_forms.py
index 8d264ae..df8e25c 100644
--- a/lib/lp/translations/scripts/fix_plural_forms.py
+++ b/lib/lp/translations/scripts/fix_plural_forms.py
@@ -11,12 +11,11 @@ __all__ = [
1111
12from sqlobject import SQLObjectNotFound12from sqlobject import SQLObjectNotFound
1313
14from lp.services.database.sqlbase import (14from lp.services.database.interfaces import IStore
15 cursor,15from lp.services.database.sqlbase import cursor
16 sqlvalues,
17 )
18from lp.translations.interfaces.translations import TranslationConstants16from lp.translations.interfaces.translations import TranslationConstants
19from lp.translations.model.pofile import POFile17from lp.translations.model.pofile import POFile
18from lp.translations.model.potmsgset import POTMsgSet
20from lp.translations.model.translationmessage import TranslationMessage19from lp.translations.model.translationmessage import TranslationMessage
21from lp.translations.utilities.gettext_po_parser import POHeader20from lp.translations.utilities.gettext_po_parser import POHeader
22from lp.translations.utilities.pluralforms import plural_form_mapper21from lp.translations.utilities.pluralforms import plural_form_mapper
@@ -49,11 +48,11 @@ def fix_pofile_plurals(pofile, logger, ztm):
49 plural_forms_mapping = get_mapping_for_pofile_plurals(pofile)48 plural_forms_mapping = get_mapping_for_pofile_plurals(pofile)
50 if plural_forms_mapping is not None:49 if plural_forms_mapping is not None:
51 logger.info("Fixing PO file %s" % pofile.title)50 logger.info("Fixing PO file %s" % pofile.title)
52 pluralmessages = TranslationMessage.select("""51 pluralmessages = IStore(TranslationMessage).find(
53 POTMsgSet.id = TranslationMessage.potmsgset AND52 TranslationMessage,
54 POTMsgSet.msgid_plural IS NOT NULL AND53 TranslationMessage.potmsgset == POTMsgSet.id,
55 TranslationMessage.pofile = %s""" % sqlvalues(pofile),54 POTMsgSet.msgid_plural != None,
56 clauseTables=["POTMsgSet"])55 TranslationMessage.pofile == pofile)
57 for message in pluralmessages:56 for message in pluralmessages:
58 logger.debug("\tFixing translations for '%s'" % (57 logger.debug("\tFixing translations for '%s'" % (
59 message.potmsgset.singular_text))58 message.potmsgset.singular_text))
diff --git a/lib/lp/translations/scripts/gettext_check_messages.py b/lib/lp/translations/scripts/gettext_check_messages.py
index fa6a388..b4e4345 100644
--- a/lib/lp/translations/scripts/gettext_check_messages.py
+++ b/lib/lp/translations/scripts/gettext_check_messages.py
@@ -11,13 +11,12 @@ from datetime import (
11 )11 )
1212
13import six13import six
14from zope.component import getUtility14from storm.locals import SQL
15from zope.security.proxy import removeSecurityProxy15from zope.security.proxy import removeSecurityProxy
1616
17from lp.services.database.interfaces import IStore
17from lp.services.scripts.base import LaunchpadScript18from lp.services.scripts.base import LaunchpadScript
18from lp.translations.interfaces.translationmessage import (19from lp.translations.model.translationmessage import TranslationMessage
19 ITranslationMessageSet,
20 )
21from lp.translations.utilities.validate import (20from lp.translations.utilities.validate import (
22 GettextValidationError,21 GettextValidationError,
23 validate_translation,22 validate_translation,
@@ -66,8 +65,11 @@ class GettextCheckMessages(LaunchpadScript):
66 self.logger.debug(65 self.logger.debug(
67 "Checking messages matching: %s" % self.options.where)66 "Checking messages matching: %s" % self.options.where)
6867
69 messages = getUtility(ITranslationMessageSet).selectDirect(68 messages = IStore(TranslationMessage).find(TranslationMessage)
70 self.options.where, order_by=self.options.order_by)69 if self.options.where is not None:
70 messages = messages.find(SQL(self.options.where))
71 if self.options.order_by is not None:
72 messages = messages.order_by(SQL(self.options.order_by))
71 self._iterate(messages)73 self._iterate(messages)
7274
73 self.logger.info("Done.")75 self.logger.info("Done.")
diff --git a/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt b/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
index 8e9f427..9c15385 100644
--- a/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
+++ b/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
@@ -294,12 +294,13 @@ Ubuntu uploads
294As a special case, the owners of Ubuntu's translation group are allowed294As a special case, the owners of Ubuntu's translation group are allowed
295to manage Ubuntu uploads.295to manage Ubuntu uploads.
296296
297 >>> from lp.registry.model.distribution import Distribution297 >>> from zope.component import getUtility
298 >>> from lp.registry.interfaces.distribution import IDistributionSet
298 >>> from lp.translations.model.translationimportqueue import (299 >>> from lp.translations.model.translationimportqueue import (
299 ... TranslationImportQueue)300 ... TranslationImportQueue)
300 >>> login('admin@canonical.com')301 >>> login('admin@canonical.com')
301 >>> queue = TranslationImportQueue()302 >>> queue = TranslationImportQueue()
302 >>> ubuntu = Distribution.selectOneBy(name='ubuntu')303 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
303 >>> hoary = ubuntu['hoary']304 >>> hoary = ubuntu['hoary']
304305
305There is a translation group for Ubuntu. Its owner has no special306There is a translation group for Ubuntu. Its owner has no special
@@ -307,17 +308,16 @@ privileges or roles other than running the group.
307308
308Somebody else has uploaded a translation template for an Ubuntu package.309Somebody else has uploaded a translation template for an Ubuntu package.
309310
310 >>> login(ANONYMOUS)
311
312 >>> package = factory.makeSourcePackageName()311 >>> package = factory.makeSourcePackageName()
313 >>> group_owner = factory.makePerson(312 >>> group_owner = factory.makePerson(
314 ... email='go@example.com', name='groupowner')313 ... email='go@example.com', name='groupowner')
315 >>> uploader = factory.makePerson()314 >>> uploader = factory.makePerson()
316 >>> ubuntu.translationgroup = factory.makeTranslationGroup(group_owner)315 >>> ubuntu.translationgroup = factory.makeTranslationGroup(group_owner)
316
317 >>> login(ANONYMOUS)
317 >>> ubuntu_upload = queue.addOrUpdateEntry(318 >>> ubuntu_upload = queue.addOrUpdateEntry(
318 ... 'messages.pot', b'(content)', False, uploader,319 ... 'messages.pot', b'(content)', False, uploader,
319 ... sourcepackagename=package, distroseries=hoary)320 ... sourcepackagename=package, distroseries=hoary)
320
321 >>> logout()321 >>> logout()
322322
323The owner of Ubuntu's translation group, despite not being the owner or323The owner of Ubuntu's translation group, despite not being the owner or
diff --git a/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt b/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
index bf9852a..59a9600 100644
--- a/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
+++ b/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
@@ -186,10 +186,11 @@ Distribution templates
186Distributions get slightly wider permissions to manage their templates186Distributions get slightly wider permissions to manage their templates
187autonomously.187autonomously.
188188
189 >>> from lp.registry.model.distribution import Distribution189 >>> from zope.component import getUtility
190 >>> from lp.registry.interfaces.distribution import IDistributionSet
190 >>> from lp.translations.model.potemplate import POTemplateSet191 >>> from lp.translations.model.potemplate import POTemplateSet
191 >>> login('admin@canonical.com')192 >>> login('admin@canonical.com')
192 >>> ubuntu = Distribution.selectOneBy(name='ubuntu')193 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
193 >>> hoary = ubuntu['hoary']194 >>> hoary = ubuntu['hoary']
194 >>> templateset = POTemplateSet()195 >>> templateset = POTemplateSet()
195196
@@ -201,6 +202,7 @@ autonomously.
201 >>> template = templatesubset.new(202 >>> template = templatesubset.new(
202 ... 'foo', 'foo', 'foo.pot', template_owner)203 ... 'foo', 'foo', 'foo.pot', template_owner)
203204
205 >>> login('admin@canonical.com')
204 >>> distro_owner = factory.makePerson('do@example.com')206 >>> distro_owner = factory.makePerson('do@example.com')
205 >>> ubuntu.owner = distro_owner207 >>> ubuntu.owner = distro_owner
206208
diff --git a/lib/lp/translations/stories/standalone/xx-translation-access-display.txt b/lib/lp/translations/stories/standalone/xx-translation-access-display.txt
index d374966..adcc0bd 100644
--- a/lib/lp/translations/stories/standalone/xx-translation-access-display.txt
+++ b/lib/lp/translations/stories/standalone/xx-translation-access-display.txt
@@ -38,20 +38,25 @@ translation group of its own, that too is shown here.
3838
39 >>> import re39 >>> import re
4040
41 >>> from zope.component import getUtility
42 >>> from zope.security.proxy import removeSecurityProxy
43
41 >>> from lp.services.database.constants import UTC_NOW44 >>> from lp.services.database.constants import UTC_NOW
42 >>> from lp.registry.model.person import Person45 >>> from lp.registry.interfaces.person import IPersonSet
43 >>> from lp.registry.model.product import Product46 >>> from lp.registry.interfaces.product import IProductSet
44 >>> from lp.services.worlddata.model.language import Language47 >>> from lp.services.worlddata.interfaces.language import ILanguageSet
45 >>> from lp.translations.model.translationgroup import (48 >>> from lp.translations.model.translationgroup import (
46 ... TranslationGroup)49 ... TranslationGroup)
4750
48 >>> spanish = Language.selectOneBy(code='es')51 >>> login('admin@canonical.com')
49 >>> evolution = Product.selectOneBy(name='evolution')52 >>> spanish = getUtility(ILanguageSet)['es']
50 >>> foobar = Person.selectOneBy(name='name16')53 >>> evolution = removeSecurityProxy(getUtility(IProductSet)['evolution'])
54 >>> foobar = getUtility(IPersonSet).getByName('name16')
51 >>> gnomegroup = TranslationGroup(name='gnomegroup',55 >>> gnomegroup = TranslationGroup(name='gnomegroup',
52 ... title="Gnome translation group", summary="Testing group",56 ... title="Gnome translation group", summary="Testing group",
53 ... datecreated=UTC_NOW, owner=foobar)57 ... datecreated=UTC_NOW, owner=foobar)
54 >>> evolution.projectgroup.translationgroup = gnomegroup58 >>> evolution.projectgroup.translationgroup = gnomegroup
59 >>> logout()
5560
56 >>> admin_browser.open(61 >>> admin_browser.open(
57 ... 'http://translations.launchpad.test/'62 ... 'http://translations.launchpad.test/'

Subscribers

People subscribed via source and target branches

to status/vote changes: