1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """convert Gettext PO localization files to an OpenOffice.org (SDF) localization file
24
25 see: http://translate.sourceforge.net/wiki/toolkit/po2oo for examples and
26 usage instructions
27 """
28
29 import sys
30 import os
31 from translate.storage import oo
32 from translate.storage import factory
33 from translate.filters import pofilter
34 from translate.filters import checks
35 from translate.filters import autocorrect
36 import time
37
39 - def __init__(self, templatefile, languages=None, timestamp=None, includefuzzy=False, long_keys=False, filteraction="exclude"):
40 """construct a reoo converter for the specified languages (timestamp=0 means leave unchanged)"""
41
42 self.long_keys = long_keys
43 self.readoo(templatefile)
44 self.languages = languages
45 self.filteraction = filteraction
46 if timestamp is None:
47 self.timestamp = time.strptime("2002-02-02 02:02:02", "%Y-%m-%d %H:%M:%S")
48 else:
49 self.timestamp = timestamp
50 if self.timestamp:
51 self.timestamp_str = time.strftime("%Y-%m-%d %H:%M:%S", self.timestamp)
52 else:
53 self.timestamp_str = None
54 self.includefuzzy = includefuzzy
55
57 """converts an oo key tuple into a key identifier for the source file"""
58 project, sourcefile, resourcetype, groupid, localid, platform = ookey
59 sourcefile = sourcefile.replace('\\','/')
60 if self.long_keys:
61 sourcebase = os.path.join(project, sourcefile)
62 else:
63 sourceparts = sourcefile.split('/')
64 sourcebase = "".join(sourceparts[-1:])
65 if len(groupid) == 0 or len(localid) == 0:
66 fullid = groupid + localid
67 else:
68 fullid = groupid + "." + localid
69 if resourcetype:
70 fullid = fullid + "." + resourcetype
71 key = "%s#%s" % (sourcebase, fullid)
72 return oo.normalizefilename(key)
73
75 """makes an index of the oo keys that are used in the source file"""
76 self.index = {}
77 for ookey, theoo in self.o.ookeys.iteritems():
78 sourcekey = self.makekey(ookey)
79 self.index[sourcekey] = theoo
80
87
89
90 locations = unit.getlocations()
91
92
93 for location in locations:
94 subkeypos = location.rfind('.')
95 subkey = location[subkeypos+1:]
96 key = location[:subkeypos]
97
98 key = key.replace(':', '#')
99
100 key = key.replace('\\', '/')
101 key = oo.normalizefilename(key)
102 if self.index.has_key(key):
103
104 theoo = self.index[key]
105 self.applytranslation(key, subkey, theoo, unit)
106 else:
107 print >> sys.stderr, "couldn't find key %s from po in %d keys" % (key, len(self.index))
108 try:
109 sourceunitlines = str(unit)
110 if isinstance(sourceunitlines, unicode):
111 sourceunitlines = sourceunitlines.encode("utf-8")
112 print >> sys.stderr, sourceunitlines
113 except:
114 print >> sys.stderr, "error outputting source unit %r" % (str(unit),)
115
117 """applies the translation from the source unit to the oo unit"""
118 if not self.includefuzzy and unit.isfuzzy():
119 return
120 makecopy = False
121 if self.languages is None:
122 part1 = theoo.lines[0]
123 if len(theoo.lines) > 1:
124 part2 = theoo.lines[1]
125 else:
126 makecopy = True
127 else:
128 part1 = theoo.languages[self.languages[0]]
129 if self.languages[1] in theoo.languages:
130 part2 = theoo.languages[self.languages[1]]
131 else:
132 makecopy = True
133 if makecopy:
134 part2 = oo.ooline(part1.getparts())
135 unquotedid = unit.source
136 unquotedstr = unit.target
137
138 if len(unquotedstr) == 0:
139 return
140 if isinstance(unquotedstr, unicode):
141 unquotedstr = unquotedstr.encode("UTF-8")
142
143 if len(unquotedstr) > 0:
144 setattr(part2, subkey, unquotedstr)
145
146 if self.timestamp_str:
147 part2.timestamp = self.timestamp_str
148 if self.languages:
149 part2.languageid = self.languages[1]
150 if makecopy:
151 theoo.addline(part2)
152
162
164 import stat
165 return time.localtime(os.stat(filename)[stat.ST_MTIME])
166
169 """Returns whether or not to use unit in conversion. (filename is just for error reporting)"""
170 if filteraction == "none": return True
171 filterresult = self.filterunit(unit)
172 if filterresult:
173 if filterresult != autocorrect:
174 for filtername, filtermessage in filterresult.iteritems():
175 location = unit.getlocations()[0].encode('utf-8')
176 if filtername in self.options.error:
177 print >> sys.stderr, "Error at %s::%s: %s" % (filename, location, filtermessage)
178 return not filteraction in ["exclude-all", "exclude-serious"]
179 if filtername in self.options.warning or self.options.alwayswarn:
180 print >> sys.stderr, "Warning at %s::%s: %s" % (filename, location, filtermessage)
181 return not filteraction in ["exclude-all"]
182 return True
183
198
199 options = oofilteroptions()
200 filter = oocheckfilter(options, [checks.OpenOfficeChecker, checks.StandardUnitChecker], checks.openofficeconfig)
201
202 -def convertoo(inputfile, outputfile, templatefile, sourcelanguage=None, targetlanguage=None, timestamp=None, includefuzzy=False, multifilestyle="single", filteraction=None):
203 inputstore = factory.getobject(inputfile)
204 inputstore.filename = getattr(inputfile, 'name', '')
205 if not targetlanguage:
206 raise ValueError("You must specify the target language")
207 if not sourcelanguage:
208 if targetlanguage.isdigit():
209 sourcelanguage = "01"
210 else:
211 sourcelanguage = "en-US"
212 languages = (sourcelanguage, targetlanguage)
213 if templatefile is None:
214 raise ValueError("must have template file for oo files")
215 else:
216 convertor = reoo(templatefile, languages=languages, timestamp=timestamp, includefuzzy=includefuzzy, long_keys=multifilestyle != "single", filteraction=filteraction)
217 outputstore = convertor.convertstore(inputstore)
218
219 outputfile.write(str(outputstore))
220 return True
221
222 -def main(argv=None):
223 from translate.convert import convert
224 formats = {("po", "oo"):("oo", convertoo), ("xlf", "oo"):("oo", convertoo), ("po", "sdf"):("sdf", convertoo)}
225
226 archiveformats = {(None, "output"): oo.oomultifile, (None, "template"): oo.oomultifile}
227 parser = convert.ArchiveConvertOptionParser(formats, usetemplates=True, description=__doc__, archiveformats=archiveformats)
228 parser.add_option("-l", "--language", dest="targetlanguage", default=None,
229 help="set target language code (e.g. af-ZA) [required]", metavar="LANG")
230 parser.add_option("", "--source-language", dest="sourcelanguage", default=None,
231 help="set source language code (default en-US)", metavar="LANG")
232 parser.add_option("-T", "--keeptimestamp", dest="timestamp", default=None, action="store_const", const=0,
233 help="don't change the timestamps of the strings")
234 parser.add_option("", "--nonrecursiveoutput", dest="allowrecursiveoutput", default=True, action="store_false", help="don't treat the output oo as a recursive store")
235 parser.add_option("", "--nonrecursivetemplate", dest="allowrecursivetemplate", default=True, action="store_false", help="don't treat the template oo as a recursive store")
236 parser.add_option("", "--filteraction", dest="filteraction", default="none", metavar="ACTION",
237 help="action on pofilter failure: none (default), warn, exclude-serious, exclude-all")
238 parser.add_fuzzy_option()
239 parser.add_multifile_option()
240 parser.passthrough.append("sourcelanguage")
241 parser.passthrough.append("targetlanguage")
242 parser.passthrough.append("timestamp")
243 parser.passthrough.append("filteraction")
244 parser.run(argv)
245
246 if __name__ == '__main__':
247 main()
248