4 This class enables translation of Dojo resource bundles using gettext format.
6 Requires polib from http://polib.googlecode.com
8 Source event definitions are structured as follows:
10 "MSG_ID1": "This is a message with 1 variable - ${0}.",
11 "MSG_ID2": "This is a message with two variables: ${0} and ${1}."
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
18 # Copyright 2007 Dan Scott <dscott@laurentian.ca>
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.
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.
39 from builtins import str
41 class DojoResource (basel10n.BaseL10N):
43 This class provides methods for extracting translatable strings from
44 Evergreen's Dojo resource bundle files, generating translatable POT files,
45 reading translated PO files, and generating an updated Dojo resource bundle
46 files with additional or changed strings.
51 basel10n.BaseL10N.__init__(self)
54 def get_strings(self, source):
56 Extracts translatable strings from Evergreen's Dojo resource bundles.
60 # Avoid generating duplicate entries by keeping track of msgids
64 bundle = simplejson.load(codecs.open(source, encoding='utf-8', mode='r'))
66 print("Reading Dojo resource file %s" % (source))
69 for key, value in bundle.items():
71 msgids[str(value)].occurrences.append((os.path.basename(source), str(key)))
74 poe.occurrences = [(os.path.basename(source), str(key))]
75 poe.msgid = str(value)
76 msgids[str(value)] = poe
78 # Now add the POEntries to our POFile
79 for poe in msgids.values():
82 def create_bundle(self):
84 Creates a Dojo resource bundle file based on a translated PO file.
87 for entry in self.pot:
88 for occurrence in entry.occurrences:
89 # Ack. Horrible hack because polib started insisting
90 # that occurrences use integers for line numbers. The nerve!
91 filename, msgkey = occurrence[0].split('.js');
92 if entry.msgstr == '':
93 # No translation available; use the en-US definition
94 self.msgs[msgkey] = entry.msgid
96 self.msgs[msgkey] = entry.msgstr
100 Determine what action to take
102 opts = optparse.OptionParser()
103 opts.add_option('-p', '--pot', action='store', \
104 help='Create a POT file from the specified Dojo resource bundle file', \
106 opts.add_option('-c', '--create', action='store', \
107 help='Create a Dojo resource bundle file from a translated PO FILE', \
109 opts.add_option('-o', '--output', dest='outfile', \
110 help='Write output to FILE (defaults to STDOUT)', metavar='FILE')
111 (options, args) = opts.parse_args()
115 # Generate a new POT file from the Dojo resource bundle file
117 pot.get_strings(options.pot)
119 if not os.path.exists(os.path.dirname(options.outfile)):
120 os.makedirs(os.path.dirname(options.outfile))
121 pot.savepot(options.outfile)
123 sys.stdout.write(pot.pot.__str__())
125 # Generate an Dojo resource bundle file from a PO file
127 pot.loadpo(options.create)
130 if not os.path.exists(os.path.dirname(options.outfile)):
131 os.makedirs(os.path.dirname(options.outfile))
132 outfile = codecs.open(options.outfile, encoding='utf-8', mode='w')
133 simplejson.dump(pot.msgs, outfile, indent=4)
135 print(simplejson.dumps(pot.msgs, indent=4))
137 # No options were recognized - print help and bail
141 if __name__ == '__main__':