]> git.evergreen-ils.org Git - working/Evergreen.git/blob - build/i18n/tests/check_properties.py
Translation updates - po files
[working/Evergreen.git] / build / i18n / tests / check_properties.py
1 #!/usr/bin/env python
2 # -----------------------------------------------------------------------
3 # Copyright (C) 2008  Laurentian University
4 # Dan Scott <dscott@laurentian.ca>
5
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 # -----------------------------------------------------------------------
16
17 # vim:et:sw=4:ts=4: set fileencoding=utf-8 :
18
19 """
20 Parse i18n properties files and XUL / JavaScript files looking for trouble
21     * Invalid strings
22     * Unused strings
23     * Missing strings
24 """
25
26 import os
27 import re
28
29 DEBUG = False
30
31 PROP_DIRS = (
32         '../../../Open-ILS/xul/staff_client/server/locale/en-US/',
33         '../../../Open-ILS/xul/staff_client/chrome/locale/en-US/'
34         )
35
36 XUL_DIRS = (
37         '../../../Open-ILS/xul/staff_client/server/',
38         '../../../Open-ILS/xul/staff_client/chrome/',
39         )
40
41 def parse_properties():
42     """
43     Parse the properties files in known places
44     """
45
46     basedir = os.path.normpath(os.path.dirname(os.path.abspath(__file__)))
47
48     properties = {}
49
50     prop_files = []
51
52     for p_dir in PROP_DIRS:
53         p_dir = os.path.normpath(os.path.join(basedir, p_dir))
54         file_list = os.listdir(p_dir)
55         for p_file in file_list:
56             if os.path.splitext(p_file)[1] == '.properties':
57                 prop_files.append(os.path.join(p_dir, p_file))
58
59     prefix = os.path.commonprefix(prop_files)
60
61     for p_file in prop_files:
62
63         # Get the shortest unique address for this file
64         short_pf = p_file[len(prefix):]
65
66         prop_file = open(p_file, 'r')
67
68         line_num = 1
69
70         for line in prop_file:
71             line_num += 1
72
73             # Get rid of trailing linefeed
74             line = line[0:-1]
75
76             # Skip comments
77             if not line or line[0] == '#':
78                 continue
79
80             # Split property/value on first = sign
81             unpack = re.split('=', line, 1)
82
83             # If a line doesn't have an = sign, is that okay (run-on from previous?) or illegal?
84             # I think it's illegal
85             if len(unpack) != 2:
86                 print("%s:%d: No property in line [%s]" % (short_pf, line_num, line))
87                 continue
88
89             prop_key, value = unpack
90
91             if not properties.has_key(prop_key):
92                 properties[prop_key] = [{'value': value, 'file': short_pf}]
93                 continue
94
95             for entry in properties[prop_key]:
96                 if entry['file'] == short_pf:
97                     print("File: %s:%d"% (short_pf, line_num))
98                     print("\tDuplicate key '%s' in line [%s]" % (prop_key, line[0:-1]))
99                     continue
100
101             properties[prop_key].append({'value': value, 'file': short_pf})
102
103         prop_file.close()
104
105     return properties
106
107 def check_xul_files(props):
108     """
109     Finds all the XUL and JavaScript files
110     """
111
112     basedir = os.path.normpath(os.path.dirname(os.path.abspath(__file__)))
113
114     xul_files = []
115
116     for x_dir in XUL_DIRS:
117         for root, dirs, files in os.walk(os.path.join(basedir, x_dir)):
118             for x_file in files:
119                 if os.path.splitext(x_file)[1] == '.xul' or os.path.splitext(x_file)[1] == '.js':
120                     check_xul(root, x_file, props)
121
122 def check_xul(root, filename, props):
123     """
124     Parse all getString() and getFormattedString() calls in XUL and JavaScript
125     files to ensure:
126       * that the requested property exists
127       * that every property is actually required
128     """
129
130     num_strings = 0
131
132     # Typical example of a getString request:
133     # document.getElementById('catStrings').getString('staff.cat.bib_brief.deleted')
134     strings = re.compile(r'''\(\s*?(['"])([^'"]+?)Strings\1\s*?\)\.getString\(\s*?(['"])([^'"]+?)\3\s*?\)''')
135
136     # Typical example of a getFormattedString request:
137     # document.getElementById('catStrings').getFormattedString('staff.cat.bib_brief.record_id', [docid])
138     formed_strings = re.compile(r'''\(\s*?(['"])([^'"]+?)Strings\1\s*?\)\.getFormattedString\(\s*?(['"])([^'"]+?)\3\s*?,\s*\[(.+?)\]\s*\)\)''')
139
140     xul = open(os.path.join(root, filename), 'r')
141     content = xul.read()
142     xul.close()
143
144     if DEBUG:
145         print "File: %s" % (os.path.normpath(os.path.join(root, filename)))
146
147     for s_match in strings.finditer(content):
148         num_strings += 1
149         #print "\tStringset: %s ID: %s" % (s_match.group(2), s_match.group(4))
150         if not props.has_key(s_match.group(4)):
151             print "File: %s" % (os.path.normpath(os.path.join(root, filename)))
152             print "\tID %s not found, expected in %sStrings" % (s_match.group(4), s_match.group(2))
153
154     for s_match in formed_strings.finditer(content):
155         num_strings += 1
156         #print "\tStringset: %s ID: %s, data: %s" % (s_match.group(2), s_match.group(4), s_match.group(5))
157         if not props.has_key(s_match.group(4)):
158             print "File: %s" % (os.path.normpath(os.path.join(root, filename)))
159             print "\tID %s not found, expected in %sStrings" % (s_match.group(4), s_match.group(2))
160
161     if DEBUG:
162         print "\t%d i18n calls found" % (num_strings)
163
164 if __name__ == '__main__':
165     props = parse_properties() 
166     check_xul_files(props)