~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Copyright 2009 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

# pylint: disable-msg=W0703

"""Mark translation credits messages as translated."""

__metaclass__ = type
__all__ = ['VerifyPOFileStatsProcess']


import logging

from zope.component import getUtility
from zope.interface import implements

from canonical.launchpad.interfaces.looptuner import ITunableLoop
from canonical.launchpad.utilities.looptuner import DBLoopTuner
from lp.translations.interfaces.pofile import IPOFileSet


class CreditsFixer:
    """`ITunableLoop` that translates all `POFile`s' translation credits."""
    implements(ITunableLoop)

    def __init__(self, transaction, logger, start_at=0):
        self.transaction = transaction
        self.logger = logger
        self.start_at = start_at

        pofileset = getUtility(IPOFileSet)
        self.pofiles = pofileset.getPOFilesWithTranslationCredits(
            untranslated=True)
        self.logger.info(
            "Figuring out POFiles that need fixing: this may take a while...")
        self.total = self.pofiles.count()
        self.logger.info(
            "Marking up a total of %d credits as translated." % self.total)

    def isDone(self):
        """See `ITunableLoop`."""
        # When the main loop hits the end of the POFile table, it sets
        # start_at to None.  Until we know we hit the end, it always has a
        # numerical value.
        return self.start_at is None

    def getPOFilesBatch(self, chunk_size):
        """Return a batch of POFiles to work with."""
        self.logger.debug(
            "Getting POFiles[%d:%d]..." % (self.start_at,
                                           self.start_at + int(chunk_size)))
        pofiles = self.pofiles[self.start_at: self.start_at + int(chunk_size)]
        return pofiles

    def __call__(self, chunk_size):
        """See `ITunableLoop`.

        Retrieve a batch of `POFile`s in ascending id order, and mark
        all of their translation credits as translated.
        """
        pofiles = self.getPOFilesBatch(chunk_size)

        done = 0
        for pofile, potmsgset in pofiles:
            done += 1
            self.logger.debug(
                "Processing %d (out of %d)" % (
                    self.start_at + done, self.total))
            potmsgset.setTranslationCreditsToTranslated(pofile)
            self.transaction.commit()
            self.transaction.begin()

        if done == 0:
            self.start_at = None
        else:
            self.start_at += done
            self.logger.info("Processed %d/%d of messages." % (
                self.start_at, self.total))


class FixTranslationCreditsProcess:
    """Mark all `POFile` translation credits as translated."""

    def __init__(self, transaction, logger=None):
        self.transaction = transaction
        self.logger = logger
        if logger is None:
            self.logger = logging.getLogger("fix-translation-credits")

    def run(self):
        loop = CreditsFixer(self.transaction, self.logger)

        DBLoopTuner(loop, 5).run()

        self.logger.info("Done.")