|
1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 """csv export views""" |
|
19 |
|
20 __docformat__ = "restructuredtext en" |
|
21 from cubicweb import _ |
|
22 |
|
23 from six import PY2 |
|
24 from six.moves import range |
|
25 |
|
26 from cubicweb.schema import display_name |
|
27 from cubicweb.predicates import any_rset, empty_rset |
|
28 from cubicweb.uilib import UnicodeCSVWriter |
|
29 from cubicweb.view import EntityView, AnyRsetView |
|
30 |
|
31 class CSVMixIn(object): |
|
32 """mixin class for CSV views""" |
|
33 templatable = False |
|
34 content_type = "text/comma-separated-values" |
|
35 binary = PY2 # python csv module is unicode aware in py3k |
|
36 csv_params = {'dialect': 'excel', |
|
37 'quotechar': '"', |
|
38 'delimiter': ';', |
|
39 'lineterminator': '\n'} |
|
40 |
|
41 def set_request_content_type(self): |
|
42 """overriden to set a .csv filename""" |
|
43 self._cw.set_content_type(self.content_type, filename='cubicwebexport.csv') |
|
44 |
|
45 def csvwriter(self, **kwargs): |
|
46 params = self.csv_params.copy() |
|
47 params.update(kwargs) |
|
48 return UnicodeCSVWriter(self.w, self._cw.encoding, **params) |
|
49 |
|
50 |
|
51 class CSVRsetView(CSVMixIn, AnyRsetView): |
|
52 """dumps raw result set in CSV""" |
|
53 __regid__ = 'csvexport' |
|
54 __select__ = any_rset() |
|
55 title = _('csv export') |
|
56 |
|
57 def call(self): |
|
58 writer = self.csvwriter() |
|
59 writer.writerow(self.columns_labels()) |
|
60 rset, descr = self.cw_rset, self.cw_rset.description |
|
61 eschema = self._cw.vreg.schema.eschema |
|
62 for rowindex, row in enumerate(rset): |
|
63 csvrow = [] |
|
64 for colindex, val in enumerate(row): |
|
65 etype = descr[rowindex][colindex] |
|
66 if val is not None and not eschema(etype).final: |
|
67 # csvrow.append(val) # val is eid in that case |
|
68 content = self._cw.view('textincontext', rset, |
|
69 row=rowindex, col=colindex) |
|
70 else: |
|
71 content = self._cw.view('final', rset, |
|
72 format='text/plain', |
|
73 row=rowindex, col=colindex) |
|
74 csvrow.append(content) |
|
75 writer.writerow(csvrow) |
|
76 |
|
77 |
|
78 class CSVEntityView(CSVMixIn, EntityView): |
|
79 """dumps rset's entities (with full set of attributes) in CSV |
|
80 |
|
81 the generated CSV file will have a table per entity type found in the |
|
82 resultset. ('table' here only means empty lines separation between table |
|
83 contents) |
|
84 """ |
|
85 __regid__ = 'ecsvexport' |
|
86 __select__ = EntityView.__select__ | empty_rset() |
|
87 title = _('csv export (entities)') |
|
88 |
|
89 def call(self): |
|
90 req = self._cw |
|
91 rows_by_type = {} |
|
92 writer = self.csvwriter() |
|
93 rowdef_by_type = {} |
|
94 for index in range(len(self.cw_rset)): |
|
95 entity = self.cw_rset.complete_entity(index) |
|
96 if entity.e_schema not in rows_by_type: |
|
97 rowdef_by_type[entity.e_schema] = [rs for rs, at in entity.e_schema.attribute_definitions() |
|
98 if at != 'Bytes'] |
|
99 rows_by_type[entity.e_schema] = [[display_name(req, rschema.type) |
|
100 for rschema in rowdef_by_type[entity.e_schema]]] |
|
101 rows = rows_by_type[entity.e_schema] |
|
102 rows.append([entity.printable_value(rs.type, format='text/plain') |
|
103 for rs in rowdef_by_type[entity.e_schema]]) |
|
104 for rows in rows_by_type.values(): |
|
105 writer.writerows(rows) |
|
106 # use two empty lines as separator |
|
107 writer.writerows([[], []]) |