~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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/python
#
# Copyright 2009 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""Substitute some chars with the right value in POTranslation.translation."""

__metaclass__ = type
__all__ = []

from optparse import OptionParser
import sys

from canonical.lp import initZopeless
from lp.services.database.sqlbase import (
    cursor,
    sqlvalues,
    )
from lp.services.scripts import (
    logger,
    logger_options,
    )


mapping = {
    # u'\u2022': u' ',  # space represented as a dot.
    u'\u21b5': u'\n', # new line represented with a graphical char.
    }

def change_char(ztm, log, character, newchar):
    """Substitute character with newchar in POTranslation.translation."""
    log.info("Changing all ocurrences of %r with %r" % (character, newchar))
    cur = cursor()
    cur.execute("""
        SELECT POTranslation.id, POTranslation.translation
        FROM POTranslation
        WHERE translation like %s
        """ % sqlvalues('%%%s%%' % character.encode('UTF-8')))

    log.info("Found %d translations that may need a fix" % cur.rowcount)

    for potranslation_id, translation in list(cur.fetchall()):
        cur = cursor()

        # Get the list of POMsgSet that will be affected by this change.
        cur.execute("""
            SELECT DISTINCT POSubmission.pomsgset
            FROM POSubmission
              JOIN POMsgSet ON POSubmission.pomsgset = POMsgSet.id
              JOIN POTMsgSet ON POMsgSet.potmsgset = POTMsgSet.id
              JOIN POMsgID ON POTMsgSet.primemsgid = POMsgID.id
            WHERE
              POSubmission.potranslation = %s AND
              POSubmission.active IS TRUE AND
              POMsgID.msgid NOT like %s
            """ % sqlvalues(
                potranslation_id, '%%%s%%' % character.encode('UTF-8')))

        log.info("Changing %d submissions for IPOTranslation %d" % (
            cur.rowcount, potranslation_id))

        pomsgset_ids = [str(id) for [id] in cur.fetchall()]
        if len(pomsgset_ids) > 0:
            # There is someone using this translation, update its review date
            # so new file exports will get this change.
            cur.execute("""
                UPDATE POMsgSet
                SET date_reviewed = (CURRENT_TIMESTAMP AT TIME ZONE 'UTC')
                WHERE id IN (%s)
                """ % ','.join(pomsgset_ids))
            log.info("Updated %d submissions for IPOTranslation %d" % (
                cur.rowcount, potranslation_id))

            fixed_translation = translation.replace(
                character, newchar).encode('UTF-8')

            cur.execute("""
                SELECT id
                FROM POTranslation
                WHERE sha1(translation) = sha1(%s)
                """ % sqlvalues(fixed_translation))

            if cur.rowcount == 0:
                # The fixed translation is not yet in our database, let's add
                # it.
                cur.execute(
                    "INSERT INTO POTranslation(translation) VALUES(%s)" % (
                        sqlvalues(fixed_translation)))

                cur.execute("""
                    SELECT id
                    FROM POTranslation
                    WHERE translation = %s
                    """ % sqlvalues(fixed_translation))

            # Get the id of the fixed POTranslation.
            [existing_translation_id] = cur.fetchone()

            # Get the submissions that should point to the fixed translation.
            cur.execute("""
                SELECT id
                FROM POSubmission
                WHERE
                  potranslation = %d AND
                  pomsgset IN (%s) AND
                  active IS TRUE
                """ % (potranslation_id, ','.join(pomsgset_ids)))

            submission_ids = [str(id) for [id] in cur.fetchall()]

            # Link to the new fixed translation.
            cur.execute("""
                UPDATE POSubmission
                SET potranslation = %d
                WHERE id IN (%s)
                """ % (existing_translation_id, ','.join(submission_ids)))

            # Commit is done per IPOTranslation.
            ztm.commit()

def read_options():
    """Read the command-line options and return an options object."""
    parser = OptionParser()
    logger_options(parser)

    (options, args) = parser.parse_args()

    return options

def main():
    options = read_options()
    log = logger(options)

    ztm = None
    try:
        log.debug("Connecting to database")
        ztm = initZopeless()
        for oldchar, newchar in mapping.iteritems():
            change_char(ztm, log, oldchar, newchar)
        return 0
    except:
        log.exception("Unhandled exception")
        log.debug("Rolling back")
        if ztm is not None:
            ztm.abort()
        return 1

if __name__ == '__main__':
    sys.exit(main())