1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """convert Java/Mozilla .properties files to Gettext PO localization files
23
24 See: http://translate.sourceforge.net/wiki/toolkit/prop2po for examples and
25 usage instructions
26 """
27
28 import sys
29 from translate.storage import po
30 from translate.storage import properties
31
32
34 """convert a .properties file to a .po file for handling the
35 translation."""
36
37 - def convertstore(self, thepropfile, personality="java",
38 duplicatestyle="msgctxt"):
39 """converts a .properties file to a .po file..."""
40 self.personality = personality
41 thetargetfile = po.pofile()
42 if self.personality == "mozilla" or self.personality == "skype":
43 targetheader = thetargetfile.init_headers(charset="UTF-8",
44 encoding="8bit",
45 x_accelerator_marker="&")
46 else:
47 targetheader = thetargetfile.init_headers(charset="UTF-8",
48 encoding="8bit")
49 targetheader.addnote("extracted from %s" % thepropfile.filename,
50 "developer")
51
52
53 appendedheader = False
54 waitingcomments = []
55 for propunit in thepropfile.units:
56 pounit = self.convertunit(propunit, "developer")
57 if pounit is None:
58 waitingcomments.extend(propunit.comments)
59
60 if pounit is "discard":
61 continue
62 if not appendedheader:
63 if propunit.isblank():
64 targetheader.addnote("\n".join(waitingcomments).rstrip(),
65 "developer", position="prepend")
66 waitingcomments = []
67 pounit = None
68 appendedheader = True
69 if pounit is not None:
70 pounit.addnote("\n".join(waitingcomments).rstrip(),
71 "developer", position="prepend")
72 waitingcomments = []
73 thetargetfile.addunit(pounit)
74 thetargetfile.removeduplicates(duplicatestyle)
75 return thetargetfile
76
77 - def mergestore(self, origpropfile, translatedpropfile, personality="java",
78 blankmsgstr=False, duplicatestyle="msgctxt"):
79 """converts two .properties files to a .po file..."""
80 self.personality = personality
81 thetargetfile = po.pofile()
82 if self.personality == "mozilla" or self.personality == "skype":
83 targetheader = thetargetfile.init_headers(charset="UTF-8",
84 encoding="8bit",
85 x_accelerator_marker="&")
86 else:
87 targetheader = thetargetfile.init_headers(charset="UTF-8",
88 encoding="8bit")
89 targetheader.addnote("extracted from %s, %s" % (origpropfile.filename, translatedpropfile.filename),
90 "developer")
91 translatedpropfile.makeindex()
92
93
94 appendedheader = False
95 waitingcomments = []
96
97 for origprop in origpropfile.units:
98 origpo = self.convertunit(origprop, "developer")
99 if origpo is None:
100 waitingcomments.extend(origprop.comments)
101
102 if origpo is "discard":
103 continue
104
105 if not appendedheader:
106 if origprop.isblank():
107 targetheader.addnote(u"".join(waitingcomments).rstrip(),
108 "developer", position="prepend")
109 waitingcomments = []
110 origpo = None
111 appendedheader = True
112
113 if origprop.name in translatedpropfile.locationindex:
114 translatedprop = translatedpropfile.locationindex[origprop.name]
115
116
117 translatedpo = self.convertunit(translatedprop, "translator")
118 if translatedpo is "discard":
119 continue
120 else:
121 translatedpo = None
122
123 if origpo is not None:
124 if translatedpo is not None and not blankmsgstr:
125 origpo.target = translatedpo.source
126 origpo.addnote(u"".join(waitingcomments).rstrip(),
127 "developer", position="prepend")
128 waitingcomments = []
129 thetargetfile.addunit(origpo)
130 elif translatedpo is not None:
131 print >> sys.stderr, "error converting original properties definition %s" % origprop.name
132 thetargetfile.removeduplicates(duplicatestyle)
133 return thetargetfile
134
154
155
156 -def convertstrings(inputfile, outputfile, templatefile, personality="strings",
157 pot=False, duplicatestyle="msgctxt", encoding=None):
158 """.strings specific convertor function"""
159 return convertprop(inputfile, outputfile, templatefile,
160 personality="strings", pot=pot,
161 duplicatestyle=duplicatestyle, encoding=encoding)
162
163
164 -def convertmozillaprop(inputfile, outputfile, templatefile, pot=False,
165 duplicatestyle="msgctxt"):
166 """Mozilla specific convertor function"""
167 return convertprop(inputfile, outputfile, templatefile,
168 personality="mozilla", pot=pot,
169 duplicatestyle=duplicatestyle)
170
171
172 -def convertprop(inputfile, outputfile, templatefile, personality="java",
173 pot=False, duplicatestyle="msgctxt", encoding=None):
174 """reads in inputfile using properties, converts using prop2po, writes
175 to outputfile"""
176 inputstore = properties.propfile(inputfile, personality, encoding)
177 convertor = prop2po()
178 if templatefile is None:
179 outputstore = convertor.convertstore(inputstore, personality,
180 duplicatestyle=duplicatestyle)
181 else:
182 templatestore = properties.propfile(templatefile, personality, encoding)
183 outputstore = convertor.mergestore(templatestore, inputstore,
184 personality, blankmsgstr=pot,
185 duplicatestyle=duplicatestyle)
186 if outputstore.isempty():
187 return 0
188 outputfile.write(str(outputstore))
189 return 1
190
191 formats = {
192 "properties": ("po", convertprop),
193 ("properties", "properties"): ("po", convertprop),
194 "lang": ("po", convertprop),
195 ("lang", "lang"): ("po", convertprop),
196 "strings": ("po", convertstrings),
197 ("strings", "strings"): ("po", convertstrings),
198 }
199
200
201 -def main(argv=None):
202 from translate.convert import convert
203 parser = convert.ConvertOptionParser(formats, usetemplates=True,
204 usepots=True,
205 description=__doc__)
206 parser.add_option("", "--personality", dest="personality",
207 default=properties.default_dialect,
208 type="choice",
209 choices=properties.dialects.keys(),
210 help="override the input file format: %s (for .properties files, default: %s)" %
211 (", ".join(properties.dialects.iterkeys()),
212 properties.default_dialect),
213 metavar="TYPE")
214 parser.add_option("", "--encoding", dest="encoding", default=None,
215 help="override the encoding set by the personality",
216 metavar="ENCODING")
217 parser.add_duplicates_option()
218 parser.passthrough.append("pot")
219 parser.passthrough.append("personality")
220 parser.passthrough.append("encoding")
221 parser.run(argv)
222
223 if __name__ == '__main__':
224 main()
225