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.
41 import xml.sax.handler
43 class ILSEvents(basel10n.BaseL10N):
45 This class provides methods for extracting translatable strings from
46 Evergreen's ils_events XML file, generating a translatable POT file,
47 reading translated PO files, and generating an updated ils_events.xml
48 file with the additional language strings.
53 basel10n.BaseL10N.__init__(self)
57 def get_strings(self, source):
59 Extracts translatable strings from the //desc[@lang='en-US'] attributes
60 in Evergreen's ils_events.xml file.
64 locator = xml.sax.xmlreader.Locator()
65 parser = xml.sax.make_parser()
66 handler = ILSEventHandler()
67 handler.setDocumentLocator(locator)
68 parser.setContentHandler(handler)
71 for entry in handler.events:
73 poe.occurrences = handler.events[entry]
77 def create_events(self):
79 Creates an ILS events XML file based on a translated PO file.
81 Each PO entry has one or more file comment with the following structure:
83 #: numcode.textcode:lineno
86 event = """ <event code='%d' textcode='%s'>
87 <desc xml:lang='%s'>%s</desc>\n </event>"""
89 # We should generate this in a real XML way, rather than faking it
90 # But we'll fake it for now
91 for entry in self.pot:
92 for name in entry.occurrences:
94 pat = re.compile(r'(\d+)\.(\w+)').match(name[0])
95 numcode = pat.group(1)
96 textcode = pat.group(2)
98 if entry.msgstr == '':
99 # No translation available; use the en-US definition
100 self.definitions.append(event % (int(numcode), textcode, self.locale, entry.msgid))
102 self.definitions.append(event % (int(numcode), textcode, self.locale, entry.msgstr))
104 class ILSEventHandler(xml.sax.handler.ContentHandler):
106 Parses an ils_events.xml file to get at event[@code] attributes and
107 the contained desc[@lang='en-US'] elements.
109 Generates a list of events and their English descriptions.
113 xml.sax.handler.ContentHandler.__init__(self)
116 self.en_us_flag = False
121 def setDocumentLocator(self, locator):
123 Override setDocumentLocator so we can track line numbers
125 self.locator = locator
127 def startElement(self, name, attributes):
129 Grab the event code attribute value for each class
133 self.numcode = attributes['code']
134 self.textcode = attributes['textcode']
135 if name == 'desc' and attributes['xml:lang'] == 'en-US':
136 self.en_us_flag = True
138 def characters(self, content):
140 Build the ILS event description
142 if self.en_us_flag is True and content is not None:
145 def endElement(self, name):
147 Generate the event with the closed description
149 if name == 'desc' and self.en_us_flag is True:
150 lineno = self.locator.getLineNumber()
151 event = "%d.%s" % (int(self.numcode), self.textcode)
152 if self.events.has_key(self.desc):
153 self.events[self.desc].append([str(event), lineno])
155 self.events[self.desc] = [[str(event), lineno]]
159 self.en_us_flag = False
165 Determine what action to take
167 opts = optparse.OptionParser()
168 opts.add_option('-p', '--pot', action='store', \
169 help='Create a POT file from the specified ils_events.xml file', \
171 opts.add_option('-c', '--create', action='store', \
172 help='Create an ils_events.xml file from a translated PO FILE', \
174 opts.add_option('-l', '--locale', action='store', \
175 help='Locale of the ils_events.xml file that will be generated', \
177 opts.add_option('-o', '--output', dest='outfile', \
178 help='Write output to FILE (defaults to STDOUT)', metavar='FILE')
179 (options, args) = opts.parse_args()
183 # Generate a new POT file from the ils_events.xml file
185 pot.get_strings(options.pot)
187 pot.savepot(options.outfile)
189 sys.stdout.write(pot.pot.__str__())
191 # Generate an ils_events.xml file from a PO file
194 pot.locale = options.locale
196 opts.error('Must specify an output locale to create an XML file')
198 head = """<?xml version="1.0" encoding="utf-8"?>
202 tail = "</ils_events>"
204 pot.loadpo(options.create)
207 outfile = open(options.outfile, 'w')
209 for event in pot.definitions:
210 outfile.write(event + "\n")
214 for event in pot.definitions:
218 # No options were recognized - print help and bail
222 if __name__ == '__main__':