web/views/csvexport.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 19 Feb 2010 09:34:14 +0100
branchstable
changeset 4643 921737d2e3a8
parent 4252 6c4f109c2b03
child 5421 8167de96c523
permissions -rw-r--r--
fix optimisation with super session that may lead to integrity loss at some point I've decided to stop ensuring ?1 cardinality was respected when adding a new relation using a super session, to avoid the cost of the delete query. That was yet discussable because it introduced unexpected difference between execute and unsafe_execute, which is imo not worth it. Also, now that rql() in migration script default to unsafe_execute, we definitly don't want that implicit behaviour change (which already cause bug when for instance adding another default workflow for an entity type: without that fix we end up with *two* default workflows while the schema tells we can have only one. IMO we should go to the direction that super session skip all security check, but nothing else, unless explicitly asked.
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