Avoid generating duplicate msgs in Dojo POT file; avoid populating msgstr in Dojo...
[working/Evergreen.git] / build / i18n / scripts / dojo_resource.py
1 #!/usr/bin/env python
2 # dojo_resource.py
3 """
4 This class enables translation of Dojo resource bundles using gettext format.
5
6 Requires polib from http://polib.googlecode.com
7
8 Source event definitions are structured as follows:
9 {
10     MSG_ID1: "This is a message with 1 variable - ${0}.",
11     MSG_ID2: "This is a message with two variables: ${0} and ${1}."
12 }
13
14 Note that this is a deliberately limited subset of the variable substitution
15 allowed by http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.string.substitute
16
17 """
18 # Copyright 2007 Dan Scott <dscott@laurentian.ca>
19 #
20 # This program is free software; you can redistribute it and/or
21 # modify it under the terms of the GNU General Public License
22 # as published by the Free Software Foundation; either version 2
23 # of the License, or (at your option) any later version.
24 #
25 # This program is distributed in the hope that it will be useful,
26 # but WITHOUT ANY WARRANTY; without even the implied warranty of
27 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 # GNU General Public License for more details.
29
30 import basel10n
31 import optparse
32 import polib
33 import re
34 import sys
35 import simplejson
36 import os.path
37
38 class DojoResource (basel10n.BaseL10N):
39     """
40     This class provides methods for extracting translatable strings from
41     Evergreen's Dojo resource bundle files, generating translatable POT files,
42     reading translated PO files, and generating an updated Dojo resource bundle
43     files with additional or changed strings.
44     """
45
46     def __init__(self):
47         self.pot = None
48         basel10n.BaseL10N.__init__(self)
49         self.msgs = {}
50
51     def get_strings(self, source):
52         """
53         Extracts translatable strings from Evergreen's Dojo resource bundles.
54         """
55         self.pothead()
56
57         # Avoid generating duplicate entries by keeping track of msgids
58         msgids = dict()
59
60         bundle = simplejson.load(open(source, 'r'))
61
62         for key, value in bundle.iteritems():
63             if value in msgids:
64                 msgids[str(value)].occurrences.append((os.path.basename(source), str(key)))
65             else:
66                 poe = polib.POEntry()
67                 poe.occurrences = [(os.path.basename(source), str(key))]
68                 poe.msgid = str(value)
69                 msgids[str(value)] = poe
70
71         # Now add the POEntries to our POFile
72         for poe in msgids.values():
73             self.pot.append(poe)
74
75     def create_bundle(self):
76         """
77         Creates a Dojo resource bundle file based on a translated PO file.
78         """
79
80         for entry in self.pot:
81             for filename, msgkey in entry.occurrences:
82                 if entry.msgstr == '':
83                     # No translation available; use the en-US definition
84                     self.msgs[msgkey] = entry.msgid
85                 else:
86                     self.msgs[msgkey] = entry.msgstr
87
88 def main():
89     """
90     Determine what action to take
91     """
92     opts = optparse.OptionParser()
93     opts.add_option('-p', '--pot', action='store', \
94         help='Create a POT file from the specified Dojo resource bundle file', \
95         metavar='FILE')
96     opts.add_option('-c', '--create', action='store', \
97         help='Create a Dojo resource bundle file from a translated PO FILE', \
98         metavar='FILE')
99     opts.add_option('-o', '--output', dest='outfile', \
100         help='Write output to FILE (defaults to STDOUT)', metavar='FILE')
101     (options, args) = opts.parse_args()
102
103     pot = DojoResource()
104
105     # Generate a new POT file from the Dojo resource bundle file
106     if options.pot:
107         pot.get_strings(options.pot)
108         if options.outfile:
109             pot.savepot(options.outfile)
110         else:
111             sys.stdout.write(pot.pot.__str__())
112
113     # Generate an Dojo resource bundle file from a PO file
114     elif options.create:
115         pot.loadpo(options.create)
116         pot.create_bundle()
117         if options.outfile:
118             outfile = open(options.outfile, 'w')
119             simplejson.dump(pot.msgs, outfile, indent=4)
120         else:
121             print(simplejson.dumps(pot.msgs, indent=4))
122
123     # No options were recognized - print help and bail
124     else:
125         opts.print_help()
126
127 if __name__ == '__main__':
128     main()