Projet

Général

Profil

0005-backoffice-convert-csv-ods-exports-to-afterjob-class.patch

Frédéric Péters, 08 décembre 2020 13:40

Télécharger (10,5 ko)

Voir les différences:

Subject: [PATCH 5/5] backoffice: convert csv/ods exports to afterjob class
 (#48407)

 wcs/backoffice/management.py | 198 +++++++++++++++++++----------------
 1 file changed, 106 insertions(+), 92 deletions(-)
wcs/backoffice/management.py
1992 1992
        r += htmltext('</div>')
1993 1993
        return r.getvalue()
1994 1994

  
1995
    def csv_tuple_heading(self, fields):
1996
        heading_fields = [] # '#id', _('time'), _('userlabel'), _('status')]
1997
        for field in fields:
1998
            heading_fields.extend(field.get_csv_heading())
1999
        return heading_fields
2000

  
2001
    def get_spreadsheet_line(self, fields, data):
2002
        elements = []
2003
        for field in fields:
2004
            element = data.get_field_view_value(field) or ''
2005
            display_value = None
2006
            if field.store_display_value:
2007
                display_value = data.data.get('%s_display' % field.id) or ''
2008
            for value in field.get_csv_value(element, display_value=display_value):
2009
                elements.append({'field': field, 'value': value, 'native_value': element})
2010
        return elements
2011

  
2012 1995
    def csv(self):
2013 1996
        self.check_access()
2014 1997
        fields = self.get_fields_from_query()
......
2018 2001
        criterias = self.get_criterias_from_query()
2019 2002
        order_by = misc.get_order_by_or_400(get_request().form.get('order_by', None))
2020 2003

  
2021
        class Exporter(object):
2022
            def __init__(self, formpage, formdef, fields, selected_filter):
2023
                self.formpage = formpage
2024
                self.formdef = formdef
2025
                self.fields = fields
2026
                self.selected_filter = selected_filter
2027

  
2028
            def export(self, job=None):
2029
                self.output = StringIO()
2030
                csv_output = csv.writer(self.output)
2031

  
2032
                csv_output.writerow(self.formpage.csv_tuple_heading(self.fields))
2033

  
2034
                items, total_count = FormDefUI(self.formdef).get_listing_items(
2035
                        fields, self.selected_filter, user=user, query=query,
2036
                        criterias=criterias, order_by=order_by)
2037

  
2038
                for filled in items:
2039
                    csv_output.writerow(tuple(
2040
                        [x['value'] for x in self.formpage.get_spreadsheet_line(self.fields, filled)]))
2041

  
2042
                if job:
2043
                    job.file_content = self.output.getvalue()
2044
                    job.content_type = 'text/csv'
2045
                    job.store()
2046

  
2047 2004
        get_logger().info('backoffice - form %s - listing csv' % self.formdef.name)
2048 2005

  
2049 2006
        count = self.formdef.data_class().count()
2050
        exporter = Exporter(self, self.formdef, fields, selected_filter)
2007
        job = CsvExportAfterJob(
2008
                self.formdef,
2009
                fields=fields,
2010
                selected_filter=selected_filter,
2011
                user_id=user.id,
2012
                query=query,
2013
                criterias=criterias,
2014
                order_by=order_by)
2051 2015
        if count > self.WCS_SYNC_EXPORT_LIMIT:
2052
            job = get_response().add_after_job(
2053
                str(N_('Exporting forms in CSV')),
2054
                exporter.export)
2055
            job.file_name = '%s.csv' % self.formdef.url_name
2016
            job = get_response().add_after_job(job)
2056 2017
            job.store()
2057 2018
            return redirect('export?job=%s' % job.id)
2058 2019
        else:
2059
            exporter.export()
2020
            job.execute()
2060 2021

  
2061 2022
            response = get_response()
2062 2023
            response.set_content_type('text/plain')
2063 2024
            #response.set_header('content-disposition', 'attachment; filename=%s.csv' % self.formdef.url_name)
2064
            return exporter.output.getvalue()
2025
            return job.file_content
2065 2026

  
2066 2027
    def export(self):
2067 2028
        self.check_access()
......
2120 2081
        criterias = self.get_criterias_from_query()
2121 2082
        order_by = misc.get_order_by_or_400(get_request().form.get('order_by', None))
2122 2083

  
2123
        class Exporter(object):
2124
            def __init__(self, formpage, formdef, fields, selected_filter):
2125
                self.formpage = formpage
2126
                self.formdef = formdef
2127
                self.fields = fields
2128
                self.selected_filter = selected_filter
2129

  
2130
            def export(self, job=None):
2131
                w = ods.Workbook(encoding=get_publisher().site_charset)
2132
                ws = w.add_sheet(self.formdef.name)
2133

  
2134
                for i, f in enumerate(self.formpage.csv_tuple_heading(self.fields)):
2135
                    ws.write(0, i, f)
2136

  
2137
                items, total_count = FormDefUI(self.formdef).get_listing_items(
2138
                        fields, self.selected_filter, user=user, query=query,
2139
                        criterias=criterias, order_by=order_by)
2140

  
2141
                for i, formdata in enumerate(items):
2142
                    for j, item in enumerate(self.formpage.get_spreadsheet_line(fields, formdata)):
2143
                        ws.write(i+1, j, item['value'],
2144
                                formdata=formdata,
2145
                                data_field=item['field'],
2146
                                native_value=item['native_value'])
2147

  
2148
                self.output = BytesIO()
2149
                w.save(self.output)
2150

  
2151
                if job:
2152
                    job.file_content = self.output.getvalue()
2153
                    job.content_type = 'application/vnd.oasis.opendocument.spreadsheet'
2154
                    job.store()
2155

  
2156
        get_logger().info('backoffice - form %s - as ods' % self.formdef.name)
2157

  
2158 2084
        count = self.formdef.data_class().count()
2159
        exporter = Exporter(self, self.formdef, fields, selected_filter)
2085
        job = OdsExportAfterJob(
2086
                self.formdef,
2087
                fields=fields,
2088
                selected_filter=selected_filter,
2089
                user_id=user.id,
2090
                query=query,
2091
                criterias=criterias,
2092
                order_by=order_by)
2160 2093
        if count > self.WCS_SYNC_EXPORT_LIMIT and not get_request().is_api_url():
2161
            job = get_response().add_after_job(
2162
                str(N_('Exporting forms in Open Document format')),
2163
                exporter.export)
2164
            job.file_name = '%s.ods' % self.formdef.url_name
2094
            job = get_response().add_after_job(job)
2165 2095
            job.store()
2166 2096
            return redirect('export?job=%s' % job.id)
2167 2097
        else:
2168
            exporter.export()
2098
            job.execute()
2169 2099

  
2170 2100
            response = get_response()
2171 2101
            response.set_content_type('application/vnd.oasis.opendocument.spreadsheet')
2172 2102
            response.set_header('content-disposition', 'attachment; filename=%s.ods' % self.formdef.url_name)
2173
            return exporter.output.getvalue()
2103
            return job.file_content
2174 2104

  
2175 2105
    def json(self):
2176 2106
        anonymise = 'anonymise' in get_request().form
......
3488 3418
                formdata.perform_global_action(action['action'].id, user)
3489 3419
            self.completion_status = '{}/{}'.format(i + 1, len(formdatas))
3490 3420
            self.store()
3421

  
3422

  
3423
class CsvExportAfterJob(AfterJob):
3424
    label = N_('Exporting forms in CSV')
3425

  
3426
    def __init__(self, formdef, **kwargs):
3427
        super().__init__(
3428
            formdef_class=formdef.__class__,
3429
            formdef_id=formdef.id,
3430
            **kwargs)
3431
        self.file_name = '%s.csv' % formdef.url_name
3432

  
3433
    def csv_tuple_heading(self, fields):
3434
        heading_fields = []  # '#id', _('time'), _('userlabel'), _('status')]
3435
        for field in fields:
3436
            heading_fields.extend(field.get_csv_heading())
3437
        return heading_fields
3438

  
3439
    def get_spreadsheet_line(self, fields, data):
3440
        elements = []
3441
        for field in fields:
3442
            element = data.get_field_view_value(field) or ''
3443
            display_value = None
3444
            if field.store_display_value:
3445
                display_value = data.data.get('%s_display' % field.id) or ''
3446
            for value in field.get_csv_value(element, display_value=display_value):
3447
                elements.append({'field': field, 'value': value, 'native_value': element})
3448
        return elements
3449

  
3450
    def execute(self):
3451
        formdef = self.kwargs['formdef_class'].get(self.kwargs['formdef_id'])
3452
        selected_filter = self.kwargs['selected_filter']
3453
        fields = self.kwargs['fields']
3454
        query = self.kwargs['query']
3455
        criterias = self.kwargs['criterias']
3456
        order_by = self.kwargs['order_by']
3457
        user = get_publisher().user_class.get(self.kwargs['user_id'])
3458

  
3459
        items, total_count = FormDefUI(formdef).get_listing_items(
3460
                fields, selected_filter, user=user, query=query,
3461
                criterias=criterias, order_by=order_by)
3462

  
3463
        return self.create_export(formdef, fields, items, total_count)
3464

  
3465
    def create_export(self, formdef, fields, items, total_count):
3466
        output = StringIO()
3467
        csv_output = csv.writer(output)
3468

  
3469
        csv_output.writerow(self.csv_tuple_heading(fields))
3470

  
3471
        for filled in items:
3472
            csv_output.writerow(tuple(
3473
                [x['value'] for x in self.get_spreadsheet_line(fields, filled)]))
3474

  
3475
        self.file_content = output.getvalue()
3476
        self.content_type = 'text/csv'
3477
        self.store()
3478

  
3479

  
3480
class OdsExportAfterJob(CsvExportAfterJob):
3481
    def __init__(self, formdef, **kwargs):
3482
        super().__init__(formdef=formdef, **kwargs)
3483
        self.file_name = '%s.ods' % formdef.url_name
3484

  
3485
    def create_export(self, formdef, fields, items, total_count):
3486
        workbook = ods.Workbook(encoding='utf-8')
3487
        ws = workbook.add_sheet(formdef.name)
3488

  
3489
        for i, field in enumerate(self.csv_tuple_heading(fields)):
3490
            ws.write(0, i, field)
3491

  
3492
        for i, formdata in enumerate(items):
3493
            for j, item in enumerate(self.get_spreadsheet_line(fields, formdata)):
3494
                ws.write(i + 1, j, item['value'],
3495
                        formdata=formdata,
3496
                        data_field=item['field'],
3497
                        native_value=item['native_value'])
3498

  
3499
        output = BytesIO()
3500
        workbook.save(output)
3501

  
3502
        self.file_content = output.getvalue()
3503
        self.content_type = 'application/vnd.oasis.opendocument.spreadsheet'
3504
        self.store()
3491
-