~rachidbm/+junk/pochecker

« back to all changes in this revision

Viewing changes to ends-with-dot.py

  • Committer: Rachid BM
  • Date: 2011-09-26 21:45:18 UTC
  • Revision ID: rachidbm@ubuntu.com-20110926214518-c3exp7w3duwclucl
Added support for plurals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/env python
2
2
# -*- coding: utf-8 -*-
3
3
#
4
 
# Analyze translations in a PO file and pick out possible flaws like:
5
 
# - Translation doesn't end with a dot or colon (while original does)
6
 
# - Translation doesn't contain a underscore (while original does)
7
 
#
8
 
#
9
 
# Copyright (c) 2011 Canonical Services Ltd.
10
 
#
11
 
# Original author: Rachid BM <rachidbm@ubuntu.com>
 
4
# Author: Rachid BM <rachidbm@ubuntu.com>
12
5
#
13
6
# This program is free software: you can redistribute it and/or modify it
14
7
# under the terms of the GNU General Public License version 3, as published
22
15
# You should have received a copy of the GNU General Public License along
23
16
# with this program.  If not, see <http://www.gnu.org/licenses/>.
24
17
 
25
 
# TODO:
26
 
# - support plurals
27
18
 
 
19
# Analyze translations in a PO file and pick out possible flaws like:
 
20
# - Translation doesn't end with a period or colon (while original does)
 
21
# - Translation doesn't contain a underscore (while original does)
28
22
 
29
23
import sys
30
24
import optparse
35
29
    print >> sys.stderr, 'You need python-polib: \nsudo apt-get install python-polib'
36
30
    sys.exit(1)
37
31
 
38
 
def print_entry(entry, level): 
 
32
def print_entry(msgid, msgstr, error_message): 
39
33
    """ Print the entry and its error level """
40
 
    print level
41
 
    print entry.msgid.strip().encode("utf-8") 
42
 
    print entry.msgstr.strip().encode("utf-8")
 
34
    print error_message
 
35
    print msgid.strip().encode("utf-8") 
 
36
    print msgstr.strip().encode("utf-8")
43
37
    print
44
38
 
45
39
 
49
43
        self.counter_error = 0
50
44
        self.counter_warning = 0
51
45
 
52
 
    def print_error(self, entry):
 
46
    def print_error(self, msgid, msgstr, message):
53
47
        self.counter_error = self.counter_error + 1
54
 
        print_entry(entry, "ERROR: ")
 
48
        print_entry(msgid, msgstr, "ERROR: {0}".format(message))
55
49
 
56
 
    def print_warning(self, entry, message):
 
50
    def print_warning(self, msgid, msgstr, message):
57
51
        self.counter_warning = self.counter_warning + 1
58
52
        if self.options.show_warnings:
59
 
            print_entry(entry, "WARNING: {0}".format(message))
 
53
            print_entry(msgid, msgstr, "WARNING: {0}".format(message))
60
54
 
61
55
    def run_checker(self):
62
56
        """ Check all translated entries of the given PO file """
65
59
        USAGE = """%prog [OPTIONS] PATTERN
66
60
 
67
61
Analyze translations in a PO file and pick out possible flaws like:
68
 
 - Translation doesn't end with a dot or colon (while original does)
 
62
 - Translation doesn't end with a period or colon (while original does)
69
63
 - Translation doesn't contain a underscore (while original does)
70
64
"""
71
65
 
90
84
        for entry in po.translated_entries():
91
85
            self.check_entry(entry)
92
86
        print "Found {0} error(s) and {1} warning(s). Add -w to show warnings". \
93
 
        format(self.counter_error, self.counter_warning)
 
87
            format(self.counter_error, self.counter_warning)
 
88
 
94
89
 
95
90
    def check_entry(self, entry):
96
91
        """ Checks the translation of an entry on possible flaws """
97
 
        
98
 
        if entry.msgid.strip().endswith("..."): 
99
 
            if not (entry.msgstr.strip().endswith("...")   \
100
 
            or entry.msgstr.strip().endswith("…".decode("utf-8"))):
101
 
                """ Error; Dot doesn't match """
102
 
                self.print_error(entry)
103
 
        elif entry.msgid.endswith(".") and not entry.msgstr.endswith("."):
104
 
            """ Error; Dot doesn't match """
105
 
            self.print_error(entry)
106
 
        elif not entry.msgid.endswith(".") and entry.msgstr.endswith("."):
107
 
            """ Warning; Dot doesn't match (original string doesn't end with dot) """
108
 
            self.print_warning(entry, " . ")
109
 
        elif (entry.msgid.endswith(":") and not entry.msgstr.endswith(":")) \
110
 
            or (not entry.msgid.endswith(":") and entry.msgstr.endswith(":")):
 
92
        if entry.msgid_plural:
 
93
            # Singular
 
94
            original = entry.msgid
 
95
            translation = entry.msgstr_plural.values()[1]
 
96
 
 
97
            # Only check plural when singular gave no error
 
98
            if self.is_proper_string(entry, original, translation):
 
99
                # Plural
 
100
                original = entry.msgid_plural
 
101
                translation = entry.msgstr_plural.values()[0]
 
102
                self.is_proper_string(entry, original, translation)
 
103
        else:
 
104
            original = entry.msgid
 
105
            translation = entry.msgstr
 
106
            self.is_proper_string(entry, original, translation)
 
107
 
 
108
 
 
109
    def is_proper_string(self, entry, original, translation):
 
110
        """ Checks two strings of an entry on possible flaws 
 
111
            Returns False when an error or warning is found, True otherwise
 
112
        """
 
113
        if original.strip().endswith("..."): 
 
114
            if not (translation.strip().endswith("...")   \
 
115
                or translation.strip().endswith("…".decode("utf-8"))):
 
116
                """ Error; period doesn't match """
 
117
                self.print_error(original, translation)
 
118
                return False
 
119
        elif original.endswith(".") and not translation.endswith("."):
 
120
            """ Error; period doesn't match """
 
121
            self.print_error(original, translation, " period doesn't match.")
 
122
            return False
 
123
        elif not original.endswith(".") and translation.endswith("."):
 
124
            """ Warning; period doesn't match (original string doesn't end with period) """
 
125
            self.print_warning(original, translation, " period doesn't match (original string doesn't end with period).")
 
126
            return False
 
127
        elif (original.endswith(":") and not translation.endswith(":")) \
 
128
            or (not original.endswith(":") and translation.endswith(":")):
111
129
            """ Error; Colon doesn't match """
112
 
            self.print_error(entry)
113
 
        elif "_" in entry.msgid and not "_" in entry.msgstr:
 
130
            self.print_error(original, translation)
 
131
            return False
 
132
        elif "_" in original and not "_" in translation:
114
133
            """Warning; forgot an underscore? """
115
 
            self.print_warning(entry, " _ ")
116
 
        elif "..." in entry.msgstr:
 
134
            self.print_warning(original, translation, " _ forgot an underscore?")
 
135
            return False
 
136
        elif "..." in translation:
117
137
            """ Warning; in Dutch we use … instead of ... """
118
 
            self.print_warning(entry, "...")
119
 
        elif entry.msgstr.count("'") > 1:
 
138
            self.print_warning(original, translation, "...  in Dutch we use … instead of ... ")
 
139
            return False
 
140
        elif translation.count("'") > 1:
120
141
            """ Warning; in Dutch we use ‘ ’ instead of ' '  """
121
 
            self.print_warning(entry, "Quotation")
 
142
            self.print_warning(original, translation, "Quotation; in Dutch we use ‘ ’ instead of ' ' ")
 
143
            return False
 
144
        return True
 
145
 
122
146
 
123
147
## Run the actual program
124
148
tc = TranslationChecker()