~launchpad-pqm/launchpad/devel

7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
1
# Copyright 2011 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
"""Job for merging translations."""
5
7675.1051.9 by Aaron Bentley
Updates from review.
6
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
7
__metaclass__ = type
8
9
7675.1050.19 by Aaron Bentley
Merged refactor-merge-job into translation-splitting-job.
10
__all__ = [
11
    'TranslationMergeJob',
12
    'TranslationSplitJob',
13555.10.16 by Danilo Segan
Add a failing test for TranslationTemplateChangeJob.
13
    'TranslationTemplateChangeJob',
7675.1050.19 by Aaron Bentley
Merged refactor-merge-job into translation-splitting-job.
14
    ]
7675.1051.9 by Aaron Bentley
Updates from review.
15
13023.4.1 by Aaron Bentley
Avoid large memory use with frequent commits.
16
import logging
7675.1051.9 by Aaron Bentley
Updates from review.
17
7675.1051.3 by Aaron Bentley
Generalize subscriptions.
18
from lazr.lifecycle.interfaces import (
19
    IObjectCreatedEvent,
7675.1050.9 by Aaron Bentley
Create job on packaging deletion.
20
    IObjectDeletedEvent,
13555.10.10 by Danilo Segan
Provide a template change job on template edits.
21
    IObjectModifiedEvent,
7675.1051.3 by Aaron Bentley
Generalize subscriptions.
22
    )
13023.4.1 by Aaron Bentley
Avoid large memory use with frequent commits.
23
import transaction
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
24
from zope.interface import (
25
    classProvides,
26
    implements,
27
    )
28
14261.1.1 by Jeroen Vermeulen
Log noise: packaging_translations skipping-merge-for-unsupported-distroseries.
29
from lp.services.job.interfaces.job import IRunnableJob
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
30
from lp.services.job.runner import BaseRunnableJob
7675.1051.1 by Aaron Bentley
Further generalization.
31
from lp.translations.interfaces.translationpackagingjob import (
32
    ITranslationPackagingJobSource,
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
33
    )
13555.8.3 by Danilo Segan
Rename TranslationTemplateJob to TranslationSharingJob instead.
34
from lp.translations.model.translationsharingjob import (
35
    TranslationSharingJob,
36
    TranslationSharingJobDerived,
37
    TranslationSharingJobType,
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
38
    )
39
from lp.translations.translationmerger import (
40
    TransactionManager,
41
    TranslationMerger,
42
    )
13555.10.11 by Danilo Segan
Basic working template-splitter.
43
from lp.translations.utilities.translationsplitter import (
44
    TranslationSplitter,
13555.10.14 by Danilo Segan
Watch out for template moves between products/sourcepackages/distributions as well.
45
    TranslationTemplateSplitter,
13555.10.11 by Danilo Segan
Basic working template-splitter.
46
    )
7675.1050.5 by Aaron Bentley
Implement TranslationSplitJob.
47
48
13555.8.3 by Danilo Segan
Rename TranslationTemplateJob to TranslationSharingJob instead.
49
class TranslationPackagingJob(TranslationSharingJobDerived, BaseRunnableJob):
7675.1051.1 by Aaron Bentley
Further generalization.
50
    """Iterate through all Translation job types."""
51
52
    classProvides(ITranslationPackagingJobSource)
53
54
    _translation_packaging_job_types = []
55
56
    @staticmethod
57
    def _register_subclass(cls):
13555.8.3 by Danilo Segan
Rename TranslationTemplateJob to TranslationSharingJob instead.
58
        TranslationSharingJobDerived._register_subclass(cls)
7675.1051.1 by Aaron Bentley
Further generalization.
59
        job_type = getattr(cls, 'class_job_type', None)
60
        if job_type is not None:
61
            cls._translation_packaging_job_types.append(job_type)
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
62
63
    @classmethod
64
    def forPackaging(cls, packaging):
12589.3.1 by Aaron Bentley
Add getNextJobStatus.
65
        """Create a TranslationPackagingJob for a Packaging.
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
66
67
        :param packaging: The `Packaging` to create the job for.
68
        :return: A `TranslationMergeJob`.
69
        """
70
        return cls.create(
71
            packaging.productseries, packaging.distroseries,
72
            packaging.sourcepackagename)
73
7675.1050.2 by Aaron Bentley
Further generalization.
74
    @classmethod
75
    def iterReady(cls):
76
        """See `IJobSource`."""
13555.8.3 by Danilo Segan
Rename TranslationTemplateJob to TranslationSharingJob instead.
77
        clause = TranslationSharingJob.job_type.is_in(
7675.1051.1 by Aaron Bentley
Further generalization.
78
            cls._translation_packaging_job_types)
79
        return super(TranslationPackagingJob, cls).iterReady([clause])
80
81
82
class TranslationMergeJob(TranslationPackagingJob):
83
    """Job for merging translations between a product and sourcepackage."""
84
85
    implements(IRunnableJob)
86
13555.8.3 by Danilo Segan
Rename TranslationTemplateJob to TranslationSharingJob instead.
87
    class_job_type = TranslationSharingJobType.PACKAGING_MERGE
7675.1050.2 by Aaron Bentley
Further generalization.
88
7675.1051.3 by Aaron Bentley
Generalize subscriptions.
89
    create_on_event = IObjectCreatedEvent
90
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
91
    def run(self):
92
        """See `IRunnableJob`."""
13023.4.1 by Aaron Bentley
Avoid large memory use with frequent commits.
93
        logger = logging.getLogger()
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
94
        if not self.distroseries.distribution.full_functionality:
14261.1.2 by Jeroen Vermeulen
Whoopsie: this is why even trivial branches need review.
95
            logger.info(
13023.4.1 by Aaron Bentley
Avoid large memory use with frequent commits.
96
                'Skipping merge for unsupported distroseries "%s".' %
97
                self.distroseries.displayname)
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
98
            return
13023.4.1 by Aaron Bentley
Avoid large memory use with frequent commits.
99
        logger.info(
100
            'Merging %s and %s', self.productseries.displayname,
101
            self.sourcepackage.displayname)
102
        tm = TransactionManager(transaction.manager, False)
7675.1050.1 by Aaron Bentley
Extract PackagingJob, PackagingJobDereived from TranslationMergeJob.
103
        TranslationMerger.mergePackagingTemplates(
104
            self.productseries, self.sourcepackagename, self.distroseries, tm)
7675.1050.5 by Aaron Bentley
Implement TranslationSplitJob.
105
106
107
class TranslationSplitJob(TranslationPackagingJob):
13555.8.4 by Danilo Segan
Minor docstring fixes.
108
    """Job for splitting translations between a product and sourcepackage."""
7675.1050.5 by Aaron Bentley
Implement TranslationSplitJob.
109
110
    implements(IRunnableJob)
111
13555.8.3 by Danilo Segan
Rename TranslationTemplateJob to TranslationSharingJob instead.
112
    class_job_type = TranslationSharingJobType.PACKAGING_SPLIT
7675.1050.5 by Aaron Bentley
Implement TranslationSplitJob.
113
7675.1050.9 by Aaron Bentley
Create job on packaging deletion.
114
    create_on_event = IObjectDeletedEvent
115
7675.1050.5 by Aaron Bentley
Implement TranslationSplitJob.
116
    def run(self):
117
        """See `IRunnableJob`."""
13023.4.1 by Aaron Bentley
Avoid large memory use with frequent commits.
118
        logger = logging.getLogger()
119
        logger.info(
120
            'Splitting %s and %s', self.productseries.displayname,
121
            self.sourcepackage.displayname)
7675.1050.5 by Aaron Bentley
Implement TranslationSplitJob.
122
        TranslationSplitter(self.productseries, self.sourcepackage).split()
13555.10.10 by Danilo Segan
Provide a template change job on template edits.
123
124
125
class TranslationTemplateChangeJob(TranslationPackagingJob):
126
    """Job for merging/splitting translations when template is changed."""
127
128
    implements(IRunnableJob)
129
130
    class_job_type = TranslationSharingJobType.TEMPLATE_CHANGE
131
132
    create_on_event = IObjectModifiedEvent
133
134
    @classmethod
135
    def forPOTemplate(cls, potemplate):
136
        """Create a TranslationTemplateChangeJob for a POTemplate.
137
138
        :param potemplate: The `POTemplate` to create the job for.
139
        :return: A `TranslationTemplateChangeJob`.
140
        """
141
        return cls.create(potemplate=potemplate)
142
143
    def run(self):
144
        """See `IRunnableJob`."""
145
        logger = logging.getLogger()
13555.10.11 by Danilo Segan
Basic working template-splitter.
146
        logger.info("Sanitizing translations for '%s'" % (
147
                self.potemplate.displayname))
13555.10.14 by Danilo Segan
Watch out for template moves between products/sourcepackages/distributions as well.
148
        TranslationTemplateSplitter(self.potemplate).split()
13555.10.12 by Danilo Segan
Basic implementation of translation merger.
149
        tm = TransactionManager(transaction.manager, False)
150
        TranslationMerger.mergeModifiedTemplates(self.potemplate, tm)