From f375258b38bd99eaf8914e958e551f8c83ca581a Mon Sep 17 00:00:00 2001
From: Calen Pennington <calen.pennington@gmail.com>
Date: Fri, 29 Jun 2012 16:08:15 -0400
Subject: [PATCH] Add xml export infrastructure for all existing modules

---
 common/lib/xmodule/abtest_module.py | 18 ++++++++++++++++
 common/lib/xmodule/raw_module.py    |  3 +++
 common/lib/xmodule/seq_module.py    |  6 ++++++
 common/lib/xmodule/xml_module.py    | 33 +++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+)

diff --git a/common/lib/xmodule/abtest_module.py b/common/lib/xmodule/abtest_module.py
index 0571cda4dad..f6057171e5c 100644
--- a/common/lib/xmodule/abtest_module.py
+++ b/common/lib/xmodule/abtest_module.py
@@ -103,3 +103,21 @@ class ABTestDescriptor(RawDescriptor, XmlDescriptor):
         definition['data']['group_portions'][DEFAULT] = default_portion
 
         return definition
+
+    def definition_to_xml(self, resource_fs):
+        xml_object = etree.Element('abtest')
+        xml_object.set('experiment', self.definition['data']['experiment'])
+        for name, group in self.definition['data']['group_content'].items():
+            if name == DEFAULT:
+                group_elem = etree.SubElement(xml_object, 'default')
+            else:
+                group_elem = etree.SubElement(xml_object, 'group', attrib={
+                    'portion': str(self.definition['data']['group_portions'][name]),
+                    'name': name,
+                })
+
+            for child_loc in group:
+                child = self.system.load_item(child_loc)
+                group_elem.append(etree.fromstring(child.export_to_xml(resource_fs)))
+
+        return xml_object
diff --git a/common/lib/xmodule/raw_module.py b/common/lib/xmodule/raw_module.py
index 43a92303ad1..59f28ff4f07 100644
--- a/common/lib/xmodule/raw_module.py
+++ b/common/lib/xmodule/raw_module.py
@@ -21,3 +21,6 @@ class RawDescriptor(MakoModuleDescriptor, XmlDescriptor):
     @classmethod
     def definition_from_xml(cls, xml_object, system):
         return {'data': etree.tostring(xml_object)}
+
+    def definition_to_xml(self, resource_fs):
+        return etree.fromstring(self.definition['data'])
diff --git a/common/lib/xmodule/seq_module.py b/common/lib/xmodule/seq_module.py
index 6d493b96ad7..9f00c3be87a 100644
--- a/common/lib/xmodule/seq_module.py
+++ b/common/lib/xmodule/seq_module.py
@@ -108,3 +108,9 @@ class SequenceDescriptor(MakoModuleDescriptor, XmlDescriptor):
             system.process_xml(etree.tostring(child_module)).location.url()
             for child_module in xml_object
         ]}
+
+    def definition_to_xml(self, resource_fs):
+        xml_object = etree.Element('sequential')
+        for child in self.get_children():
+            xml_object.append(etree.fromstring(child.export_to_xml(resource_fs)))
+        return xml_object
diff --git a/common/lib/xmodule/xml_module.py b/common/lib/xmodule/xml_module.py
index b167e52e880..d6338aeb39a 100644
--- a/common/lib/xmodule/xml_module.py
+++ b/common/lib/xmodule/xml_module.py
@@ -51,3 +51,36 @@ class XmlDescriptor(XModuleDescriptor):
                       xml_object.get('slug')],
             metadata=metadata,
         )
+
+    def export_to_xml(self, resource_fs):
+        """
+        Returns an xml string representing this module, and all modules underneath it.
+        May also write required resources out to resource_fs
+
+        Assumes that modules have single parantage (that no module appears twice in the same course),
+        and that it is thus safe to nest modules as xml children as appropriate.
+
+        The returned XML should be able to be parsed back into an identical XModuleDescriptor
+        using the from_xml method with the same system, org, and course
+        """
+        xml_object = self.definition_to_xml(resource_fs)
+        xml_object.set('slug', self.name)
+        xml_object.tag = self.type
+
+        for attr in ('format', 'graceperiod', 'showanswer', 'rerandomize', 'due'):
+            if attr in self.metadata:
+                xml_object.set(attr, self.metadata[attr])
+
+        if 'graded' in self.metadata:
+            xml_object.set('graded', str(self.metadata['graded']).lower())
+
+        if 'display_name' in self.metadata:
+            xml_object.set('name', self.metadata['display_name'])
+
+        return etree.tostring(xml_object, pretty_print=True)
+
+    def definition_to_xml(self, resource_fs):
+        """
+        Return a new etree Element object created from this modules definition.
+        """
+        raise NotImplementedError("%s does not implement definition_to_xml" % self.__class__.__name__)
-- 
GitLab