web/views/csvexport.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 24 Feb 2010 15:00:37 +0100
branchstable
changeset 4694 c19366a12281
parent 4252 6c4f109c2b03
child 5421 8167de96c523
permissions -rw-r--r--
simplejson may not be available with python 2.4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
     1
"""csv export views
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
     2
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
:organization: Logilab
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
     4
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
     7
"""
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
     9
2303
ea86d250cca9 import display_name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    10
from cubicweb.schema import display_name
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
    11
from cubicweb.uilib import UnicodeCSVWriter
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    12
from cubicweb.view import EntityView, AnyRsetView
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    13
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    14
class CSVMixIn(object):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    15
    """mixin class for CSV views"""
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    16
    templatable = False
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    17
    content_type = "text/comma-separated-values"
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    18
    binary = True # avoid unicode assertion
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    19
    csv_params = {'dialect': 'excel',
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    20
                  'quotechar': '"',
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    21
                  'delimiter': ';',
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    22
                  'lineterminator': '\n'}
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    23
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    24
    def set_request_content_type(self):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    25
        """overriden to set a .csv filename"""
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    26
        self._cw.set_content_type(self.content_type, filename='cubicwebexport.csv')
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    27
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    28
    def csvwriter(self, **kwargs):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    29
        params = self.csv_params.copy()
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    30
        params.update(kwargs)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    31
        return UnicodeCSVWriter(self.w, self._cw.encoding, **params)
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    32
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    33
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    34
class CSVRsetView(CSVMixIn, AnyRsetView):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    35
    """dumps raw result set in CSV"""
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3165
diff changeset
    36
    __regid__ = 'csvexport'
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    37
    title = _('csv export')
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    38
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    39
    def call(self):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    40
        writer = self.csvwriter()
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    41
        writer.writerow(self.columns_labels())
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    42
        rset, descr = self.cw_rset, self.cw_rset.description
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4023
diff changeset
    43
        eschema = self._cw.vreg.schema.eschema
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    44
        for rowindex, row in enumerate(rset):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    45
            csvrow = []
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    46
            for colindex, val in enumerate(row):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    47
                etype = descr[rowindex][colindex]
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3165
diff changeset
    48
                if val is not None and not eschema(etype).final:
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    49
                    # csvrow.append(val) # val is eid in that case
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    50
                    content = self._cw.view('textincontext', rset,
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    51
                                            row=rowindex, col=colindex)
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    52
                else:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    53
                    content = self._cw.view('final', rset,
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    54
                                            format='text/plain',
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    55
                                            row=rowindex, col=colindex)
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    56
                csvrow.append(content)
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    57
            writer.writerow(csvrow)
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    58
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    59
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    60
class CSVEntityView(CSVMixIn, EntityView):
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    61
    """dumps rset's entities (with full set of attributes) in CSV
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    62
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    63
    the generated CSV file will have a table per entity type found in the
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    64
    resultset. ('table' here only means empty lines separation between table
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    65
    contents)
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    66
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3165
diff changeset
    67
    __regid__ = 'ecsvexport'
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    68
    title = _('csv entities export')
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    69
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    70
    def call(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    71
        req = self._cw
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    72
        rows_by_type = {}
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    73
        writer = self.csvwriter()
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    74
        rowdef_by_type = {}
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    75
        for index in xrange(len(self.cw_rset)):
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    76
            entity = self.cw_rset.complete_entity(index)
824
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    77
            if entity.e_schema not in rows_by_type:
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    78
                rowdef_by_type[entity.e_schema] = [rs for rs, at in entity.e_schema.attribute_definitions()
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    79
                                                   if at != 'Bytes']
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
                rows_by_type[entity.e_schema] = [[display_name(req, rschema.type)
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    81
                                                  for rschema in rowdef_by_type[entity.e_schema]]]
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    82
            rows = rows_by_type[entity.e_schema]
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    83
            rows.append([entity.printable_value(rs.type, format='text/plain')
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    84
                         for rs in rowdef_by_type[entity.e_schema]])
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    85
        for rows in rows_by_type.itervalues():
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    86
            writer.writerows(rows)
a5e6acffde30 merge, split baseviews (new csvexport, xmlrss and editviews modules)
sylvain.thenault@logilab.fr
parents:
diff changeset
    87
            # use two empty lines as separator
1477
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    88
            writer.writerows([[], []])
b056a49c16dc backport default branch
sylvain.thenault@logilab.fr
parents: 824
diff changeset
    89