4 This class enables translation of Evergreen's ils_events XML file.
6 Requires polib from http://polib.googlecode.com
8 Source event definitions are structured as follows:
10 <event code='1' textcode='UNKNOWN'>
11 <desc xml:lang="en-US">Placeholder event. Used for development only</desc>
15 This generates an updated file with the following structure:
17 <event code='1' textcode='UNKNOWN'>
18 <desc xml:lang="en-US">Placeholder event. Used for development only</desc>
19 <desc xml:lang="fr-CA">Exemple - seulement developpement</desc>
23 # Copyright 2007 Dan Scott <dscott@laurentian.ca>
25 # This program is free software; you can redistribute it and/or
26 # modify it under the terms of the GNU General Public License
27 # as published by the Free Software Foundation; either version 2
28 # of the License, or (at your option) any later version.
30 # This program is distributed in the hope that it will be useful,
31 # but WITHOUT ANY WARRANTY; without even the implied warranty of
32 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 # GNU General Public License for more details.
42 import xml.sax.handler
44 class ILSEvents(basel10n.BaseL10N):
46 This class provides methods for extracting translatable strings from
47 Evergreen's ils_events XML file, generating a translatable POT file,
48 reading translated PO files, and generating an updated ils_events.xml
49 file with the additional language strings.
54 basel10n.BaseL10N.__init__(self)
58 def get_strings(self, source):
60 Extracts translatable strings from the //desc[@lang='en-US'] attributes
61 in Evergreen's ils_events.xml file.
65 locator = xml.sax.xmlreader.Locator()
66 parser = xml.sax.make_parser()
67 handler = ILSEventHandler()
68 handler.setDocumentLocator(locator)
69 parser.setContentHandler(handler)
72 for entry in handler.events:
74 poe.occurrences = handler.events[entry]
78 def create_events(self):
80 Creates an ILS events XML file based on a translated PO file.
82 Each PO entry has one or more file comment with the following structure:
84 #: numcode.textcode:lineno
87 event = """ <event code='%d' textcode='%s'>
88 <desc xml:lang='%s'>%s</desc>\n </event>"""
90 # We should generate this in a real XML way, rather than faking it
91 # But we'll fake it for now
92 for entry in self.pot:
93 for name in entry.occurrences:
95 pat = re.compile(r'(\d+)\.(\w+)').match(name[0])
96 numcode = pat.group(1)
97 textcode = pat.group(2)
99 if entry.msgstr == '':
100 # No translation available; use the en-US definition
101 self.definitions.append(event % (int(numcode), textcode, self.locale, entry.msgid))
103 self.definitions.append(event % (int(numcode), textcode, self.locale, entry.msgstr))
105 class ILSEventHandler(xml.sax.handler.ContentHandler):
107 Parses an ils_events.xml file to get at event[@code] attributes and
108 the contained desc[@lang='en-US'] elements.
110 Generates a list of events and their English descriptions.
114 xml.sax.handler.ContentHandler.__init__(self)
117 self.en_us_flag = False
122 def setDocumentLocator(self, locator):
124 Override setDocumentLocator so we can track line numbers
126 self.locator = locator
128 def startElement(self, name, attributes):
130 Grab the event code attribute value for each class
134 self.numcode = attributes['code']
135 self.textcode = attributes['textcode']
136 if name == 'desc' and attributes['xml:lang'] == 'en-US':
137 self.en_us_flag = True
139 def characters(self, content):
141 Build the ILS event description
143 if self.en_us_flag is True and content is not None:
146 def endElement(self, name):
148 Generate the event with the closed description
150 if name == 'desc' and self.en_us_flag is True:
151 lineno = self.locator.getLineNumber()
152 event = "%d.%s" % (int(self.numcode), self.textcode)
153 if self.events.has_key(self.desc):
154 self.events[self.desc].append([str(event), lineno])
156 self.events[self.desc] = [[str(event), lineno]]
160 self.en_us_flag = False
166 Determine what action to take
168 opts = optparse.OptionParser()
169 opts.add_option('-p', '--pot', action='store', \
170 help='Create a POT file from the specified ils_events.xml file', \
172 opts.add_option('-c', '--create', action='store', \
173 help='Create an ils_events.xml file from a translated PO FILE', \
175 opts.add_option('-l', '--locale', action='store', \
176 help='Locale of the ils_events.xml file that will be generated', \
178 opts.add_option('-o', '--output', dest='outfile', \
179 help='Write output to FILE (defaults to STDOUT)', metavar='FILE')
180 (options, args) = opts.parse_args()
184 # Generate a new POT file from the ils_events.xml file
186 pot.get_strings(options.pot)
188 pot.savepot(options.outfile)
190 sys.stdout.write(pot.pot.__str__())
192 # Generate an ils_events.xml file from a PO file
195 pot.locale = options.locale
197 opts.error('Must specify an output locale to create an XML file')
199 head = """<?xml version="1.0" encoding="utf-8"?>
203 tail = "</ils_events>"
205 pot.loadpo(options.create)
208 outfile = codecs.open(options.outfile, encoding='utf-8', mode='w')
210 for event in pot.definitions:
211 outfile.write(event + "\n")
215 for event in pot.definitions:
219 # No options were recognized - print help and bail
223 if __name__ == '__main__':