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