-
Notifications
You must be signed in to change notification settings - Fork 2k
/
check_po_files.py
executable file
·103 lines (71 loc) · 2.85 KB
/
check_po_files.py
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
#!/usr/bin/env python
# encoding: utf-8
'''Script for checking for common translation mistakes in po files, see:
paster check-po-files --help
for usage.
'''
import polib
import re
import six
if six.PY2:
import paste.script.command
def simple_conv_specs(s):
'''Return the simple Python string conversion specifiers in the string s.
e.g. ['%s', '%i']
See http://docs.python.org/library/stdtypes.html#string-formatting
'''
simple_conv_specs_re = re.compile(r'\%\w')
return simple_conv_specs_re.findall(s)
def mapping_keys(s):
'''Return a sorted list of the mapping keys in the string s.
e.g. ['%(name)s', '%(age)i']
See http://docs.python.org/library/stdtypes.html#string-formatting
'''
mapping_keys_re = re.compile(r'\%\([^\)]*\)\w')
return sorted(mapping_keys_re.findall(s))
def replacement_fields(s):
'''Return a sorted list of the Python replacement fields in the string s.
e.g. ['{}', '{2}', '{object}', '{target}']
See http://docs.python.org/library/string.html#formatstrings
'''
repl_fields_re = re.compile(r'\{[^\}]*\}')
return sorted(repl_fields_re.findall(s))
if six.PY2:
class CheckPoFiles(paste.script.command.Command):
usage = "[FILE] ..."
group_name = 'ckan'
summary = 'Check po files for common mistakes'
parser = paste.script.command.Command.standard_parser(verbose=True)
def command(self):
check_po_files(self.args)
def check_po_files(paths):
for path in paths:
print(u'Checking file {}'.format(path))
errors = check_po_file(path)
if errors:
for msgid, msgstr in errors:
print("Format specifiers don't match:")
print(u' {0} -> {1}'.format(
msgid, msgstr.encode('ascii', 'replace')))
def check_po_file(path):
errors = []
def check_translation(validator, msgid, msgstr):
if not validator(msgid) == validator(msgstr):
errors.append((msgid, msgstr))
po = polib.pofile(path)
for entry in po.translated_entries():
if entry.msgid_plural and entry.msgstr_plural:
for function in (simple_conv_specs, mapping_keys,
replacement_fields):
for key, msgstr in six.iteritems(entry.msgstr_plural):
if key == '0':
check_translation(function, entry.msgid,
entry.msgstr_plural[key])
else:
check_translation(function, entry.msgid_plural,
entry.msgstr_plural[key])
elif entry.msgstr:
for function in (simple_conv_specs, mapping_keys,
replacement_fields):
check_translation(function, entry.msgid, entry.msgstr)
return errors