Projet

Général

Profil

0001-admin-change-export-import-to-use-XML-files-for-form.patch

Frédéric Péters, 17 juillet 2019 14:04

Télécharger (12,3 ko)

Voir les différences:

Subject: [PATCH 1/3] admin: change export/import to use XML files for forms
 and workflows (#34705)

 tests/test_admin_pages.py | 77 +++++++++++++++++++++++++++++++++------
 wcs/admin/settings.py     | 18 ++++++++-
 wcs/formdef.py            | 50 +++++++++++--------------
 wcs/publisher.py          | 22 ++++++++++-
 wcs/workflows.py          |  5 +--
 5 files changed, 124 insertions(+), 48 deletions(-)
tests/test_admin_pages.py
3988 3988
    zip_content = StringIO.StringIO(resp.body)
3989 3989
    zipf = zipfile.ZipFile(zip_content, 'a')
3990 3990
    filelist = zipf.namelist()
3991
    assert 'formdefs/1' in filelist
3992
    assert 'workflows/1' in filelist
3993
    assert 'models/export_to_model-1.upload' in filelist
3991
    assert 'formdefs/1' not in filelist
3992
    assert 'formdefs_xml/1' in filelist
3993
    assert 'workflows/1' not in filelist
3994
    assert 'workflows_xml/1' in filelist
3995
    assert 'models/export_to_model-1.upload' not in filelist
3994 3996
    assert 'roles/1' in filelist
3995 3997
    assert 'categories/1' in filelist
3996 3998
    assert 'datasources/1' in filelist
......
4015 4017
    assert 'Imported successfully' in resp.body
4016 4018
    assert '1 forms' in resp.body
4017 4019

  
4020
    # check roles are found by name
4021
    wipe()
4022
    role = Role(name='qux')
4023
    role.store()
4024

  
4025
    workflow = Workflow(name='Workflow One')
4026
    st1 = workflow.add_status(name='st1')
4027
    commentable = CommentableWorkflowStatusItem()
4028
    commentable.id = '_commentable'
4029
    commentable.by = [role.id]
4030
    commentable.label = 'foobar'
4031
    st1.items.append(commentable)
4032
    commentable.parent = st1
4033
    workflow.store()
4034

  
4035
    formdef = FormDef()
4036
    formdef.name = 'foo'
4037
    formdef.workflow_id = workflow.id
4038
    formdef.roles = [role.id]
4039
    formdef.backoffice_submission_roles = [role.id]
4040
    formdef.workflow_roles = {'_receiver': role.id}
4041
    formdef.store()
4042

  
4043
    resp = app.get('/backoffice/settings/export')
4044
    resp.form['formdefs'] = True
4045
    resp.form['workflows'] = True
4046
    resp.form['roles'] = False
4047
    resp.form['categories'] = False
4048
    resp.form['datasources'] = False
4049
    resp.form['wscalls'] = False
4050
    resp = resp.form.submit('submit')
4051
    assert resp.location.startswith('http://example.net/backoffice/settings/export?job=')
4052
    job_id = urlparse.parse_qs(urlparse.urlparse(resp.location).query)['job'][0]
4053
    resp = resp.follow()
4054
    resp = resp.click('Download Export')
4055
    zip_content = StringIO.StringIO(resp.body)
4056
    zipf = zipfile.ZipFile(zip_content, 'a')
4057
    filelist = zipf.namelist()
4058
    assert 'formdefs_xml/%s' % formdef.id in filelist
4059
    assert 'workflows_xml/%s' % workflow.id in filelist
4060
    assert 'roles/%s' % role.id not in filelist
4061

  
4062
    FormDef.wipe()
4063
    Workflow.wipe()
4064
    Role.wipe()
4065

  
4066
    # create role beforehand, it should be matched by name
4067
    role = Role(name='qux')
4068
    role.id = '012345'
4069
    role.store()
4070

  
4071
    resp = app.get('/backoffice/settings/import')
4072
    resp.form['file'] = Upload('export.wcs', zip_content.getvalue())
4073
    resp = resp.form.submit('submit')
4074
    assert FormDef.select()[0].roles == ['012345']
4075
    assert FormDef.select()[0].backoffice_submission_roles == ['012345']
4076
    assert FormDef.select()[0].workflow_roles == {'_receiver': '012345'}
4077
    assert Workflow.select()[0].possible_status[0].items[0].by == ['012345']
4078

  
4018 4079
    # do not export roles when managed by idp
4019 4080
    pub.cfg['sp'] = {'idp-manage-roles': True}
4020 4081
    pub.write_cfg()
......
4027 4088
    zip_content = StringIO.StringIO(resp.body)
4028 4089
    zipf = zipfile.ZipFile(zip_content, 'a')
4029 4090
    filelist = zipf.namelist()
4030
    assert 'formdefs/1' in filelist
4031
    assert 'workflows/1' in filelist
4032
    assert 'models/export_to_model-1.upload' in filelist
4033
    assert 'roles/1' not in filelist
4034
    assert 'categories/1' in filelist
4035
    assert 'datasources/1' in filelist
4036
    assert 'wscalls/corge' in filelist
4037
    for filename in filelist:
4038
        assert not '.indexes' in filename
4091
    assert len([x for x in filelist if 'roles/' in x]) == 0
4039 4092

  
4040 4093
def test_settings_themes(pub):
4041 4094
    create_superuser(pub)
wcs/admin/settings.py
53 53
import qommon.template
54 54

  
55 55
from formdef import FormDef
56
from workflows import Workflow
56 57
from fields import FieldDefPage, FieldsDirectory
57 58
from wcs.roles import Role
58 59

  
......
876 877
                c = StringIO()
877 878
                z = zipfile.ZipFile(c, 'w')
878 879
                for d in self.dirs:
880
                    if d not in ('roles', 'categories', 'datasources', 'wscalls'):
881
                        continue
879 882
                    path = os.path.join(self.app_dir, d)
880 883
                    if not os.path.exists(path):
881 884
                        continue
......
883 886
                        if f == '.indexes':
884 887
                            continue
885 888
                        z.write(os.path.join(path, f), os.path.join(d, f))
889
                if 'formdefs' in self.dirs:
890
                    for formdef in FormDef.select():
891
                        node = formdef.export_to_xml(include_id=True)
892
                        misc.indent_xml(node)
893
                        z.writestr(os.path.join('formdefs_xml', str(formdef.id)),
894
                                '<?xml version="1.0" encoding="iso-8859-15"?>\n' + ET.tostring(node))
895
                if 'workflows' in self.dirs:
896
                    for workflow in Workflow.select():
897
                        node = workflow.export_to_xml(include_id=True)
898
                        misc.indent_xml(node)
899
                        z.writestr(os.path.join('workflows_xml', str(workflow.id)),
900
                                '<?xml version="1.0" encoding="iso-8859-15"?>\n' + ET.tostring(node))
901

  
886 902
                if self.settings:
887 903
                    z.write(os.path.join(self.app_dir, 'config.pck'), 'config.pck')
888 904
                    for f in os.listdir(self.app_dir):
......
901 917
                'datasources', 'wscalls'):
902 918
            if form.get_widget(w) and form.get_widget(w).parse():
903 919
                dirs.append(w)
904
        if 'workflows' in dirs:
905
            dirs.append('models')
906 920
        if not dirs and not form.get_widget('settings').parse():
907 921
            return redirect('.')
908 922

  
wcs/formdef.py
1092 1092
                        formdef.workflow_id = w.id
1093 1093
                        break
1094 1094

  
1095
        def get_role_by_node(role_node):
1096
            role_id = None
1097
            value = role_node.text.encode(charset)
1098
            if value.startswith('_') or value == 'logged-users':
1099
                role_id = value
1100
            elif include_id:
1101
                role_id = role_node.attrib.get('role_id')
1102
                if role_id and not Role.has_key(role_id):
1103
                    role_id = None
1104

  
1105
            if not role_id:
1106
                for role in Role.select(ignore_errors=True):
1107
                    if role.name == value:
1108
                        role_id = role.id
1109
                        break
1110

  
1111
            return role_id
1112

  
1113

  
1095 1114
        roles_elements = [
1096 1115
            ('roles', 'user-roles'),
1097 1116
            ('backoffice_submission_roles', 'backoffice-submission-roles')
......
1103 1122
            roles = []
1104 1123
            setattr(formdef, attr_name, roles)
1105 1124
            for child in roles_node:
1106
                role_id = None
1107
                value = child.text.encode(charset)
1108
                if value.startswith('_') or value == 'logged-users':
1109
                    role_id = value
1110
                elif include_id:
1111
                    role_id = child.attrib.get('role_id')
1112
                    if role_id and not Role.has_key(role_id):
1113
                        role_id = None
1114

  
1115
                if not role_id:
1116
                    for role in Role.select(ignore_errors=True):
1117
                        if role.name == value:
1118
                            role_id = role.id
1119
                            break
1125
                role_id = get_role_by_node(child)
1120 1126
                if role_id:
1121 1127
                    roles.append(role_id)
1122 1128

  
......
1125 1131
            formdef.workflow_roles = {}
1126 1132
            for child in roles_node:
1127 1133
                role_key = child.attrib['role_key']
1128
                role_id = None
1129
                value = child.text.encode(charset)
1130
                if value.startswith('_') or value == 'logged-users':
1131
                    role_id = value
1132
                elif include_id:
1133
                    role_id = child.attrib.get('role_id')
1134
                else:
1135
                    for role in Role.select(ignore_errors=True):
1136
                        if role.name == value:
1137
                            role_id = role.id
1138
                            break
1139

  
1140
                if role_id and not Role.has_key(role_id):
1141
                    role_id = None
1142

  
1134
                role_id = get_role_by_node(child)
1143 1135
                formdef.workflow_roles[role_key] = role_id
1144 1136

  
1145 1137
        if tree.find('geolocations') is not None:
wcs/publisher.py
195 195
        for f in z.namelist():
196 196
            if '.indexes' in f:
197 197
                continue
198
            if os.path.dirname(f) in ('formdefs_xml', 'workflows_xml'):
199
                continue
198 200
            path = os.path.join(self.app_dir, f)
199 201
            if not os.path.exists(os.path.dirname(path)):
200 202
                os.mkdir(os.path.dirname(path))
......
223 225
            if results.has_key(os.path.split(f)[0]):
224 226
                results[os.path.split(f)[0]] += 1
225 227

  
228
        # second pass, workflows
229
        from wcs.workflows import Workflow
230
        for f in z.namelist():
231
            if os.path.dirname(f) == 'workflows_xml' and os.path.basename(f):
232
                workflow = Workflow.import_from_xml(z.open(f), include_id=True)
233
                workflow.store()
234
                results['workflows'] += 1
235

  
236
        # third pass, forms
237
        from wcs.formdef import FormDef
238
        formdefs = []
239
        for f in z.namelist():
240
            if os.path.dirname(f) == 'formdefs_xml' and os.path.basename(f):
241
                formdef = FormDef.import_from_xml(z.open(f), include_id=True)
242
                formdef.store()
243
                formdefs.append(formdef)
244
                results['formdefs'] += 1
245

  
226 246
        # rebuild indexes for imported objects
227 247
        for k, v in results.items():
228 248
            if k == 'settings':
......
248 268
            if k == 'formdefs':
249 269
                # in case of formdefs, we store them anew in case SQL changes
250 270
                # are required.
251
                for formdef in FormDef.select():
271
                for formdef in (formdefs or FormDef.select()):
252 272
                    formdef.store()
253 273

  
254 274
        z.close()
wcs/workflows.py
907 907
            return value
908 908

  
909 909
        # if we import using id, only look at the role_id attribute
910
        if include_id:
911
            if not 'role_id' in elem.attrib:
912
                return None
910
        if include_id and 'role_id' in elem.attrib:
913 911
            role_id = elem.attrib['role_id'].encode(charset)
914 912
            if Role.has_key(role_id):
915 913
                return role_id
916 914
            if WorkflowStatusItem.get_expression(role_id)['type'] in ('python', 'template'):
917 915
                return role_id
918
            return None
919 916

  
920 917
        # if not using id, look up on the name
921 918
        for role in Role.select(ignore_errors=True):
922
-