From 8aeb8f5efa26f3d3af6f399b5f2825a99199b5d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Wed, 17 Jul 2019 07:02:14 +0200
Subject: [PATCH 2/2] admin: change export/import to use XML files for forms
 and workflows (#34705)

---
 tests/test_admin_pages.py | 16 ++++++++++------
 wcs/admin/settings.py     | 18 ++++++++++++++++--
 wcs/publisher.py          | 22 +++++++++++++++++++++-
 3 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py
index 645273ba1..2bbfb3f2d 100644
--- a/tests/test_admin_pages.py
+++ b/tests/test_admin_pages.py
@@ -3988,9 +3988,11 @@ def test_settings_export_import(pub):
     zip_content = StringIO.StringIO(resp.body)
     zipf = zipfile.ZipFile(zip_content, 'a')
     filelist = zipf.namelist()
-    assert 'formdefs/1' in filelist
-    assert 'workflows/1' in filelist
-    assert 'models/export_to_model-1.upload' in filelist
+    assert 'formdefs/1' not in filelist
+    assert 'formdefs_xml/1' in filelist
+    assert 'workflows/1' not in filelist
+    assert 'workflows_xml/1' in filelist
+    assert 'models/export_to_model-1.upload' not in filelist
     assert 'roles/1' in filelist
     assert 'categories/1' in filelist
     assert 'datasources/1' in filelist
@@ -4027,9 +4029,11 @@ def test_settings_export_import(pub):
     zip_content = StringIO.StringIO(resp.body)
     zipf = zipfile.ZipFile(zip_content, 'a')
     filelist = zipf.namelist()
-    assert 'formdefs/1' in filelist
-    assert 'workflows/1' in filelist
-    assert 'models/export_to_model-1.upload' in filelist
+    assert 'formdefs/1' not in filelist
+    assert 'formdefs_xml/1' in filelist
+    assert 'workflows/1' not in filelist
+    assert 'workflows_xml/1' in filelist
+    assert 'models/export_to_model-1.upload' not in filelist
     assert 'roles/1' not in filelist
     assert 'categories/1' in filelist
     assert 'datasources/1' in filelist
diff --git a/wcs/admin/settings.py b/wcs/admin/settings.py
index 8861c2c04..70eee5d50 100644
--- a/wcs/admin/settings.py
+++ b/wcs/admin/settings.py
@@ -53,6 +53,7 @@ import qommon.ident
 import qommon.template
 
 from formdef import FormDef
+from workflows import Workflow
 from fields import FieldDefPage, FieldsDirectory
 from wcs.roles import Role
 
@@ -876,6 +877,8 @@ class SettingsDirectory(QommonSettingsDirectory):
                 c = StringIO()
                 z = zipfile.ZipFile(c, 'w')
                 for d in self.dirs:
+                    if d not in ('roles', 'categories', 'datasources', 'wscalls'):
+                        continue
                     path = os.path.join(self.app_dir, d)
                     if not os.path.exists(path):
                         continue
@@ -883,6 +886,19 @@ class SettingsDirectory(QommonSettingsDirectory):
                         if f == '.indexes':
                             continue
                         z.write(os.path.join(path, f), os.path.join(d, f))
+                if 'formdefs' in self.dirs:
+                    for formdef in FormDef.select():
+                        node = formdef.export_to_xml(include_id=True)
+                        misc.indent_xml(node)
+                        z.writestr(os.path.join('formdefs_xml', str(formdef.id)),
+                                '<?xml version="1.0" encoding="iso-8859-15"?>\n' + ET.tostring(node))
+                if 'workflows' in self.dirs:
+                    for workflow in Workflow.select():
+                        node = workflow.export_to_xml(include_id=True)
+                        misc.indent_xml(node)
+                        z.writestr(os.path.join('workflows_xml', str(workflow.id)),
+                                '<?xml version="1.0" encoding="iso-8859-15"?>\n' + ET.tostring(node))
+
                 if self.settings:
                     z.write(os.path.join(self.app_dir, 'config.pck'), 'config.pck')
                     for f in os.listdir(self.app_dir):
@@ -901,8 +917,6 @@ class SettingsDirectory(QommonSettingsDirectory):
                 'datasources', 'wscalls'):
             if form.get_widget(w) and form.get_widget(w).parse():
                 dirs.append(w)
-        if 'workflows' in dirs:
-            dirs.append('models')
         if not dirs and not form.get_widget('settings').parse():
             return redirect('.')
 
diff --git a/wcs/publisher.py b/wcs/publisher.py
index 288a205b3..5ca21f95d 100644
--- a/wcs/publisher.py
+++ b/wcs/publisher.py
@@ -195,6 +195,8 @@ class WcsPublisher(StubWcsPublisher):
         for f in z.namelist():
             if '.indexes' in f:
                 continue
+            if os.path.dirname(f) in ('formdefs_xml', 'workflows_xml'):
+                continue
             path = os.path.join(self.app_dir, f)
             if not os.path.exists(os.path.dirname(path)):
                 os.mkdir(os.path.dirname(path))
@@ -223,6 +225,24 @@ class WcsPublisher(StubWcsPublisher):
             if results.has_key(os.path.split(f)[0]):
                 results[os.path.split(f)[0]] += 1
 
+        # second pass, workflows
+        from wcs.workflows import Workflow
+        for f in z.namelist():
+            if os.path.dirname(f) == 'workflows_xml' and os.path.basename(f):
+                workflow = Workflow.import_from_xml(z.open(f), include_id=True)
+                workflow.store()
+                results['workflows'] += 1
+
+        # third pass, forms
+        from wcs.formdef import FormDef
+        formdefs = []
+        for f in z.namelist():
+            if os.path.dirname(f) == 'formdefs_xml' and os.path.basename(f):
+                formdef = FormDef.import_from_xml(z.open(f), include_id=True)
+                formdef.store()
+                formdefs.append(formdef)
+                results['formdefs'] += 1
+
         # rebuild indexes for imported objects
         for k, v in results.items():
             if k == 'settings':
@@ -248,7 +268,7 @@ class WcsPublisher(StubWcsPublisher):
             if k == 'formdefs':
                 # in case of formdefs, we store them anew in case SQL changes
                 # are required.
-                for formdef in FormDef.select():
+                for formdef in (formdefs or FormDef.select()):
                     formdef.store()
 
         z.close()
-- 
2.22.0

