Welcome to mirror list, hosted at ThFree Co, Russian Federation.

merge_po.py « i18n « modules « scripts « release - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1a55cd670b061cd8a9fce779177ab8807119c153 (plain)
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
150
151
152
153
154
155
156
#!/usr/bin/python3

# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENSE BLOCK *****

# <pep8 compliant>

# Merge one or more .po files into the first dest one.
# If a msgkey is present in more than one merged po, the one in the first file wins, unless 
# it’s marked as fuzzy and one later is not.
# The fuzzy flag is removed if necessary.
# All other comments are never modified.
# However, commented messages in dst will always remain commented, and commented messages are
# never merged from sources.

import sys
from codecs import open

import utils


def main():
    import argparse
    parser = argparse.ArgumentParser(description="" \
                    "Merge one or more .po files into the first dest one.\n" \
                    "If a msgkey (msgid, msgctxt) is present in more than " \
                    "one merged po, the one in the first file wins, unless " \
                    "it’s marked as fuzzy and one later is not.\n" \
                    "The fuzzy flag is removed if necessary.\n" \
                    "All other comments are never modified.\n" \
                    "Commented messages in dst will always remain " \
                    "commented, and commented messages are never merged " \
                    "from sources.")
    parser.add_argument('-s', '--stats', action="store_true",
                        help="Show statistics info.")
    parser.add_argument('-r', '--replace', action="store_true",
                        help="Replace existing messages of same \"level\" already in dest po.")
    parser.add_argument('dst', metavar='dst.po',
                        help="The dest po into which merge the others.")
    parser.add_argument('src', metavar='src.po', nargs='+',
                        help="The po's to merge into the dst.po one.")
    args = parser.parse_args()


    ret = 0
    done_msgkeys = set()
    done_fuzzy_msgkeys = set()
    nbr_merged = 0
    nbr_replaced = 0
    nbr_added = 0
    nbr_unfuzzied = 0

    dst_messages, dst_states, dst_stats = utils.parse_messages(args.dst)
    if dst_states["is_broken"]:
        print("Dest po is BROKEN, aborting.")
        return 1
    if args.stats:
        print("Dest po, before merging:")
        utils.print_stats(dst_stats, prefix="\t")
    # If we don’t want to replace existing valid translations, pre-populate
    # done_msgkeys and done_fuzzy_msgkeys.
    if not args.replace:
        done_msgkeys =  dst_states["trans_msg"].copy()
        done_fuzzy_msgkeys = dst_states["fuzzy_msg"].copy()
    for po in args.src:
        messages, states, stats = utils.parse_messages(po)
        if states["is_broken"]:
            print("\tSrc po {} is BROKEN, skipping.".format(po))
            ret = 1
            continue
        print("\tMerging {}...".format(po))
        if args.stats:
            print("\t\tMerged po stats:")
            utils.print_stats(stats, prefix="\t\t\t")
        for msgkey, val in messages.items():
            msgctxt, msgid = msgkey
            # This msgkey has already been completely merged, or is a commented one,
            # or the new message is commented, skip it.
            if msgkey in (done_msgkeys | dst_states["comm_msg"] | states["comm_msg"]):
                continue
            is_ttip = utils.is_tooltip(msgid)
            # New messages does not yet exists in dest.
            if msgkey not in dst_messages:
                dst_messages[msgkey] = messages[msgkey]
                if msgkey in states["fuzzy_msg"]:
                    done_fuzzy_msgkeys.add(msgkey)
                    dst_states["fuzzy_msg"].add(msgkey)
                elif msgkey in states["trans_msg"]:
                    done_msgkeys.add(msgkey)
                    dst_states["trans_msg"].add(msgkey)
                    dst_stats["trans_msg"] += 1
                    if is_ttip:
                        dst_stats["trans_ttips"] += 1
                nbr_added += 1
                dst_stats["tot_msg"] += 1
                if is_ttip:
                    dst_stats["tot_ttips"] += 1
            # From now on, the new messages is already in dst.
            # New message is neither translated nor fuzzy, skip it.
            elif msgkey not in (states["trans_msg"] | states["fuzzy_msg"]):
                continue
            # From now on, the new message is either translated or fuzzy!
            # The new message is translated.
            elif msgkey in states["trans_msg"]:
                dst_messages[msgkey]["msgstr_lines"] = messages[msgkey]["msgstr_lines"]
                done_msgkeys.add(msgkey)
                done_fuzzy_msgkeys.discard(msgkey)
                if msgkey in dst_states["fuzzy_msg"]:
                    dst_states["fuzzy_msg"].remove(msgkey)
                    nbr_unfuzzied += 1
                if msgkey not in dst_states["trans_msg"]:
                    dst_states["trans_msg"].add(msgkey)
                    dst_stats["trans_msg"] += 1
                    if is_ttip:
                        dst_stats["trans_ttips"] += 1
                else:
                    nbr_replaced += 1
                nbr_merged += 1
            # The new message is fuzzy, org one is fuzzy too,
            # and this msgkey has not yet been merged.
            elif msgkey not in (dst_states["trans_msg"] | done_fuzzy_msgkeys):
                dst_messages[msgkey]["msgstr_lines"] = messages[msgkey]["msgstr_lines"]
                done_fuzzy_msgkeys.add(msgkey)
                dst_states["fuzzy_msg"].add(msgkey)
                nbr_merged += 1
                nbr_replaced += 1

    utils.write_messages(args.dst, dst_messages, dst_states["comm_msg"], dst_states["fuzzy_msg"])

    print("Merged completed. {} messages were merged (among which {} were replaced), " \
          "{} were added, {} were \"un-fuzzied\"." \
          "".format(nbr_merged, nbr_replaced, nbr_added, nbr_unfuzzied))
    if args.stats:
        print("Final merged po stats:")
        utils.print_stats(dst_stats, prefix="\t")
    return ret


if __name__ == "__main__":
    print("\n\n *** Running {} *** \n".format(__file__))
    sys.exit(main())