launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02557
[Merge] lp:~abentley/launchpad/share-on-link into lp:launchpad
Aaron Bentley has proposed merging lp:~abentley/launchpad/share-on-link into lp:launchpad with lp:~abentley/launchpad/sharingKey as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~abentley/launchpad/share-on-link/+merge/49092
= Summary =
Implement a Job that merges translations between a product and sourcepackage.
== Proposed fix ==
See above
== Pre-implementation notes ==
None
== Implementation details ==
This builds on the prerequisite branches to introduce TranslationMergeJob.
When the job is run, it merges the translations among the templates.
== Tests ==
bin/test -v test_translationmergejob
== Demo and Q/A ==
None
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/translations/tests/test_potemplate.py
lib/lp/translations/interfaces/potemplate.py
lib/lp/translations/tests/test_translationmerger.py
lib/lp/translations/translationmerger.py
lib/lp/translations/model/translationmergejob.py
lib/lp/translations/tests/test_translationmergejob.py
lib/lp/translations/model/potemplate.py
scripts/rosetta/message-sharing-merge.py
./scripts/rosetta/message-sharing-merge.py
10: '_pythonpath' imported but unused
24: E303 too many blank lines (3)
--
https://code.launchpad.net/~abentley/launchpad/share-on-link/+merge/49092
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~abentley/launchpad/share-on-link into lp:launchpad.
=== added file 'lib/lp/translations/model/translationmergejob.py'
--- lib/lp/translations/model/translationmergejob.py 1970-01-01 00:00:00 +0000
+++ lib/lp/translations/model/translationmergejob.py 2011-02-09 17:04:02 +0000
@@ -0,0 +1,54 @@
+# Copyright 2011 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Job for merging translations."""
+
+__metaclass__ = type
+
+
+from zope.interface import implements
+
+from lp.services.job.interfaces.job import IRunnableJob
+from lp.services.job.runner import BaseRunnableJob
+from lp.translations.model.potemplate import POTemplate, POTemplateSubset
+from lp.translations.translationmerger import (
+ TransactionManager,
+ TranslationMerger,
+ )
+
+__all__ = ['TranslationMergeJob']
+
+
+class TranslationMergeJob(BaseRunnableJob):
+ """Job for merging translations between a product and sourcepackage."""
+
+ implements(IRunnableJob)
+
+ def __init__(self, job, productseries, distroseries, sourcepackagename):
+ """"Constructor.
+
+ :param job: The `Job` to use for storing basic job state.
+ :param productseries: The ProductSeries side of the Packaging.
+ :param distroseries: The distroseries of the Packaging sourcepackage.
+ :param sourcepackagename: The name of the Packaging sourcepackage.
+ """
+ self.job = job
+ self.distroseries = distroseries
+ self.sourcepackagename = sourcepackagename
+ self.productseries = productseries
+
+ def run(self):
+ """See `IRunnableJob`."""
+ template_map = dict()
+ tm = TransactionManager(None, False)
+ all_templates = list(POTemplateSubset(
+ sourcepackagename=self.sourcepackagename,
+ distroseries=self.distroseries))
+ all_templates.extend(POTemplateSubset(
+ productseries=self.productseries))
+ for template in all_templates:
+ template_map.setdefault(template.name, []).append(template)
+ for name, templates in template_map.iteritems():
+ templates.sort(key=POTemplate.sharingKey, reverse=True)
+ merger = TranslationMerger(templates, tm)
+ merger.mergePOTMsgSets()
=== added file 'lib/lp/translations/tests/test_translationmergejob.py'
--- lib/lp/translations/tests/test_translationmergejob.py 1970-01-01 00:00:00 +0000
+++ lib/lp/translations/tests/test_translationmergejob.py 2011-02-09 17:04:02 +0000
@@ -0,0 +1,104 @@
+# Copyright 2011 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for merging translations."""
+
+__metaclass__ = type
+
+
+from canonical.launchpad.webapp.testing import verifyObject
+from canonical.testing.layers import (
+ LaunchpadZopelessLayer,
+ )
+from lp.services.job.interfaces.job import IRunnableJob
+from lp.services.job.model.job import Job
+from lp.testing import TestCaseWithFactory
+from lp.translations.interfaces.side import TranslationSide
+from lp.translations.model.potemplate import POTemplateSubset
+from lp.translations.model.translationmergejob import TranslationMergeJob
+
+
+class TestTranslationMergeJob(TestCaseWithFactory):
+
+ layer = LaunchpadZopelessLayer
+
+ def makeTranslationMergeJob(self):
+ singular = self.factory.getUniqueString()
+ upstream_pofile = self.factory.makePOFile(
+ side=TranslationSide.UPSTREAM)
+ upstream_potmsgset = self.factory.makePOTMsgSet(
+ upstream_pofile.potemplate, singular, sequence=1)
+ upstream = self.factory.makeCurrentTranslationMessage(
+ pofile=upstream_pofile, potmsgset=upstream_potmsgset)
+ ubuntu_potemplate = self.factory.makePOTemplate(
+ side=TranslationSide.UBUNTU, name=upstream_pofile.potemplate.name)
+ ubuntu_pofile = self.factory.makePOFile(
+ potemplate=ubuntu_potemplate, language=upstream_pofile.language)
+ ubuntu_potmsgset = self.factory.makePOTMsgSet(
+ ubuntu_pofile.potemplate, singular, sequence=1)
+ ubuntu = self.factory.makeCurrentTranslationMessage(
+ pofile=ubuntu_pofile, potmsgset=ubuntu_potmsgset,
+ translations=upstream.translations)
+ productseries = upstream_pofile.potemplate.productseries
+ distroseries = ubuntu_pofile.potemplate.distroseries
+ sourcepackagename = ubuntu_pofile.potemplate.sourcepackagename
+ return TranslationMergeJob(
+ Job(), productseries, distroseries, sourcepackagename)
+
+ def test_interface(self):
+ """TranslationMergeJob must implement IRunnableJob."""
+ job = self.makeTranslationMergeJob()
+ verifyObject(IRunnableJob, job)
+
+ @staticmethod
+ def getMsgSets(productseries=None, distroseries=None,
+ sourcepackagename=None):
+ msg_sets = []
+ for template in POTemplateSubset(
+ productseries=productseries, distroseries=distroseries,
+ sourcepackagename=sourcepackagename):
+ msg_sets.extend(template.getPOTMsgSets())
+ return msg_sets
+
+ @classmethod
+ def getTranslations(cls, productseries=None, distroseries=None,
+ sourcepackagename=None):
+ msg_sets = cls.getMsgSets(
+ productseries=productseries, distroseries=distroseries,
+ sourcepackagename=sourcepackagename)
+ translations = set()
+ for msg_set in msg_sets:
+ translations.update(msg_set.getAllTranslationMessages())
+ return translations
+
+ @classmethod
+ def countTranslations(cls, job):
+ tm = cls.getTranslations(productseries=job.productseries)
+ tm.update(cls.getTranslations(
+ sourcepackagename=job.sourcepackagename,
+ distroseries=job.distroseries))
+ return len(tm)
+
+ def test_run_merges_msgset(self):
+ """Run should merge msgsets."""
+ job = self.makeTranslationMergeJob()
+ self.becomeDbUser('rosettaadmin')
+ product_msg = self.getMsgSets(productseries=job.productseries)
+ package_msg = self.getMsgSets(
+ sourcepackagename=job.sourcepackagename,
+ distroseries=job.distroseries)
+ self.assertNotEqual(package_msg, product_msg)
+ job.run()
+ product_msg = self.getMsgSets(productseries=job.productseries)
+ package_msg = self.getMsgSets(
+ sourcepackagename=job.sourcepackagename,
+ distroseries=job.distroseries)
+ self.assertEqual(package_msg, product_msg)
+
+ def test_run_merges_translations(self):
+ """Run should merge translations."""
+ job = self.makeTranslationMergeJob()
+ self.becomeDbUser('rosettaadmin')
+ self.assertEqual(2, self.countTranslations(job))
+ job.run()
+ self.assertEqual(1, self.countTranslations(job))