Projet

Général

Profil

0001-settings-make-site-export-async-34915.patch

Frédéric Péters, 16 juillet 2019 20:43

Télécharger (8,29 ko)

Voir les différences:

Subject: [PATCH] settings: make site export async (#34915)

 tests/test_admin_pages.py |  18 +++++++
 wcs/admin/settings.py     | 101 ++++++++++++++++++++++++++++----------
 2 files changed, 92 insertions(+), 27 deletions(-)
tests/test_admin_pages.py
9 9
import shutil
10 10
import StringIO
11 11
import tarfile
12
import urlparse
12 13
import time
13 14
import xml.etree.ElementTree as ET
14 15
import zipfile
......
3939 3940
    resp = resp.form.submit('cancel')
3940 3941
    resp = app.get('/backoffice/settings/export')
3941 3942
    resp = resp.form.submit('submit')
3943
    assert resp.location.startswith('http://example.net/backoffice/settings/export?job=')
3944
    job_id = urlparse.parse_qs(urlparse.urlparse(resp.location).query)['job'][0]
3945
    resp = resp.follow()
3946
    assert 'completed' in resp.body
3947
    resp = resp.click('Download Export')
3942 3948
    zip_content = StringIO.StringIO(resp.body)
3943 3949
    zipf = zipfile.ZipFile(zip_content, 'a')
3944 3950
    filelist = zipf.namelist()
3945 3951
    assert len(filelist) == 0
3946 3952

  
3953
    # check afterjob ajax call
3954
    status_resp = app.get('/afterjobs/' + job_id)
3955
    assert status_resp.body == 'completed|completed'
3956

  
3947 3957
    formdef = FormDef()
3948 3958
    formdef.name = 'foo'
3949 3959
    formdef.store()
......
3968 3978

  
3969 3979
    resp = app.get('/backoffice/settings/export')
3970 3980
    resp = resp.form.submit('submit')
3981
    assert resp.location.startswith('http://example.net/backoffice/settings/export?job=')
3982
    job_id = urlparse.parse_qs(urlparse.urlparse(resp.location).query)['job'][0]
3983
    resp = resp.follow()
3984
    resp = resp.click('Download Export')
3971 3985
    zip_content = StringIO.StringIO(resp.body)
3972 3986
    zipf = zipfile.ZipFile(zip_content, 'a')
3973 3987
    filelist = zipf.namelist()
......
4003 4017
    pub.write_cfg()
4004 4018
    resp = app.get('/backoffice/settings/export')
4005 4019
    resp = resp.form.submit('submit')
4020
    assert resp.location.startswith('http://example.net/backoffice/settings/export?job=')
4021
    job_id = urlparse.parse_qs(urlparse.urlparse(resp.location).query)['job'][0]
4022
    resp = resp.follow()
4023
    resp = resp.click('Download Export')
4006 4024
    zip_content = StringIO.StringIO(resp.body)
4007 4025
    zipf = zipfile.ZipFile(zip_content, 'a')
4008 4026
    filelist = zipf.namelist()
wcs/admin/settings.py
41 41
from qommon.form import *
42 42
from qommon.sms import SMS
43 43

  
44
from qommon.afterjobs import AfterJob
44 45
from qommon.backoffice.menu import html_top
45 46
from qommon.admin.menu import error_page
46 47
from qommon.admin.cfg import cfg_submit
......
840 841
            return redirect('.')
841 842

  
842 843
    def export(self):
844
        if get_request().form.get('job') or get_request().form.get('download'):
845
            return self.export_pending()
846

  
843 847
        form = Form(enctype="multipart/form-data")
844 848
        form.add(CheckboxWidget, 'formdefs', title = _('Forms'), value = True)
845 849
        form.add(CheckboxWidget, 'workflows', title = _('Workflows'), value = True)
......
861 865
            r += htmltext('<h2>%s</h2>') % _('Export')
862 866
            r += form.render()
863 867
            return r.getvalue()
864
        else:
865
            return self.export_submit(form)
866 868

  
867
    def export_submit(self, form):
869
        class Exporter(object):
870
            def __init__(self, dirs, settings):
871
                self.app_dir = get_publisher().app_dir
872
                self.dirs = dirs
873
                self.settings = settings
874

  
875
            def export(self, job):
876
                c = StringIO()
877
                z = zipfile.ZipFile(c, 'w')
878
                for d in self.dirs:
879
                    path = os.path.join(self.app_dir, d)
880
                    if not os.path.exists(path):
881
                        continue
882
                    for f in os.listdir(path):
883
                        if f == '.indexes':
884
                            continue
885
                        z.write(os.path.join(path, f), os.path.join(d, f))
886
                if self.settings:
887
                    z.write(os.path.join(self.app_dir, 'config.pck'), 'config.pck')
888
                    for f in os.listdir(self.app_dir):
889
                        if f.startswith('idp-') and os.path.splitext(f)[-1] in ('.pem', '.xml'):
890
                            z.write(os.path.join(self.app_dir, f), f)
891
                    if os.path.exists(os.path.join(self.app_dir, 'config')):
892
                        for f in os.listdir(os.path.join(self.app_dir, 'config')):
893
                            z.write(os.path.join(self.app_dir, 'config', f), os.path.join('config', f))
894
                z.close()
895

  
896
                job.file_content = c.getvalue()
897
                job.store()
898

  
868 899
        dirs = []
869 900
        for w in ('formdefs', 'workflows', 'roles', 'categories',
870 901
                'datasources', 'wscalls'):
......
875 906
        if not dirs and not form.get_widget('settings').parse():
876 907
            return redirect('.')
877 908

  
878
        c = StringIO()
879
        z = zipfile.ZipFile(c, 'w')
880
        app_dir = get_publisher().app_dir
881
        for d in dirs:
882
            path = os.path.join(app_dir, d)
883
            if not os.path.exists(path):
884
                continue
885
            for f in os.listdir(path):
886
                if f == '.indexes':
887
                    continue
888
                z.write(os.path.join(path, f), os.path.join(d, f))
889
        if form.get_widget('settings').parse():
890
            z.write(os.path.join(app_dir, 'config.pck'), 'config.pck')
891
            for f in os.listdir(app_dir):
892
                if f.startswith('idp-') and os.path.splitext(f)[-1] in ('.pem', '.xml'):
893
                    z.write(os.path.join(app_dir, f), f)
894
            if os.path.exists(os.path.join(app_dir, 'config')):
895
                for f in os.listdir(os.path.join(app_dir, 'config')):
896
                    z.write(os.path.join(app_dir, 'config', f), os.path.join('config', f))
909
        exporter = Exporter(dirs, settings=form.get_widget('settings').parse())
897 910

  
898
        z.close()
911
        job = get_response().add_after_job(
912
                N_('Exporting site settings'),
913
                exporter.export)
914
        job.store()
915
        return redirect('export?job=%s' % job.id)
899 916

  
900
        response = get_response()
901
        response.set_content_type('application/x-wcs')
902
        response.set_header('content-disposition', 'attachment; filename=export.wcs')
903
        return c.getvalue()
917
    def export_pending(self):
918
        job_id = get_request().form.get('job') or get_request().form.get('download')
919
        try:
920
            job = AfterJob.get(job_id)
921
        except KeyError:
922
            return redirect('.')
923

  
924
        if get_request().form.get('download'):
925
            response = get_response()
926
            response.set_content_type('application/x-wcs')
927
            response.set_header('content-disposition', 'attachment; filename=export.wcs')
928
            return job.file_content
929

  
930
        html_top('settings', title=_('Exporting'))
931
        r = TemplateIO(html=True)
932
        get_response().add_javascript(['jquery.js', 'afterjob.js'])
933
        r += htmltext('<h2>%s</h2>') % _('Export')
934
        r += htmltext('<div class="section"><dl class="job-status">')
935
        r += htmltext('<dt>')
936
        r += _(job.label)
937
        r += htmltext('</dt>')
938
        r += htmltext('<dd>')
939
        r += htmltext('<span class="afterjob" id="%s">') % job.id
940
        r += _(job.status)
941
        r += htmltext('</span>')
942
        r += htmltext('</dd>')
943
        r += htmltext('</dl>')
944

  
945
        r += htmltext('<div class="done">')
946
        r += htmltext('<a download="export.wcs" href="export?download=%s">%s</a>') % (
947
                job.id, _('Download Export'))
948
        r += htmltext('</div>')
949
        r += htmltext('</div>')
950
        return r.getvalue()
904 951

  
905 952
    def p_import(self):
906 953
        form = Form(enctype='multipart/form-data')
907
-