1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """classes that hold units of comma-separated values (.csv) files (csvunit)
23 or entire files (csvfile) for use with localisation
24 """
25
26 import csv
27
28 from translate.misc import sparse
29 from translate.storage import base
30
32 - def __init__(self, fileobj, fieldnames):
33 self.fieldnames = fieldnames
34 self.contents = fileobj.read()
35 self.parser = sparse.SimpleParser(defaulttokenlist=[",", "\n"], whitespacechars="\r")
36 self.parser.stringescaping = 0
37 self.parser.quotechars = '"'
38 self.tokens = self.parser.tokenize(self.contents)
39 self.tokenpos = 0
40
43
50
52 lentokens = len(self.tokens)
53 while self.tokenpos < lentokens and self.tokens[self.tokenpos] == "\n":
54 self.tokenpos += 1
55 if self.tokenpos >= lentokens:
56 raise StopIteration()
57 thistokens = []
58 while self.tokenpos < lentokens and self.tokens[self.tokenpos] != "\n":
59 thistokens.append(self.tokens[self.tokenpos])
60 self.tokenpos += 1
61 while self.tokenpos < lentokens and self.tokens[self.tokenpos] == "\n":
62 self.tokenpos += 1
63 fields = []
64
65 currentfield = ''
66 fieldparts = 0
67 for token in thistokens:
68 if token == ',':
69
70 if fieldparts == 1:
71 currentfield = self.getvalue(currentfield)
72 fields.append(currentfield)
73 currentfield = ''
74 fieldparts = 0
75 else:
76 currentfield += token
77 fieldparts += 1
78
79 if fieldparts:
80 if fieldparts == 1:
81 currentfield = self.getvalue(currentfield)
82 fields.append(currentfield)
83 values = {}
84 for fieldnum in range(len(self.fieldnames)):
85 if fieldnum >= len(fields):
86 values[self.fieldnames[fieldnum]] = ""
87 else:
88 values[self.fieldnames[fieldnum]] = fields[fieldnum]
89 return values
90
91 -class csvunit(base.TranslationUnit):
92 spreadsheetescapes = [("+", "\\+"), ("-", "\\-"), ("=", "\\="), ("'", "\\'")]
98
107
116
128
129 - def todict(self, encoding='utf-8'):
130 comment, source, target = self.comment, self.source, self.target
131 source, target = self.add_spreadsheet_escapes(source, target)
132 if isinstance(comment, unicode):
133 comment = comment.encode(encoding)
134 if isinstance(source, unicode):
135 source = source.encode(encoding)
136 if isinstance(target, unicode):
137 target = target.encode(encoding)
138 return {'location':comment, 'source': source, 'target': target}
139
140 -class csvfile(base.TranslationStore):
141 """This class represents a .csv file with various lines.
142 The default format contains three columns: location, source, target"""
143 UnitClass = csvunit
144 Name = _("Comma Separated Value")
145 Mimetypes = ['text/comma-separated-values', 'text/csv']
146 Extensions = ["csv"]
147 - def __init__(self, inputfile=None, fieldnames=None):
148 base.TranslationStore.__init__(self, unitclass = self.UnitClass)
149 self.units = []
150 if fieldnames is None:
151 self.fieldnames = ['location', 'source', 'target']
152 else:
153 if isinstance(fieldnames, basestring):
154 fieldnames = [fieldname.strip() for fieldname in fieldnames.split(",")]
155 self.fieldnames = fieldnames
156 self.filename = getattr(inputfile, 'name', '')
157 if inputfile is not None:
158 csvsrc = inputfile.read()
159 inputfile.close()
160 self.parse(csvsrc)
161
162 - def parse(self, csvsrc):
169
176
185