Commit cf12a2ed by Calen Pennington

Clean up how mapping from metadata to xml attributes is done

parent cebdf797
...@@ -24,6 +24,8 @@ URL_RE = re.compile(""" ...@@ -24,6 +24,8 @@ URL_RE = re.compile("""
INVALID_CHARS = re.compile(r"[^\w.-]") INVALID_CHARS = re.compile(r"[^\w.-]")
_LocationBase = namedtuple('LocationBase', 'tag org course category name revision') _LocationBase = namedtuple('LocationBase', 'tag org course category name revision')
class Location(_LocationBase): class Location(_LocationBase):
''' '''
Encodes a location. Encodes a location.
......
...@@ -3,6 +3,7 @@ from xmodule.x_module import XModuleDescriptor ...@@ -3,6 +3,7 @@ from xmodule.x_module import XModuleDescriptor
from lxml import etree from lxml import etree
import copy import copy
import logging import logging
from collections import namedtuple
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -62,6 +63,18 @@ class LazyLoadingDict(MutableMapping): ...@@ -62,6 +63,18 @@ class LazyLoadingDict(MutableMapping):
self._loaded = True self._loaded = True
_AttrMapBase = namedtuple('_AttrMap', 'metadata_key to_metadata from_metadata')
class AttrMap(_AttrMapBase):
"""
A class that specifies a metadata_key, a function to transform an xml attribute to be placed in that key,
and to transform that key value
"""
def __new__(_cls, metadata_key, to_metadata=lambda x: x, from_metadata=lambda x: x):
return _AttrMapBase.__new__(_cls, metadata_key, to_metadata, from_metadata)
class XmlDescriptor(XModuleDescriptor): class XmlDescriptor(XModuleDescriptor):
""" """
Mixin class for standardized parsing of from xml Mixin class for standardized parsing of from xml
...@@ -75,11 +88,11 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -75,11 +88,11 @@ class XmlDescriptor(XModuleDescriptor):
metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize', metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize',
'due', 'graded', 'name', 'slug') 'due', 'graded', 'name', 'slug')
# A dictionary mapping xml attribute names to function of the value # A dictionary mapping xml attribute names to functions of the value
# that return the metadata key and value # that return the metadata key and value
xml_attribute_map = { xml_attribute_map = {
'graded': lambda val: ('graded', val == 'true'), 'graded': AttrMap('graded', lambda val: val == 'true', lambda val: str(val).lower()),
'name': lambda val: ('display_name', val), 'name': AttrMap('display_name'),
} }
@classmethod @classmethod
...@@ -130,12 +143,8 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -130,12 +143,8 @@ class XmlDescriptor(XModuleDescriptor):
for attr in cls.metadata_attributes: for attr in cls.metadata_attributes:
val = xml_object.get(attr) val = xml_object.get(attr)
if val is not None: if val is not None:
map_fn = cls.xml_attribute_map.get(attr) attr_map = cls.xml_attribute_map.get(attr, AttrMap(attr))
if map_fn is None: metadata[attr_map.metadata_key] = attr_map.to_metadata(val)
metadata[attr] = val
else:
key, val = map_fn(val)
metadata[key] = val
return metadata return metadata
...@@ -203,15 +212,15 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -203,15 +212,15 @@ class XmlDescriptor(XModuleDescriptor):
xml_object.set('slug', self.name) xml_object.set('slug', self.name)
xml_object.tag = self.category xml_object.tag = self.category
for attr in ('format', 'graceperiod', 'showanswer', 'rerandomize', 'due'): for attr in self.metadata_attributes:
if attr in self.metadata and attr not in self._inherited_metadata: attr_map = self.xml_attribute_map.get(attr, AttrMap(attr))
xml_object.set(attr, self.metadata[attr]) metadata_key = attr_map.metadata_key
if 'graded' in self.metadata and 'graded' not in self._inherited_metadata: if metadata_key not in self.metadata or metadata_key in self._inherited_metadata:
xml_object.set('graded', str(self.metadata['graded']).lower()) continue
if 'display_name' in self.metadata: val = attr_map.from_metadata(self.metadata[metadata_key])
xml_object.set('name', self.metadata['display_name']) xml_object.set(attr, val)
return etree.tostring(xml_object, pretty_print=True) return etree.tostring(xml_object, pretty_print=True)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment