launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #16091
[Merge] lp:~ursinha/launchpad/qa-bad-bug-1201485-rebased into lp:launchpad
Ursula Junque has proposed merging lp:~ursinha/launchpad/qa-bad-bug-1201485-rebased into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1201485 in Launchpad itself: "Need to import translations for the unity daily builds"
https://bugs.launchpad.net/launchpad/+bug/1201485
For more details, see:
https://code.launchpad.net/~ursinha/launchpad/qa-bad-bug-1201485-rebased/+merge/191077
This branch fixes the problem of outdated translations in packages copied from PPAs to the main archive. First attempt of fixing it failed, as copies don't have sourcepackagereleases directly linked to them. Added tests to check the copies behavior as well.
It creates a CustomUpload for Rosetta Translations, and adds PackageUploadCustomFormat.ROSETTA_TRANSLATIONS to the list of custom copyable files, so the translations from copied packages will be copied, uploaded and processed as well.
Tests:
./bin/test -vvt lp.soyuz.tests.test_distroseriesqueue_rosetta_translations.*
./bin/test -vvt lp.archivepublisher.tests.test_rosetta_translations.*
./bin/test -vvt lp.soyuz.scripts.tests.test_custom_uploads.copier.*
./bin/test -vvt lp.soyuz.tests.test_packagecopyjob.*
This also adds test data to lib/lp/archiveuploader/tests/data/rosetta-translations, to run end-to-end tests.
--
https://code.launchpad.net/~ursinha/launchpad/qa-bad-bug-1201485-rebased/+merge/191077
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~ursinha/launchpad/qa-bad-bug-1201485-rebased into lp:launchpad.
=== added file 'lib/lp/archivepublisher/rosetta_translations.py'
--- lib/lp/archivepublisher/rosetta_translations.py 1970-01-01 00:00:00 +0000
+++ lib/lp/archivepublisher/rosetta_translations.py 2013-10-14 23:28:23 +0000
@@ -0,0 +1,117 @@
+# Copyright 2009-2013 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""The processing of Rosetta translations tarballs.
+
+ROSETTA-TRANSLATIONS is a custom format upload supported by Launchpad
+infrastructure to enable developers to publish translations.
+"""
+
+__metaclass__ = type
+
+__all__ = [
+ 'RosettaTranslationsUpload',
+ 'process_rosetta_translations',
+ ]
+
+from zope.component import getUtility
+
+from lp.app.interfaces.launchpad import ILaunchpadCelebrities
+from lp.archivepublisher.customupload import CustomUpload
+from lp.archivepublisher.debversion import Version
+from lp.registry.interfaces.pocket import PackagePublishingPocket
+from lp.soyuz.interfaces.archive import MAIN_ARCHIVE_PURPOSES
+from lp.soyuz.interfaces.packagetranslationsuploadjob import (
+ IPackageTranslationsUploadJobSource,
+ )
+
+
+class RosettaTranslationsUpload(CustomUpload):
+ """Rosetta Translations tarball upload.
+
+ All other CustomUploads extract and copy files when processed,
+ RosettaTranslationsUpload is a special case that involves more than
+ copying the files, so it triggers a job that processes them accordingly.
+ For this reason, all methods from CustomUpload that deal with files are
+ bypassed.
+ """
+ custom_type = "rosetta-translations"
+
+ def process(self, packageupload, libraryfilealias):
+ self.tarfile_path = libraryfilealias.filename
+ # Ignore translations not with main distribution purposes.
+ if packageupload.archive.purpose not in MAIN_ARCHIVE_PURPOSES:
+ if self.logger is not None:
+ self.logger.debug(
+ "Skipping translations since its purpose is not "
+ "in MAIN_ARCHIVE_PURPOSES.")
+ return
+
+ # If the distroseries is 11.10 (oneiric) or later, the valid names
+ # check is not required. (See bug 788685.)
+ distroseries = packageupload.distroseries
+ do_names_check = Version(distroseries.version) < Version('11.10')
+
+ latest_publication = self._findSourcePublication(packageupload)
+ component_name = latest_publication.component.name
+ sourcepackagerelease = latest_publication.sourcepackagerelease
+
+ valid_pockets = (
+ PackagePublishingPocket.RELEASE, PackagePublishingPocket.SECURITY,
+ PackagePublishingPocket.UPDATES, PackagePublishingPocket.PROPOSED)
+ valid_components = ('main', 'restricted')
+ if (packageupload.pocket not in valid_pockets or
+ (do_names_check and
+ component_name not in valid_components)):
+ # XXX: CarlosPerelloMarin 2006-02-16 bug=31665:
+ # This should be implemented using a more general rule to accept
+ # different policies depending on the distribution.
+ # Ubuntu's MOTU told us that they are not able to handle
+ # translations like we do in main. We are going to import only
+ # packages in main.
+ return
+
+ blamee = packageupload.findPersonToNotify()
+ if blamee is None:
+ blamee = getUtility(ILaunchpadCelebrities).rosetta_experts
+ getUtility(IPackageTranslationsUploadJobSource).create(
+ packageupload, sourcepackagerelease, libraryfilealias, blamee)
+
+ @staticmethod
+ def parsePath(tarfile_name):
+ """Parses the lfa filename."""
+ bits = tarfile_name.split("_")
+ if len(bits) != 4:
+ raise ValueError(
+ "%s is not NAME_VERSION_ARCH_translations.tar.gz" %
+ tarfile_name)
+ return tuple(bits)
+
+ def setComponents(self, tarfile_name):
+ """Sets the package name parsed from the lfa filename."""
+ self.package_name = self.parsePath(tarfile_name)[0]
+
+ def setTargetDirectory(self, pubconf, tarfile_path, distroseries):
+ pass
+
+ @classmethod
+ def getSeriesKey(cls, tarfile_path):
+ pass
+
+ def shouldInstall(self, filename):
+ pass
+
+ def _findSourcePublication(self, packageupload):
+ """Find destination source publishing record of the packageupload."""
+ if packageupload.package_name is None:
+ self.setComponents(self.tarfile_path)
+ return packageupload.archive.getPublishedSources(
+ name=packageupload.package_name, exact_match=True,
+ distroseries=packageupload.distroseries,
+ pocket=packageupload.pocket).first()
+
+
+def process_rosetta_translations(packageupload, libraryfilealias, logger=None):
+ """Process a Rosetta translation upload."""
+ upload = RosettaTranslationsUpload(logger)
+ upload.process(packageupload, libraryfilealias)
=== added file 'lib/lp/archivepublisher/tests/test_rosetta_translations.py'
--- lib/lp/archivepublisher/tests/test_rosetta_translations.py 1970-01-01 00:00:00 +0000
+++ lib/lp/archivepublisher/tests/test_rosetta_translations.py 2013-10-14 23:28:23 +0000
@@ -0,0 +1,176 @@
+# Copyright 2013 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Test rosetta-translations custom uploads.
+
+See also lp.soyuz.tests.test_distroseriesqueue_rosetta_translations for
+high-level tests of rosetta-translations upload and queue manipulation.
+"""
+
+import transaction
+from zope.security.proxy import removeSecurityProxy
+from zope.component import getUtility
+
+from lp.archivepublisher.rosetta_translations import (
+ process_rosetta_translations,
+ )
+from lp.registry.interfaces.pocket import PackagePublishingPocket
+from lp.services.tarfile_helpers import LaunchpadWriteTarFile
+from lp.soyuz.enums import (
+ ArchivePurpose,
+ PackageUploadCustomFormat,
+ PackageUploadStatus,
+ SourcePackageFormat,
+ )
+from lp.soyuz.interfaces.sourcepackageformat import (
+ ISourcePackageFormatSelectionSet,
+ )
+from lp.soyuz.model.packagetranslationsuploadjob import (
+ PackageTranslationsUploadJob,
+ )
+from lp.testing import TestCaseWithFactory, person_logged_in
+from lp.testing.layers import LaunchpadZopelessLayer
+
+
+class TestRosettaTranslations(TestCaseWithFactory):
+
+ layer = LaunchpadZopelessLayer
+
+ def makeTranslationsLFA(self, tar_content=None, filename=None):
+ """Create an LibraryFileAlias containing dummy translation data."""
+ if tar_content is None:
+ tar_content = {
+ 'source/po/foo.pot': 'Foo template',
+ 'source/po/eo.po': 'Foo translation',
+ }
+ tarfile_content = LaunchpadWriteTarFile.files_to_string(
+ tar_content)
+ return self.factory.makeLibraryFileAlias(content=tarfile_content,
+ filename=filename)
+
+ def makeAndPublishSourcePackage(self, sourcepackagename, distroseries,
+ archive=None):
+ self.factory.makeSourcePackage(
+ sourcepackagename=sourcepackagename,
+ distroseries=distroseries)
+ if archive is None:
+ archive = distroseries.main_archive
+ spph = self.factory.makeSourcePackagePublishingHistory(
+ distroseries=distroseries,
+ archive=archive,
+ sourcepackagename=sourcepackagename,
+ pocket=PackagePublishingPocket.RELEASE)
+ return spph
+
+ def makeJobElements(self):
+ distroseries = self.factory.makeDistroSeries()
+ sourcepackagename = "foo"
+ sourcepackage_version = "3.8.2-1ubuntu1"
+ filename = "%s_%s_i386_translations.tar.gz" % (sourcepackagename,
+ sourcepackage_version)
+
+ spph = self.makeAndPublishSourcePackage(
+ sourcepackagename=sourcepackagename, distroseries=distroseries)
+ packageupload = removeSecurityProxy(self.factory.makePackageUpload(
+ distroseries=distroseries,
+ archive=distroseries.main_archive))
+ packageupload.addSource(spph.sourcepackagerelease)
+
+ libraryfilealias = self.makeTranslationsLFA(filename=filename)
+ return spph.sourcepackagerelease, packageupload, libraryfilealias
+
+ def makeJobElementsFromCopyJob(self):
+ sourcepackage_version = "3.8.2-1ubuntu1"
+
+ das = self.factory.makeDistroArchSeries()
+ distroseries = das.distroseries
+ distroseries.nominatedarchindep = das
+ getUtility(ISourcePackageFormatSelectionSet).add(distroseries,
+ SourcePackageFormat.FORMAT_1_0)
+
+ bpb = self.factory.makeBinaryPackageBuild(
+ distroarchseries=distroseries.nominatedarchindep,
+ archive=self.factory.makeArchive(purpose=ArchivePurpose.PPA),
+ pocket=PackagePublishingPocket.RELEASE)
+ bpr = self.factory.makeBinaryPackageRelease(build=bpb)
+ self.factory.makeBinaryPackagePublishingHistory(
+ binarypackagerelease=bpr, distroarchseries=bpb.distro_arch_series,
+ archive=bpb.archive, pocket=bpb.pocket)
+ bin_pu = self.factory.makePackageUpload(
+ status=PackageUploadStatus.DONE, archive=bpb.archive,
+ distroseries=distroseries)
+ bin_pu.addBuild(bpb)
+
+ filename = "%s_%s_i386_translations.tar.gz" % (
+ bpb.source_package_release.sourcepackagename.name,
+ sourcepackage_version)
+
+ libraryfilealias = self.makeTranslationsLFA(filename=filename)
+ bin_pu.addCustom(
+ libraryfilealias, PackageUploadCustomFormat.ROSETTA_TRANSLATIONS)
+
+ # Create ancestry in the target to avoid hitting New.
+ spph_target = self.factory.makeSourcePackagePublishingHistory(
+ sourcepackagename=bpb.source_package_release.sourcepackagename,
+ version='0', archive=distroseries.main_archive,
+ distroseries=distroseries, pocket=PackagePublishingPocket.RELEASE)
+
+ target_archive = distroseries.main_archive
+
+ admin = self.factory.makePerson(name="john")
+ with person_logged_in(target_archive.owner):
+ component = spph_target.component.name
+ target_archive.newComponentUploader(admin, component)
+ pass
+
+ spr = bpb.source_package_release
+ job = self.factory.makePlainPackageCopyJob(
+ package_name=spr.sourcepackagename.name,
+ package_version=spr.version, source_archive=bpb.archive,
+ target_archive=distroseries.main_archive,
+ target_distroseries=distroseries,
+ target_pocket=PackagePublishingPocket.RELEASE,
+ requester=admin, include_binaries=True)
+
+ job.run()
+
+ from storm.expr import Desc
+ from lp.soyuz.model.queue import PackageUpload
+ from lp.services.database.interfaces import IStore
+ upload = IStore(PackageUpload).find(PackageUpload).order_by(
+ Desc(PackageUpload.id)).first()
+
+ return spr, upload, libraryfilealias
+
+ def test_basic_from_copy(self):
+ spr, pu, lfa = self.makeJobElementsFromCopyJob()
+ transaction.commit()
+ process_rosetta_translations(pu, lfa)
+
+ def test_basic_from_upload(self):
+ spr, pu, lfa = self.makeJobElements()
+ transaction.commit()
+ process_rosetta_translations(pu, lfa)
+
+ def test_correct_job_is_created_from_upload(self):
+ spr, packageupload, libraryfilealias = self.makeJobElements()
+ transaction.commit()
+ process_rosetta_translations(packageupload, libraryfilealias)
+
+ jobs = list(PackageTranslationsUploadJob.iterReady())
+ self.assertEqual(1, len(jobs))
+
+ self.assertEqual(spr, jobs[0].sourcepackagerelease)
+ self.assertEqual(libraryfilealias, jobs[0].libraryfilealias)
+
+ def test_correct_job_is_created_from_copy(self):
+ spr, packageupload, libraryfilealias = (
+ self.makeJobElementsFromCopyJob())
+ transaction.commit()
+ process_rosetta_translations(packageupload, libraryfilealias)
+
+ jobs = list(PackageTranslationsUploadJob.iterReady())
+ self.assertEqual(1, len(jobs))
+
+ self.assertEqual(spr, jobs[0].sourcepackagerelease)
+ self.assertEqual(libraryfilealias, jobs[0].libraryfilealias)
=== modified file 'lib/lp/archiveuploader/nascentuploadfile.py'
--- lib/lp/archiveuploader/nascentuploadfile.py 2013-10-02 02:59:38 +0000
+++ lib/lp/archiveuploader/nascentuploadfile.py 2013-10-14 23:28:23 +0000
@@ -32,6 +32,7 @@
from lp.archivepublisher.ddtp_tarball import DdtpTarballUpload
from lp.archivepublisher.debian_installer import DebianInstallerUpload
from lp.archivepublisher.dist_upgrader import DistUpgraderUpload
+from lp.archivepublisher.rosetta_translations import RosettaTranslationsUpload
from lp.archivepublisher.uefi import UefiUpload
from lp.archiveuploader.utils import (
determine_source_file_type,
@@ -263,6 +264,8 @@
PackageUploadCustomFormat.DEBIAN_INSTALLER: DebianInstallerUpload,
PackageUploadCustomFormat.DIST_UPGRADER: DistUpgraderUpload,
PackageUploadCustomFormat.DDTP_TARBALL: DdtpTarballUpload,
+ PackageUploadCustomFormat.ROSETTA_TRANSLATIONS:
+ RosettaTranslationsUpload,
PackageUploadCustomFormat.UEFI: UefiUpload,
}
=== added directory 'lib/lp/archiveuploader/tests/data/rosetta-translations'
=== added file 'lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386.changes'
--- lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386.changes 1970-01-01 00:00:00 +0000
+++ lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386.changes 2013-10-14 23:28:23 +0000
@@ -0,0 +1,26 @@
+Format: 1.8
+Date: Fri, 13 Sep 2013 18:06:21 +0000
+Source: pmount
+Binary: pmount
+Architecture: i386 i386_translations
+Version: 0.9.20-2ubuntu0.2
+Distribution: breezy-autotest
+Urgency: low
+Maintainer: Ubuntu Build Daemon <buildd@lpdev>
+Changed-By: Foo Bar <foo.bar@xxxxxxxxxxxxx>
+Description:
+ pmount - mount removable devices as normal user
+Changes:
+ pmount (0.9.20-2ubuntu0.2) breezy-autotest; urgency=low
+ .
+ * Boooo
+Checksums-Sha1:
+ 17e907a47a080ecd17e05b1cdda84577356922ec 112354 pmount_0.9.20-2ubuntu0.2_i386.deb
+ e86c8bce3ebf21354ac06207eeb08a513143a89d 35535 pmount_0.9.20-2ubuntu0.2_i386_translations.tar.gz
+Checksums-Sha256:
+ 97ffd0d39d38d7e644214b44f8cda80a1e1f7706655c81980361960d0f3846e4 112354 pmount_0.9.20-2ubuntu0.2_i386.deb
+ efce09a62dc4be2d053cbb7acaa5b2d481fd88c0e512c53b7ebc6d1d49210d7d 35535 pmount_0.9.20-2ubuntu0.2_i386_translations.tar.gz
+Files:
+ 8a61eb49d42d4ee7eb7ac6fe3fb0c1e3 112354 utils optional pmount_0.9.20-2ubuntu0.2_i386.deb
+ 0cd445544a6caa3ce9b665e80aeb0093 35535 raw-translations - pmount_0.9.20-2ubuntu0.2_i386_translations.tar.gz
+Original-Maintainer: Vincent Fourmond <fourmond@xxxxxxxxxx>
=== added file 'lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386.deb'
Binary files lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386.deb 1970-01-01 00:00:00 +0000 and lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386.deb 2013-10-14 23:28:23 +0000 differ
=== added file 'lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386_translations.tar.gz'
Binary files lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386_translations.tar.gz 1970-01-01 00:00:00 +0000 and lib/lp/archiveuploader/tests/data/rosetta-translations/pmount_0.9.20-2ubuntu0.2_i386_translations.tar.gz 2013-10-14 23:28:23 +0000 differ
=== modified file 'lib/lp/soyuz/doc/distroseriesqueue-translations.txt'
--- lib/lp/soyuz/doc/distroseriesqueue-translations.txt 2013-09-11 06:05:44 +0000
+++ lib/lp/soyuz/doc/distroseriesqueue-translations.txt 2013-10-14 23:28:23 +0000
@@ -158,6 +158,14 @@
>>> from lp.soyuz.enums import PackageUploadStatus
>>> queue_item = dapper.getPackageUploads(
... status=PackageUploadStatus.NEW)[0]
+
+The source package needs to be published because rosetta translations
+publisher will query for the latest publication to know the destination
+component.
+
+ >>> spph = factory.makeSourcePackagePublishingHistory(
+ ... sourcepackagerelease=queue_item.sourcepackagerelease,
+ ... distroseries=queue_item.distroseries, pocket=queue_item.pocket)
>>> queue_item.customfiles[0].publish()
When publish() runs, it creates a PackageTranslationsUploadJob that will
@@ -169,22 +177,24 @@
>>> runPendingPackageTranslationsUploadJob()
-As we can see from the translation import queue content.
+As we can see from the translation import queue content. The importer isn't
+the sourcepackagerelease creator, but the person pointed by
+findPersonToNotify, or rosetta-admins.
>>> for entry in translation_import_queue.getAllEntries(target=ubuntu):
... print '%s/%s by %s: %s' % (
... entry.distroseries.name, entry.sourcepackagename.name,
... entry.importer.name, entry.path)
- dapper/pmount by ubuntu-team: po/es_ES.po
- dapper/pmount by ubuntu-team: po/ca.po
- dapper/pmount by ubuntu-team: po/de.po
- dapper/pmount by ubuntu-team: po/cs.po
- dapper/pmount by ubuntu-team: po/es.po
- dapper/pmount by ubuntu-team: po/fr.po
- dapper/pmount by ubuntu-team: po/hr.po
- dapper/pmount by ubuntu-team: po/nb.po
- dapper/pmount by ubuntu-team: po/pmount.pot
- dapper/pmount by ubuntu-team: po/it_IT.po
+ dapper/pmount by rosetta-admins: po/es_ES.po
+ dapper/pmount by rosetta-admins: po/ca.po
+ dapper/pmount by rosetta-admins: po/de.po
+ dapper/pmount by rosetta-admins: po/cs.po
+ dapper/pmount by rosetta-admins: po/es.po
+ dapper/pmount by rosetta-admins: po/fr.po
+ dapper/pmount by rosetta-admins: po/hr.po
+ dapper/pmount by rosetta-admins: po/nb.po
+ dapper/pmount by rosetta-admins: po/pmount.pot
+ dapper/pmount by rosetta-admins: po/it_IT.po
# Abort the transaction so we can check the same upload in a different
# pocket.
@@ -201,6 +211,10 @@
>>> dapper = distro_series_set.queryByName(ubuntu, 'dapper')
>>> queue_item = dapper.getPackageUploads(PackageUploadStatus.NEW)[0]
>>> queue_item.pocket = PackagePublishingPocket.BACKPORTS
+ >>> spph = factory.makeSourcePackagePublishingHistory(
+ ... sourcepackagerelease=queue_item.sourcepackagerelease,
+ ... distroseries=queue_item.distroseries, pocket=queue_item.pocket)
+
>>> queue_item.customfiles[0].publish()
# And this time, we see that there are no entries imported in the queue.
@@ -217,6 +231,10 @@
>>> dapper = distro_series_set.queryByName(ubuntu, 'dapper')
>>> queue_item = dapper.getPackageUploads(PackageUploadStatus.NEW)[0]
>>> queue_item.pocket = PackagePublishingPocket.UPDATES
+ >>> spph = factory.makeSourcePackagePublishingHistory(
+ ... sourcepackagerelease=queue_item.sourcepackagerelease,
+ ... distroseries=queue_item.distroseries, pocket=queue_item.pocket)
+
>>> queue_item.customfiles[0].publish()
>>> runPendingPackageTranslationsUploadJob()
@@ -226,16 +244,16 @@
... print '%s/%s by %s: %s' % (
... entry.distroseries.name, entry.sourcepackagename.name,
... entry.importer.name, entry.path)
- dapper/pmount by ubuntu-team: po/es_ES.po
- dapper/pmount by ubuntu-team: po/ca.po
- dapper/pmount by ubuntu-team: po/de.po
- dapper/pmount by ubuntu-team: po/cs.po
- dapper/pmount by ubuntu-team: po/es.po
- dapper/pmount by ubuntu-team: po/fr.po
- dapper/pmount by ubuntu-team: po/hr.po
- dapper/pmount by ubuntu-team: po/nb.po
- dapper/pmount by ubuntu-team: po/pmount.pot
- dapper/pmount by ubuntu-team: po/it_IT.po
+ dapper/pmount by rosetta-admins: po/es_ES.po
+ dapper/pmount by rosetta-admins: po/ca.po
+ dapper/pmount by rosetta-admins: po/de.po
+ dapper/pmount by rosetta-admins: po/cs.po
+ dapper/pmount by rosetta-admins: po/es.po
+ dapper/pmount by rosetta-admins: po/fr.po
+ dapper/pmount by rosetta-admins: po/hr.po
+ dapper/pmount by rosetta-admins: po/nb.po
+ dapper/pmount by rosetta-admins: po/pmount.pot
+ dapper/pmount by rosetta-admins: po/it_IT.po
# Let's abort the transaction so we can check the same upload in a different
# pocket.
@@ -260,16 +278,16 @@
... print '%s/%s by %s: %s' % (
... entry.distroseries.name, entry.sourcepackagename.name,
... entry.importer.name, entry.path)
- dapper/pmount by ubuntu-team: po/es_ES.po
- dapper/pmount by ubuntu-team: po/ca.po
- dapper/pmount by ubuntu-team: po/de.po
- dapper/pmount by ubuntu-team: po/cs.po
- dapper/pmount by ubuntu-team: po/es.po
- dapper/pmount by ubuntu-team: po/fr.po
- dapper/pmount by ubuntu-team: po/hr.po
- dapper/pmount by ubuntu-team: po/nb.po
- dapper/pmount by ubuntu-team: po/pmount.pot
- dapper/pmount by ubuntu-team: po/it_IT.po
+ dapper/pmount by rosetta-admins: po/es_ES.po
+ dapper/pmount by rosetta-admins: po/ca.po
+ dapper/pmount by rosetta-admins: po/de.po
+ dapper/pmount by rosetta-admins: po/cs.po
+ dapper/pmount by rosetta-admins: po/es.po
+ dapper/pmount by rosetta-admins: po/fr.po
+ dapper/pmount by rosetta-admins: po/hr.po
+ dapper/pmount by rosetta-admins: po/nb.po
+ dapper/pmount by rosetta-admins: po/pmount.pot
+ dapper/pmount by rosetta-admins: po/it_IT.po
# Let's abort the transaction so we can check the same upload in a different
# component.
=== modified file 'lib/lp/soyuz/interfaces/packagetranslationsuploadjob.py'
--- lib/lp/soyuz/interfaces/packagetranslationsuploadjob.py 2013-07-24 13:07:37 +0000
+++ lib/lp/soyuz/interfaces/packagetranslationsuploadjob.py 2013-10-14 23:28:23 +0000
@@ -17,12 +17,23 @@
class IPackageTranslationsUploadJobSource(IJobSource):
"""An interface for acquiring IPackageTranslationsUploadJob."""
- def create(sourcepackagerelease, libraryfilealias, requester):
+ def create(packageupload, sourcepackagerelease, libraryfilealias,
+ requester):
"""Create new translations upload job for a source package release."""
class IPackageTranslationsUploadJob(IRunnableJob):
- """A `Job` that uploads and attaches files to a `ISourcePackageRelease`."""
+ """A `Job` that uploads/attaches files to a `ITranslationsImportQueue`."""
def getErrorRecipients():
"""Return a list of email-ids to notify about upload errors."""
+
+ def attachTranslationFiles(by_maintainer):
+ """Attach a tarball with translations to be imported into Rosetta.
+
+ :by_maintainer: indicates if the imported files where uploaded by
+ the maintainer of the project or package.
+
+ raise DownloadFailed if we are not able to fetch the file from
+ :tarball_alias:.
+ """
=== modified file 'lib/lp/soyuz/interfaces/sourcepackagerelease.py'
--- lib/lp/soyuz/interfaces/sourcepackagerelease.py 2013-01-07 02:40:55 +0000
+++ lib/lp/soyuz/interfaces/sourcepackagerelease.py 2013-10-14 23:28:23 +0000
@@ -209,19 +209,6 @@
argument remains untouched.
"""
- def attachTranslationFiles(tarball_alias, by_maintainer, importer=None):
- """Attach a tarball with translations to be imported into Rosetta.
-
- :tarball_alias: is a Librarian alias that references to a tarball with
- translations.
- :by_maintainer: indicates if the imported files where uploaded by
- the maintainer of the project or package.
- :importer: is the person that did the import.
-
- raise DownloadFailed if we are not able to fetch the file from
- :tarball_alias:.
- """
-
package_diffs = Attribute(
"All `IPackageDiff` generated from this context.")
=== modified file 'lib/lp/soyuz/model/packagetranslationsuploadjob.py'
--- lib/lp/soyuz/model/packagetranslationsuploadjob.py 2013-07-26 08:44:21 +0000
+++ lib/lp/soyuz/model/packagetranslationsuploadjob.py 2013-10-14 23:28:23 +0000
@@ -4,6 +4,7 @@
__metaclass__ = type
__all__ = [
+ '_filter_ubuntu_translation_file',
'PackageTranslationsUploadJob',
]
@@ -29,8 +30,45 @@
IPackageTranslationsUploadJob,
IPackageTranslationsUploadJobSource,
)
+from lp.soyuz.model.queue import PackageUpload
from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
+from lp.translations.interfaces.translationimportqueue import (
+ ITranslationImportQueue,
+ )
+
+
+def _filter_ubuntu_translation_file(filename):
+ """Filter for translation filenames in tarball.
+
+ Grooms filenames of translation files in tarball, returning None or
+ empty string for files that should be ignored.
+
+ Passed to `ITranslationImportQueue.addOrUpdateEntriesFromTarball`.
+ """
+ source_prefix = 'source/'
+ if not filename.startswith(source_prefix):
+ return None
+
+ filename = filename[len(source_prefix):]
+
+ blocked_prefixes = [
+ # Translations for use by debconf--not used in Ubuntu.
+ 'debian/po/',
+ # Debian Installer translations--treated separately.
+ 'd-i/',
+ # Documentation--not translatable in Launchpad.
+ 'help/',
+ 'man/po/',
+ 'man/po4a/',
+ ]
+
+ for prefix in blocked_prefixes:
+ if filename.startswith(prefix):
+ return None
+
+ return filename
+
class PackageTranslationsUploadJobDerived(BaseRunnableJob):
@@ -46,12 +84,14 @@
self.context = self
@classmethod
- def create(cls, sourcepackagerelease, libraryfilealias, requester):
+ def create(cls, packageupload, sourcepackagerelease, libraryfilealias,
+ requester):
job = Job(
base_job_type=JobType.UPLOAD_PACKAGE_TRANSLATIONS,
requester=requester,
base_json_data=simplejson.dumps(
- {'sourcepackagerelease': sourcepackagerelease.id,
+ {'packageupload': packageupload.id,
+ 'sourcepackagerelease': sourcepackagerelease.id,
'libraryfilealias': libraryfilealias.id}))
derived = cls(job)
derived.celeryRunOnCommit()
@@ -76,6 +116,10 @@
classProvides(IPackageTranslationsUploadJobSource)
@property
+ def packageupload_id(self):
+ return simplejson.loads(self.base_json_data)['packageupload']
+
+ @property
def sourcepackagerelease_id(self):
return simplejson.loads(self.base_json_data)['sourcepackagerelease']
@@ -84,6 +128,10 @@
return simplejson.loads(self.base_json_data)['libraryfilealias']
@property
+ def packageupload(self):
+ return PackageUpload.get(self.packageupload_id)
+
+ @property
def sourcepackagerelease(self):
return SourcePackageRelease.get(self.sourcepackagerelease_id)
@@ -91,9 +139,21 @@
def libraryfilealias(self):
return getUtility(ILibraryFileAliasSet)[self.libraryfilealias_id]
+ def attachTranslationFiles(self, by_maintainer):
+ pu = self.packageupload
+ spr = self.sourcepackagerelease
+ only_templates = spr.sourcepackage.has_sharing_translation_templates
+ importer = self.requester
+ tarball = self.libraryfilealias.read()
+
+ queue = getUtility(ITranslationImportQueue)
+
+ queue.addOrUpdateEntriesFromTarball(
+ tarball, by_maintainer, importer,
+ sourcepackagename=spr.sourcepackagename,
+ distroseries=pu.distroseries,
+ filename_filter=_filter_ubuntu_translation_file,
+ only_templates=only_templates)
+
def run(self):
- sourcepackagerelease = self.sourcepackagerelease
- libraryfilealias = self.libraryfilealias
- importer = sourcepackagerelease.creator
- sourcepackagerelease.attachTranslationFiles(libraryfilealias, True,
- importer=importer)
+ self.attachTranslationFiles(True)
=== modified file 'lib/lp/soyuz/model/queue.py'
--- lib/lp/soyuz/model/queue.py 2013-10-02 02:59:38 +0000
+++ lib/lp/soyuz/model/queue.py 2013-10-14 23:28:23 +0000
@@ -46,7 +46,6 @@
# that it needs a bit of redesigning here around the publication stuff.
from lp.archivepublisher.config import getPubConfig
from lp.archivepublisher.customupload import CustomUploadError
-from lp.archivepublisher.debversion import Version
from lp.archiveuploader.tagfiles import parse_tagfile_content
from lp.registry.interfaces.pocket import PackagePublishingPocket
from lp.registry.model.sourcepackagename import SourcePackageName
@@ -90,7 +89,6 @@
)
from lp.soyuz.interfaces.archive import (
ComponentNotFound,
- MAIN_ARCHIVE_PURPOSES,
PriorityNotFound,
SectionNotFound,
)
@@ -98,9 +96,6 @@
from lp.soyuz.interfaces.component import IComponentSet
from lp.soyuz.interfaces.packagecopyjob import IPackageCopyJobSource
from lp.soyuz.interfaces.packagediff import IPackageDiffSet
-from lp.soyuz.interfaces.packagetranslationsuploadjob import (
- IPackageTranslationsUploadJobSource,
- )
from lp.soyuz.interfaces.publishing import (
IPublishingSet,
name_priority_map,
@@ -915,6 +910,8 @@
# It may be a recipe upload.
elif spr and spr.source_package_recipe_build:
return spr.source_package_recipe_build.requester
+ elif self.contains_copy:
+ return self.package_copy_job.requester
else:
return None
@@ -1423,38 +1420,11 @@
def publishRosettaTranslations(self, logger=None):
"""See `IPackageUploadCustom`."""
- sourcepackagerelease = self.packageupload.sourcepackagerelease
-
- # Ignore translations not with main distribution purposes.
- if self.packageupload.archive.purpose not in MAIN_ARCHIVE_PURPOSES:
- debug(logger,
- "Skipping translations since its purpose is not "
- "in MAIN_ARCHIVE_PURPOSES.")
- return
-
- # If the distroseries is 11.10 (oneiric) or later, the valid names
- # check is not required. (See bug 788685.)
- distroseries = sourcepackagerelease.upload_distroseries
- do_names_check = Version(distroseries.version) < Version('11.10')
-
- valid_pockets = (
- PackagePublishingPocket.RELEASE, PackagePublishingPocket.SECURITY,
- PackagePublishingPocket.UPDATES, PackagePublishingPocket.PROPOSED)
- valid_components = ('main', 'restricted')
- if (self.packageupload.pocket not in valid_pockets or
- (do_names_check and
- sourcepackagerelease.component.name not in valid_components)):
- # XXX: CarlosPerelloMarin 2006-02-16 bug=31665:
- # This should be implemented using a more general rule to accept
- # different policies depending on the distribution.
- # Ubuntu's MOTU told us that they are not able to handle
- # translations like we do in main. We are going to import only
- # packages in main.
- return
-
- blamee = self.packageupload.findPersonToNotify()
- getUtility(IPackageTranslationsUploadJobSource).create(
- sourcepackagerelease, self.libraryfilealias, blamee)
+ from lp.archivepublisher.rosetta_translations import (
+ process_rosetta_translations)
+
+ process_rosetta_translations(self.packageupload,
+ self.libraryfilealias, logger=logger)
def publishStaticTranslations(self, logger=None):
"""See `IPackageUploadCustom`."""
=== modified file 'lib/lp/soyuz/model/sourcepackagerelease.py'
--- lib/lp/soyuz/model/sourcepackagerelease.py 2013-09-25 03:15:03 +0000
+++ lib/lp/soyuz/model/sourcepackagerelease.py 2013-10-14 23:28:23 +0000
@@ -4,7 +4,6 @@
__metaclass__ = type
__all__ = [
'SourcePackageRelease',
- '_filter_ubuntu_translation_file',
]
@@ -38,7 +37,6 @@
from zope.interface import implements
from lp.app.errors import NotFoundError
-from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.archiveuploader.utils import determine_source_file_type
from lp.buildmaster.enums import BuildStatus
from lp.registry.interfaces.person import validate_public_person
@@ -77,41 +75,6 @@
PackageUpload,
PackageUploadSource,
)
-from lp.translations.interfaces.translationimportqueue import (
- ITranslationImportQueue,
- )
-
-
-def _filter_ubuntu_translation_file(filename):
- """Filter for translation filenames in tarball.
-
- Grooms filenames of translation files in tarball, returning None or
- empty string for files that should be ignored.
-
- Passed to `ITranslationImportQueue.addOrUpdateEntriesFromTarball`.
- """
- source_prefix = 'source/'
- if not filename.startswith(source_prefix):
- return None
-
- filename = filename[len(source_prefix):]
-
- blocked_prefixes = [
- # Translations for use by debconf--not used in Ubuntu.
- 'debian/po/',
- # Debian Installer translations--treated separately.
- 'd-i/',
- # Documentation--not translatable in Launchpad.
- 'help/',
- 'man/po/',
- 'man/po4a/',
- ]
-
- for prefix in blocked_prefixes:
- if filename.startswith(prefix):
- return None
-
- return filename
class SourcePackageRelease(SQLBase):
@@ -542,24 +505,6 @@
return change
- def attachTranslationFiles(self, tarball_alias, by_maintainer,
- importer=None):
- """See ISourcePackageRelease."""
- tarball = tarball_alias.read()
-
- if importer is None:
- importer = getUtility(ILaunchpadCelebrities).rosetta_experts
-
- queue = getUtility(ITranslationImportQueue)
-
- only_templates = self.sourcepackage.has_sharing_translation_templates
- queue.addOrUpdateEntriesFromTarball(
- tarball, by_maintainer, importer,
- sourcepackagename=self.sourcepackagename,
- distroseries=self.upload_distroseries,
- filename_filter=_filter_ubuntu_translation_file,
- only_templates=only_templates)
-
def getDiffTo(self, to_sourcepackagerelease):
"""See ISourcePackageRelease."""
return PackageDiff.selectOneBy(
=== modified file 'lib/lp/soyuz/scripts/custom_uploads_copier.py'
--- lib/lp/soyuz/scripts/custom_uploads_copier.py 2013-10-02 02:59:38 +0000
+++ lib/lp/soyuz/scripts/custom_uploads_copier.py 2013-10-14 23:28:23 +0000
@@ -17,6 +17,7 @@
from lp.archivepublisher.ddtp_tarball import DdtpTarballUpload
from lp.archivepublisher.debian_installer import DebianInstallerUpload
from lp.archivepublisher.dist_upgrader import DistUpgraderUpload
+from lp.archivepublisher.rosetta_translations import RosettaTranslationsUpload
from lp.archivepublisher.uefi import UefiUpload
from lp.registry.interfaces.pocket import PackagePublishingPocket
from lp.services.database.bulk import load_referencing
@@ -37,6 +38,8 @@
PackageUploadCustomFormat.DEBIAN_INSTALLER: DebianInstallerUpload,
PackageUploadCustomFormat.DIST_UPGRADER: DistUpgraderUpload,
PackageUploadCustomFormat.DDTP_TARBALL: DdtpTarballUpload,
+ PackageUploadCustomFormat.ROSETTA_TRANSLATIONS:
+ RosettaTranslationsUpload,
PackageUploadCustomFormat.UEFI: UefiUpload,
}
=== modified file 'lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py'
--- lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py 2013-10-02 02:59:38 +0000
+++ lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py 2013-10-14 23:28:23 +0000
@@ -200,7 +200,7 @@
matching_upload = package_upload.addCustom(
library_file, PackageUploadCustomFormat.DEBIAN_INSTALLER)
nonmatching_upload = package_upload.addCustom(
- library_file, PackageUploadCustomFormat.ROSETTA_TRANSLATIONS)
+ library_file, PackageUploadCustomFormat.STATIC_TRANSLATIONS)
copier = CustomUploadsCopier(FakeDistroSeries())
candidates = copier.getCandidateUploads(source_series)
self.assertContentEqual([matching_upload], candidates)
=== added file 'lib/lp/soyuz/tests/test_distroseriesqueue_rosetta_translations.py'
--- lib/lp/soyuz/tests/test_distroseriesqueue_rosetta_translations.py 1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/tests/test_distroseriesqueue_rosetta_translations.py 2013-10-14 23:28:23 +0000
@@ -0,0 +1,139 @@
+# Copyright 2013 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Test upload and queue manipulation of Rosetta Translations' tarballs.
+
+See also lp.archivepublisher.tests.test_rosetta_translations for detailed
+tests of rosetta-translations handling.
+"""
+
+import transaction
+from os.path import relpath
+from tarfile import TarFile
+from zope.component import getUtility
+
+from lp.archiveuploader.nascentupload import NascentUpload
+from lp.archiveuploader.tests import (
+ datadir,
+ getPolicy,
+ )
+from lp.services.log.logger import DevNullLogger
+from lp.soyuz.enums import PackagePublishingStatus
+from lp.soyuz.model.packagetranslationsuploadjob import (
+ PackageTranslationsUploadJob,
+ )
+from lp.soyuz.tests.test_publishing import TestNativePublishingBase
+from lp.testing.dbuser import dbuser
+from lp.testing.gpgkeys import import_public_test_keys
+from lp.testing.layers import LaunchpadZopelessLayer
+
+from lp.translations.interfaces.translationimportqueue import (
+ ITranslationImportQueue,
+ )
+from lp.translations.enums import RosettaImportStatus
+from lp.translations.scripts.import_queue_gardener import ImportQueueGardener
+from lp.translations.scripts.po_import import TranslationsImport
+
+
+class TestDistroSeriesQueueRosettaTranslationsTarball(
+ TestNativePublishingBase):
+
+ layer = LaunchpadZopelessLayer
+
+ def setUp(self):
+ super(TestDistroSeriesQueueRosettaTranslationsTarball, self).setUp()
+ import_public_test_keys()
+ self.logger = DevNullLogger()
+ self.absolutely_anything_policy = getPolicy(
+ name="absolutely-anything", distro="ubuntutest",
+ distroseries=None)
+ self.package_name = "pmount"
+ self.version = "0.9.20-2ubuntu0.2"
+
+ def uploadTestData(self, name=None, version=None):
+ if name is None:
+ name = self.package_name
+ if version is None:
+ version = self.version
+ changes_file = "%s_%s_i386.changes" % (name, version)
+
+ spph = self.getPubSource(sourcename=name, version=version,
+ distroseries=self.breezy_autotest,
+ status=PackagePublishingStatus.PUBLISHED)
+ self.spr = spph.sourcepackagerelease
+ self.translations_file = "%s_%s_i386_translations.tar.gz" % (name,
+ version)
+ upload = NascentUpload.from_changesfile_path(
+ datadir("rosetta-translations/%s" % changes_file),
+ self.absolutely_anything_policy, self.logger)
+
+ upload.process()
+ self.assertFalse(upload.is_rejected)
+ self.assertTrue(upload.do_accept())
+ self.assertFalse(upload.rejection_message)
+ # Accepting the queue entry because there's no ancestry, so not
+ # auto-accepted
+ upload.queue_root.setAccepted()
+ return upload
+
+ def test_accepts_correct_upload(self):
+ upload = self.uploadTestData()
+ self.assertEqual(1, len(upload.queue_root.customfiles))
+
+ def _getImportableFilesFromTarball(self):
+ tarball = TarFile.open(mode="r:gz", fileobj=open(datadir(
+ "rosetta-translations/%s" % self.translations_file)))
+ return [relpath(file_, "./source/") for file_ in tarball.getnames() if
+ ".po" in file_]
+
+ def _getQueuePaths(self, import_status=None):
+ if import_status is not None:
+ entries = self.translation_import_queue.getAllEntries(
+ target=self.spr.sourcepackage, import_status=import_status)
+ else:
+ entries = self.translation_import_queue.getAllEntries(
+ target=self.spr.sourcepackage)
+ return [entry.path for entry in entries]
+
+ def test_publish(self):
+ upload = self.uploadTestData()
+ transaction.commit()
+ upload.queue_root.realiseUpload(self.logger)
+
+ # Test if the job was created correctly
+ jobs = list(PackageTranslationsUploadJob.iterReady())
+ self.assertEqual(1, len(jobs))
+
+ job = jobs[0]
+ # Assert if the job corresponds to the file we uploaded
+ self.assertEqual(job.sourcepackagerelease, self.spr)
+ self.assertEqual(job.libraryfilealias.filename, self.translations_file)
+
+ # Test if the pmount translations tarball files were added to the
+ # translation import queue
+ with dbuser("upload_package_translations_job"):
+ job.run()
+ self.translation_import_queue = getUtility(ITranslationImportQueue)
+ self.assertContentEqual(self._getImportableFilesFromTarball(),
+ self._getQueuePaths())
+
+ self.factory.makePOTemplate(distroseries=self.breezy_autotest,
+ sourcepackagename=self.spr.sourcepackagename, path="po/pmount.pot",
+ translation_domain=self.package_name)
+
+ # Approve all translations in the queue
+ with dbuser("translations_import_queue_gardener"):
+ gardener = ImportQueueGardener(
+ 'translations-import-queue-gardener', logger=self.logger,
+ test_args=[])
+ gardener.main()
+
+ # Import all approved translations
+ with dbuser("poimport"):
+ importer = TranslationsImport('poimport', logger=self.logger,
+ test_args=[])
+ importer.main()
+ # Test if all translations in the queue were successfully imported
+ self.assertContentEqual(
+ self._getImportableFilesFromTarball(), self._getQueuePaths(
+ import_status=RosettaImportStatus.IMPORTED))
=== modified file 'lib/lp/soyuz/tests/test_packagecopyjob.py'
--- lib/lp/soyuz/tests/test_packagecopyjob.py 2013-10-02 02:59:38 +0000
+++ lib/lp/soyuz/tests/test_packagecopyjob.py 2013-10-14 23:28:23 +0000
@@ -1362,7 +1362,7 @@
custom_file, PackageUploadCustomFormat.DIST_UPGRADER)
build.package_upload.addCustom(
self.factory.makeLibraryFileAlias(),
- PackageUploadCustomFormat.ROSETTA_TRANSLATIONS)
+ PackageUploadCustomFormat.STATIC_TRANSLATIONS)
# Make the new librarian file available.
self.layer.txn.commit()
@@ -1392,7 +1392,7 @@
status=PackageUploadStatus.ACCEPTED, archive=spph.archive,
pocket=PackagePublishingPocket.UPDATES))
- # ROSETTA_TRANSLATIONS is not a copyable type, so is not copied.
+ # STATIC_TRANSLATIONS is not a copyable type, so is not copied.
self.assertEqual(1, len(uploads))
upload = uploads[0]
self.assertEqual(
=== modified file 'lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py'
--- lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py 2013-08-07 06:26:36 +0000
+++ lib/lp/soyuz/tests/test_packagetranslationsuploadjob.py 2013-10-14 23:28:23 +0000
@@ -3,8 +3,8 @@
__metaclass__ = type
+import transaction
from testtools.content import text_content
-import transaction
from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
@@ -21,10 +21,12 @@
PackageTranslationsUploadJob,
)
from lp.testing import (
+ person_logged_in,
run_script,
TestCaseWithFactory,
verifyObject,
)
+from lp.testing.dbuser import dbuser
from lp.testing.fakemethod import FakeMethod
from lp.testing.layers import (
CeleryJobLayer,
@@ -37,27 +39,26 @@
class LocalTestHelper(TestCaseWithFactory):
- def makeJob(self, spr_creator=None, archive=None,
- sourcepackagerelease=None, libraryfilealias=None,
- job_requester=None, tar_content=None):
- if spr_creator is None:
- creator = self.factory.makePerson()
- else:
- creator = self.factory.makePerson(name=spr_creator)
- if job_requester is None:
- requester = self.factory.makePerson()
- else:
- requester = self.factory.makePerson(name=job_requester)
+ def makeJob(self, archive=None, distroseries=None, tar_content=None):
+ requester = self.factory.makePerson()
+ distroseries = self.factory.makeDistroSeries()
+ sourcepackagename = self.factory.getOrMakeSourcePackageName("foobar")
if archive is None:
- archive = self.factory.makeArchive()
- if sourcepackagerelease is None:
- sourcepackagerelease = self.factory.makeSourcePackageRelease(
- archive=archive, creator=creator)
- if libraryfilealias is None:
- libraryfilealias = self.makeTranslationsLFA(tar_content)
- return (sourcepackagerelease,
+ archive = distroseries.main_archive
+ libraryfilealias = self.makeTranslationsLFA(tar_content)
+ self.factory.makeSourcePackage(sourcepackagename=sourcepackagename,
+ distroseries=distroseries, publish=True)
+ spr = self.factory.makeSourcePackageRelease(
+ sourcepackagename=sourcepackagename,
+ distroseries=distroseries)
+ upload = removeSecurityProxy(self.factory.makePackageUpload(
+ distroseries=distroseries, archive=archive))
+
+ upload.addSource(spr)
+
+ return (upload,
getUtility(IPackageTranslationsUploadJobSource).create(
- sourcepackagerelease, libraryfilealias, requester))
+ upload, spr, libraryfilealias, requester))
def makeTranslationsLFA(self, tar_content=None):
"""Create an LibraryFileAlias containing dummy translation data."""
@@ -91,29 +92,18 @@
jobs = list(PackageTranslationsUploadJob.iterReady())
self.assertEqual(1, len(jobs))
- def test_importer_is_creator(self):
- spr, job = self.makeJob(spr_creator="foobar")
- transaction.commit()
- job.run()
- translation_import_queue = getUtility(ITranslationImportQueue)
- entries_in_queue = translation_import_queue.getAllEntries(
- target=spr.sourcepackage)
- self.assertEqual(entries_in_queue[0].importer.name, "foobar")
-
def test_getErrorRecipients_requester(self):
- spr, job = self.makeJob()
+ _, job = self.makeJob()
email = format_address_for_person(job.requester)
self.assertEquals([email], job.getErrorRecipients())
removeSecurityProxy(job).requester = None
self.assertEquals([], job.getErrorRecipients())
-
def test_run(self):
archive = self.factory.makeArchive()
- foo_pkg = self.factory.makeSourcePackageRelease(archive=archive)
+ packageupload, job = self.makeJob(archive=archive)
method = FakeMethod()
- removeSecurityProxy(foo_pkg).attachTranslationFiles = method
- spr, job = self.makeJob(archive=archive, sourcepackagerelease=foo_pkg)
+ removeSecurityProxy(job).attachTranslationFiles = method
transaction.commit()
job.run()
self.assertEqual(method.call_count, 1)
@@ -122,7 +112,7 @@
tar_content = {
'source/po/foobar.pot': 'FooBar template',
}
- spr, job = self.makeJob(tar_content=tar_content)
+ packageupload, job = self.makeJob(tar_content=tar_content)
transaction.commit()
out, err, exit_code = run_script(
"LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" % (
@@ -134,7 +124,7 @@
self.assertEqual(0, exit_code)
translation_import_queue = getUtility(ITranslationImportQueue)
entries_in_queue = translation_import_queue.getAllEntries(
- target=spr.sourcepackage)
+ target=packageupload.sourcepackagerelease.sourcepackage)
self.assertEqual(1, entries_in_queue.count())
# Check if the file in tar_content is queued:
@@ -151,10 +141,52 @@
'jobs.celery.enabled_classes': 'PackageTranslationsUploadJob',
}))
- spr, job = self.makeJob()
+ packageupload, job = self.makeJob()
with block_on_job(self):
transaction.commit()
translation_import_queue = getUtility(ITranslationImportQueue)
entries_in_queue = translation_import_queue.getAllEntries(
+ target=packageupload.sourcepackagerelease.sourcepackage).count()
+ self.assertEqual(2, entries_in_queue)
+
+
+class TestAttachTranslationFiles(LocalTestHelper):
+ """Tests for attachTranslationFiles."""
+
+ layer = LaunchpadZopelessLayer
+
+ def test_attachTranslationFiles__no_translation_sharing(self):
+ # If translation sharing is disabled, attachTranslationFiles() creates
+ # a job in the translation import queue.
+
+ packageupload, job = self.makeJob()
+ spr = packageupload.sourcepackagerelease
+
+ self.assertFalse(spr.sourcepackage.has_sharing_translation_templates)
+ transaction.commit()
+ with dbuser('upload_package_translations_job'):
+ job.attachTranslationFiles(True)
+ translation_import_queue = getUtility(ITranslationImportQueue)
+ entries_in_queue = translation_import_queue.getAllEntries(
target=spr.sourcepackage).count()
self.assertEqual(2, entries_in_queue)
+
+ def test_attachTranslationFiles__translation_sharing(self):
+ # If translation sharing is enabled, attachTranslationFiles() only
+ # attaches templates.
+ packageupload, job = self.makeJob()
+ sourcepackage = packageupload.sourcepackagerelease.sourcepackage
+ productseries = self.factory.makeProductSeries()
+
+ self.factory.makePOTemplate(productseries=productseries)
+ with person_logged_in(sourcepackage.distroseries.owner):
+ sourcepackage.setPackaging(
+ productseries, sourcepackage.distroseries.owner)
+ self.assertTrue(sourcepackage.has_sharing_translation_templates)
+ transaction.commit()
+ with dbuser('upload_package_translations_job'):
+ job.attachTranslationFiles(True)
+ translation_import_queue = getUtility(ITranslationImportQueue)
+ entries = translation_import_queue.getAllEntries(target=sourcepackage)
+ self.assertEqual(1, entries.count())
+ self.assertTrue(entries[0].path.endswith('.pot'))
=== modified file 'lib/lp/soyuz/tests/test_sourcepackagerelease.py'
--- lib/lp/soyuz/tests/test_sourcepackagerelease.py 2013-09-11 08:17:34 +0000
+++ lib/lp/soyuz/tests/test_sourcepackagerelease.py 2013-10-14 23:28:23 +0000
@@ -17,7 +17,6 @@
from lp.buildmaster.enums import BuildStatus
from lp.registry.interfaces.pocket import PackagePublishingPocket
-from lp.services.tarfile_helpers import LaunchpadWriteTarFile
from lp.soyuz.enums import (
ArchivePurpose,
PackagePublishingStatus,
@@ -29,18 +28,12 @@
)
from lp.soyuz.scripts.packagecopier import do_copy
from lp.testing import (
- person_logged_in,
TestCaseWithFactory,
)
-from lp.testing.dbuser import dbuser
from lp.testing.layers import (
LaunchpadFunctionalLayer,
- LaunchpadZopelessLayer,
ZopelessDatabaseLayer,
)
-from lp.translations.interfaces.translationimportqueue import (
- ITranslationImportQueue,
- )
class TestSourcePackageRelease(TestCaseWithFactory):
@@ -301,56 +294,3 @@
self.assertEqual(
{distroseries.nominatedarchindep.architecturetag: bpr.build},
naked_spr.findBuildsByArchitecture(distroseries, archive))
-
-
-class TestSourcePackageReleaseTranslationFiles(TestCaseWithFactory):
- """Tests for attachTranslationFiles on a different layer."""
-
- layer = LaunchpadZopelessLayer
-
- def makeTranslationsLFA(self):
- """Create an LibraryFileAlias containing dummy translation data."""
- test_tar_content = {
- 'source/po/foo.pot': 'Foo template',
- 'source/po/eo.po': 'Foo translation',
- }
- tarfile_content = LaunchpadWriteTarFile.files_to_string(
- test_tar_content)
- return self.factory.makeLibraryFileAlias(content=tarfile_content)
-
- def test_attachTranslationFiles__no_translation_sharing(self):
- # If translation sharing is disabled,
- # SourcePackageRelease.attachTranslationFiles() creates a job
- # in the translation import queue.
- spr = self.factory.makeSourcePackageRelease()
- self.assertFalse(spr.sourcepackage.has_sharing_translation_templates)
- lfa = self.makeTranslationsLFA()
- transaction.commit()
- with dbuser('upload_package_translations_job'):
- spr.attachTranslationFiles(lfa, True, spr.maintainer)
- translation_import_queue = getUtility(ITranslationImportQueue)
- entries_in_queue = translation_import_queue.getAllEntries(
- target=spr.sourcepackage).count()
- self.assertEqual(2, entries_in_queue)
-
- def test_attachTranslationFiles__translation_sharing(self):
- # If translation sharing is enabled,
- # SourcePackageRelease.attachTranslationFiles() only attaches
- # templates.
- spr = self.factory.makeSourcePackageRelease()
- sourcepackage = spr.sourcepackage
- productseries = self.factory.makeProductSeries()
- self.factory.makePOTemplate(productseries=productseries)
- with person_logged_in(sourcepackage.distroseries.owner):
- sourcepackage.setPackaging(
- productseries, sourcepackage.distroseries.owner)
- self.assertTrue(sourcepackage.has_sharing_translation_templates)
- lfa = self.makeTranslationsLFA()
- transaction.commit()
- with dbuser('upload_package_translations_job'):
- spr.attachTranslationFiles(lfa, True, spr.maintainer)
- translation_import_queue = getUtility(ITranslationImportQueue)
- entries = translation_import_queue.getAllEntries(
- target=sourcepackage)
- self.assertEqual(1, entries.count())
- self.assertTrue(entries[0].path.endswith('.pot'))
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2013-09-13 06:20:49 +0000
+++ lib/lp/testing/factory.py 2013-10-14 23:28:23 +0000
@@ -3440,7 +3440,8 @@
def makeCopyJobPackageUpload(self, distroseries=None,
sourcepackagename=None, source_archive=None,
- target_pocket=None):
+ target_pocket=None, requester=None,
+ include_binaries=False):
"""Make a `PackageUpload` with a `PackageCopyJob` attached."""
if distroseries is None:
distroseries = self.makeDistroSeries()
@@ -3453,7 +3454,8 @@
source_archive=spph.archive,
target_pocket=target_pocket,
target_archive=distroseries.main_archive,
- target_distroseries=distroseries)
+ target_distroseries=distroseries, requester=requester,
+ include_binaries=include_binaries)
job.addSourceOverride(SourceOverride(
spr.sourcepackagename, spr.component, spr.section))
try:
@@ -4217,7 +4219,7 @@
def makePlainPackageCopyJob(
self, package_name=None, package_version=None, source_archive=None,
target_archive=None, target_distroseries=None, target_pocket=None,
- requester=None):
+ requester=None, include_binaries=False):
"""Create a new `PlainPackageCopyJob`."""
if package_name is None and package_version is None:
package_name = self.makeSourcePackageName().name
@@ -4235,7 +4237,8 @@
return getUtility(IPlainPackageCopyJobSource).create(
package_name, source_archive, target_archive,
target_distroseries, target_pocket,
- package_version=package_version, requester=requester)
+ package_version=package_version, requester=requester,
+ include_binaries=include_binaries)
def makeAccessPolicy(self, pillar=None,
type=InformationType.PROPRIETARY,
=== modified file 'lib/lp/translations/doc/sourcepackagerelease-translations.txt'
--- lib/lp/translations/doc/sourcepackagerelease-translations.txt 2011-12-22 05:37:22 +0000
+++ lib/lp/translations/doc/sourcepackagerelease-translations.txt 2013-10-14 23:28:23 +0000
@@ -36,17 +36,19 @@
>>> transaction.commit()
-We will use an arbitrary source package release from the sampledata.
+We will use an arbitrary source package release from the sampledata, and
+create a PackageUpload with it.
>>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
>>> spr_test = SourcePackageRelease.get(20)
>>> print spr_test.title
pmount - 0.1-1
-And the 'katie' celebrity as the user responsible for the transalation.
-
- >>> from lp.app.interfaces.launchpad import ILaunchpadCelebrities
- >>> katie = getUtility(ILaunchpadCelebrities).katie
+ >>> from lp.soyuz.interfaces.packagetranslationsuploadjob import (
+ ... IPackageTranslationsUploadJobSource)
+ >>> upload = factory.makePackageUpload(
+ ... distroseries=spr_test.upload_distroseries)
+ >>> pus = upload.addSource(spr_test)
Before the final upload, we can see that the translation queue for the
testing source package is empty.
@@ -59,11 +61,19 @@
0
Now we bind both uploaded translations, the public and the restricted
-ones, to the testing source package.
-
- >>> spr_test.attachTranslationFiles(public_translation, True, katie)
-
- >>> spr_test.attachTranslationFiles(restricted_translation, True, katie)
+ones, to the testing upload entry, creating an PackageTranslationsUploadJob
+for each import.
+
+ >>> importer = factory.makePerson(name="maria")
+
+ >>> job1 = getUtility(IPackageTranslationsUploadJobSource).create(upload,
+ ... spr_test, public_translation, importer)
+
+ >>> job2 = getUtility(IPackageTranslationsUploadJobSource).create(upload,
+ ... spr_test, restricted_translation, importer)
+
+ >>> job1.run()
+ >>> job2.run()
And the queue should have 2 entries, with exactly the same contents.
@@ -75,8 +85,8 @@
>>> for entry in queue_entries:
... print entry.path, entry.importer.name
- something/en-US.xpi katie
- po/es.po katie
+ something/en-US.xpi maria
+ po/es.po maria
Commit, so the uploaded translations become available to the scripts.
@@ -122,7 +132,7 @@
A callback tells the translations import queue what to do with the file
names found in the tarball:
- >>> from lp.soyuz.model.sourcepackagerelease import (
+ >>> from lp.soyuz.model.packagetranslationsuploadjob import (
... _filter_ubuntu_translation_file)
Anything not in the "source/" directory is ignored.
=== modified file 'lib/lp/translations/scripts/reupload_translations.py'
--- lib/lp/translations/scripts/reupload_translations.py 2011-05-27 19:53:20 +0000
+++ lib/lp/translations/scripts/reupload_translations.py 2013-10-14 23:28:23 +0000
@@ -93,7 +93,7 @@
def _processPackage(self, package):
"""Get translations for `package` re-uploaded."""
# Avoid circular imports.
- from lp.soyuz.model.sourcepackagerelease import (
+ from lp.soyuz.model.packagetranslationsuploadjob import (
_filter_ubuntu_translation_file)
self.logger.info("Processing %s" % package.displayname)
=== modified file 'lib/lp/translations/scripts/tests/test_reupload_translations.py'
--- lib/lp/translations/scripts/tests/test_reupload_translations.py 2012-01-01 02:58:52 +0000
+++ lib/lp/translations/scripts/tests/test_reupload_translations.py 2013-10-14 23:28:23 +0000
@@ -17,7 +17,7 @@
from lp.registry.model.sourcepackage import SourcePackage
from lp.services.librarian.model import LibraryFileAliasSet
from lp.services.scripts.tests import run_script
-from lp.soyuz.model.sourcepackagerelease import (
+from lp.soyuz.model.packagetranslationsuploadjob import (
_filter_ubuntu_translation_file,
)
from lp.testing import TestCaseWithFactory
Follow ups