1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """convert Comma-Separated Value (.csv) files to Gettext PO localization files
23
24 See: http://translate.sourceforge.net/wiki/toolkit/csv2po for examples and
25 usage instructions
26 """
27
28 import sys
29 from translate.misc import sparse
30 from translate.storage import po
31 from translate.storage import csvl10n
32
37
39 return '"' + replacestrings(source, ('\\"','"'), ('"','\\"'), ("\\\\'", "\\'"), ('\\\\n', '\\n')) + '"'
40
45
47 """a class that takes translations from a .csv file and puts them in a .po file"""
48 - def __init__(self, templatepo=None, charset=None, duplicatestyle="keep"):
49 """construct the converter..."""
50 self.pofile = templatepo
51 self.charset = charset
52 self.duplicatestyle = duplicatestyle
53 if self.pofile is not None:
54 self.unmatched = 0
55 self.makeindex()
56
58 """makes indexes required for searching..."""
59 self.commentindex = {}
60 self.sourceindex = {}
61 self.simpleindex = {}
62 self.duplicatecomments = []
63 for pounit in self.pofile.units:
64 joinedcomment = " ".join(pounit.getlocations())
65 source = pounit.source
66
67 if joinedcomment in self.commentindex:
68
69 self.duplicatecomments.append(joinedcomment)
70 else:
71 self.commentindex[joinedcomment] = pounit
72
73 simpleid = simplify(source)
74
75 if simpleid in self.simpleindex and not (source in self.sourceindex):
76
77 self.simpleindex[simpleid].append(pounit)
78 else:
79 self.simpleindex[simpleid] = [pounit]
80
81 self.sourceindex[source] = pounit
82 for comment in self.duplicatecomments:
83 if comment in self.commentindex:
84 del self.commentindex[comment]
85
94
96 """handles reintegrating a csv unit into the .po file"""
97 if len(csvunit.comment.strip()) > 0 and csvunit.comment in self.commentindex:
98 pounit = self.commentindex[csvunit.comment]
99 elif csvunit.source in self.sourceindex:
100 pounit = self.sourceindex[csvunit.source]
101 elif simplify(csvunit.source) in self.simpleindex:
102 thepolist = self.simpleindex[simplify(csvunit.source)]
103 if len(thepolist) > 1:
104 csvfilename = getattr(self.csvfile, "filename", "(unknown)")
105 matches = "\n ".join(["possible match: " + pounit.source for pounit in thepolist])
106 print >> sys.stderr, "%s - csv entry not found in pofile, multiple matches found:\n location\t%s\n original\t%s\n translation\t%s\n %s" % (csvfilename, csvunit.comment, csvunit.source, csvunit.target, matches)
107 self.unmatched += 1
108 return
109 pounit = thepolist[0]
110 else:
111 csvfilename = getattr(self.csvfile, "filename", "(unknown)")
112 print >> sys.stderr, "%s - csv entry not found in pofile:\n location\t%s\n original\t%s\n translation\t%s" % (csvfilename, csvunit.comment, csvunit.source, csvunit.target)
113 self.unmatched += 1
114 return
115 if pounit.hasplural():
116
117 singularid = pounit.source.strings[0]
118 pluralid = pounit.source.strings[1]
119 if csvunit.source == singularid:
120 pounit.msgstr[0] = csvunit.target
121 elif csvunit.source == pluralid:
122 pounit.msgstr[1] = csvunit.target
123 elif simplify(csvunit.source) == simplify(singularid):
124 pounit.msgstr[0] = csvunit.target
125 elif simplify(csvunit.source) == simplify(pluralid):
126 pounit.msgstr[1] = csvunit.target
127 else:
128 print >> sys.stderr, "couldn't work out singular or plural: %r, %r, %r" % \
129 (csvunit.source, singularid, pluralid)
130 self.unmatched += 1
131 return
132 else:
133 pounit.target = csvunit.target
134
169
170 -def convertcsv(inputfile, outputfile, templatefile, charset=None, columnorder=None, duplicatestyle="msgctxt"):
171 """reads in inputfile using csvl10n, converts using csv2po, writes to outputfile"""
172 inputstore = csvl10n.csvfile(inputfile, fieldnames=columnorder)
173 if templatefile is None:
174 convertor = csv2po(charset=charset, duplicatestyle=duplicatestyle)
175 else:
176 templatestore = po.pofile(templatefile)
177 convertor = csv2po(templatestore, charset=charset, duplicatestyle=duplicatestyle)
178 outputstore = convertor.convertstore(inputstore)
179 if outputstore.isempty():
180 return 0
181 outputfile.write(str(outputstore))
182 return 1
183
184 -def main(argv=None):
185 from translate.convert import convert
186 formats = {("csv", "po"): ("po", convertcsv), ("csv", "pot"): ("po", convertcsv),
187 ("csv", None): ("po", convertcsv)}
188 parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
189 parser.add_option("", "--charset", dest="charset", default=None,
190 help="set charset to decode from csv files", metavar="CHARSET")
191 parser.add_option("", "--columnorder", dest="columnorder", default=None,
192 help="specify the order and position of columns (location,source,target)")
193 parser.add_duplicates_option()
194 parser.passthrough.append("charset")
195 parser.passthrough.append("columnorder")
196 parser.run(argv)
197
198
199 if __name__ == '__main__':
200 main()
201