Projet

Général

Profil

0001-backoffice-add-button-to-download-all-files-in-a-zip.patch

Frédéric Péters, 30 juin 2020 11:55

Télécharger (5,58 ko)

Voir les différences:

Subject: [PATCH] backoffice: add button to download all files in a zip
 (#44395)

 tests/test_backoffice_pages.py | 30 ++++++++++++++++++++++
 wcs/backoffice/management.py   | 47 ++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)
tests/test_backoffice_pages.py
1913 1913
    assert 'by %s' % user.get_display_name() in resp.text
1914 1914

  
1915 1915

  
1916
def test_backoffice_download_as_zip(pub):
1917
    create_user(pub)
1918
    create_environment(pub)
1919
    formdef = FormDef.get_by_urlname('form-title')
1920
    formdef.fields.append(fields.FileField(id='4', label='file1 field', type='file'))
1921
    formdef.fields.append(fields.FileField(id='5', label='file2 field', type='file2'))
1922
    formdef.store()
1923
    number31 = [x for x in formdef.data_class().select() if x.data['1'] == 'FOO BAR 30'][0]
1924
    number31.data['4'] = PicklableUpload('/foo/bar', content_type='text/plain')
1925
    number31.data['4'].receive([b'hello world'])
1926
    number31.data['5'] = PicklableUpload('/foo/bar', content_type='text/plain')
1927
    number31.data['5'].receive([b'hello world2'])
1928
    number31.store()
1929
    app = login(get_app(pub))
1930
    resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
1931
    resp = resp.click('Download all files as .zip')
1932
    zip_content = BytesIO(resp.body)
1933
    zipf = zipfile.ZipFile(zip_content, 'a')
1934
    filelist = zipf.namelist()
1935
    assert set(filelist) == {'1_bar', '2_bar'}
1936
    for zipinfo in zipf.infolist():
1937
        content = zipf.read(zipinfo)
1938
        if zipinfo.filename == '1_bar':
1939
            assert content == b'hello world'
1940
        elif zipinfo.filename == '2_bar':
1941
            assert content == b'hello world2'
1942
        else:
1943
            assert False  # unknown zip part
1944

  
1945

  
1916 1946
def test_backoffice_sidebar_user_template(pub):
1917 1947
    user = create_user(pub)
1918 1948
    create_environment(pub)
wcs/backoffice/management.py
21 21
import time
22 22
import types
23 23
import vobject
24
import zipfile
24 25

  
25 26
try:
26 27
    import xlwt
......
51 52
from ..qommon import errors
52 53
from ..qommon import ods
53 54
from ..qommon.form import *
55
from ..qommon.form import PicklableUpload
54 56
from ..qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or,
55 57
        Intersects, ILike, FtsMatch, Contains, Null, NotNull)
56 58
from ..qommon.template import Template
......
2515 2517
class FormBackOfficeStatusPage(FormStatusPage):
2516 2518
    _q_exports_orig = ['', 'download', 'json', 'action', 'live',
2517 2519
            'inspect', ('inspect-tool', 'inspect_tool'),
2520
            ('download-as-zip', 'download_as_zip'),
2518 2521
            ('user-pending-forms', 'user_pending_forms')]
2519 2522
    form_page_class = FormFillPage
2520 2523

  
......
2641 2644
                        'date': formdata.anonymised.strftime(misc.date_format())}
2642 2645
                r += htmltext('</div>')
2643 2646

  
2647
            has_attached_files = False
2648
            for value in formdata.data.values():
2649
                if isinstance(value, PicklableUpload):
2650
                    has_attached_files = True
2651
                if isinstance(value, dict) and isinstance(value.get('data'), list):
2652
                    for subvalue in value.get('data'):
2653
                        for subvalue_elem in subvalue.values():
2654
                            if isinstance(subvalue_elem, PicklableUpload):
2655
                                has_attached_files = True
2656
                                break
2657
                if has_attached_files:
2658
                    break
2659

  
2660
            if has_attached_files:
2661
                r += htmltext('<p><a class="button" href="download-as-zip">%s</a></p>') % _('Download all files as .zip')
2662

  
2644 2663
            r += htmltext('</div>')
2645 2664

  
2646 2665
        if formdata.submission_context or formdata.submission_channel:
......
2717 2736

  
2718 2737
        return r.getvalue()
2719 2738

  
2739
    def download_as_zip(self):
2740
        formdata = self.filled
2741
        zip_content = BytesIO()
2742
        zip_file = zipfile.ZipFile(zip_content, 'w')
2743
        counter = {'value': 0}
2744

  
2745
        def add_zip_file(upload):
2746
            counter['value'] += 1
2747
            filename = '%s_%s' % (counter['value'], upload.base_filename)
2748
            zip_file.writestr(filename, upload.get_content())
2749

  
2750
        for value in formdata.data.values():
2751
            if isinstance(value, PicklableUpload):
2752
                add_zip_file(value)
2753
            if isinstance(value, dict) and isinstance(value.get('data'), list):
2754
                for subvalue in value.get('data'):
2755
                    for subvalue_elem in subvalue.values():
2756
                        if isinstance(subvalue_elem, PicklableUpload):
2757
                            add_zip_file(subvalue_elem)
2758

  
2759
        zip_file.close()
2760

  
2761
        response = get_response()
2762
        response.set_content_type('application/zip')
2763
        response.set_header('content-disposition',
2764
                'attachment; filename=files-%s.zip' % formdata.get_display_id())
2765
        return zip_content.getvalue()
2766

  
2720 2767
    def get_user_pending_forms(self):
2721 2768
        from wcs import sql
2722 2769
        formdata = self.filled
2723
-