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("""
INVALID_CHARS = re.compile(r"[^\w.-]")
_LocationBase = namedtuple('LocationBase', 'tag org course category name revision')
class Location(_LocationBase):
'''
Encodes a location.
......
......@@ -3,6 +3,7 @@ from xmodule.x_module import XModuleDescriptor
from lxml import etree
import copy
import logging
from collections import namedtuple
log = logging.getLogger(__name__)
......@@ -62,6 +63,18 @@ class LazyLoadingDict(MutableMapping):
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):
"""
Mixin class for standardized parsing of from xml
......@@ -75,11 +88,11 @@ class XmlDescriptor(XModuleDescriptor):
metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize',
'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
xml_attribute_map = {
'graded': lambda val: ('graded', val == 'true'),
'name': lambda val: ('display_name', val),
'graded': AttrMap('graded', lambda val: val == 'true', lambda val: str(val).lower()),
'name': AttrMap('display_name'),
}
@classmethod
......@@ -130,12 +143,8 @@ class XmlDescriptor(XModuleDescriptor):
for attr in cls.metadata_attributes:
val = xml_object.get(attr)
if val is not None:
map_fn = cls.xml_attribute_map.get(attr)
if map_fn is None:
metadata[attr] = val
else:
key, val = map_fn(val)
metadata[key] = val
attr_map = cls.xml_attribute_map.get(attr, AttrMap(attr))
metadata[attr_map.metadata_key] = attr_map.to_metadata(val)
return metadata
......@@ -203,15 +212,15 @@ class XmlDescriptor(XModuleDescriptor):
xml_object.set('slug', self.name)
xml_object.tag = self.category
for attr in ('format', 'graceperiod', 'showanswer', 'rerandomize', 'due'):
if attr in self.metadata and attr not in self._inherited_metadata:
xml_object.set(attr, self.metadata[attr])
for attr in self.metadata_attributes:
attr_map = self.xml_attribute_map.get(attr, AttrMap(attr))
metadata_key = attr_map.metadata_key
if 'graded' in self.metadata and 'graded' not in self._inherited_metadata:
xml_object.set('graded', str(self.metadata['graded']).lower())
if metadata_key not in self.metadata or metadata_key in self._inherited_metadata:
continue
if 'display_name' in self.metadata:
xml_object.set('name', self.metadata['display_name'])
val = attr_map.from_metadata(self.metadata[metadata_key])
xml_object.set(attr, val)
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