Commit 54c79f42 by Victor Shnayder

Make the malformed descriptor import properly

* Also get rid of lazy loading of metadata and definition
parent e2f1a71e
......@@ -25,6 +25,7 @@ setup(
"discuss = xmodule.backcompat_module:TranslateCustomTagDescriptor",
"html = xmodule.html_module:HtmlDescriptor",
"image = xmodule.backcompat_module:TranslateCustomTagDescriptor",
"malformed = xmodule.malformed_module:MalformedDescriptor",
"problem = xmodule.capa_module:CapaDescriptor",
"problemset = xmodule.vertical_module:VerticalDescriptor",
"section = xmodule.backcompat_module:SemanticSectionDescriptor",
......
......@@ -20,8 +20,15 @@ class MalformedDescriptor(EditingDescriptor):
Does not try to parse the data--just stores it.
'''
# TODO (vshnayder): how does one get back from this to a valid descriptor?
# try to parse and if successfull, send back to x_module?
#log.debug("processing '{0}'".format(xml_data))
try:
xml_obj = etree.fromstring(xml_data)
if xml_obj.tag == 'malformed':
xml_data = xml_obj.text
# TODO (vshnayder): how does one get back from this to a valid descriptor?
# For now, have to fix manually.
except etree.XMLSyntaxError:
pass
definition = { 'data' : xml_data }
# TODO (vshnayder): Do we need a valid slug here? Just pick a random
......
......@@ -464,6 +464,7 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
# Put import here to avoid circular import errors
from xmodule.malformed_module import MalformedDescriptor
#system.error_handler("Error loading from xml.")
descriptor = MalformedDescriptor.from_xml(xml_data, system, org, course)
return descriptor
......
......@@ -11,66 +11,65 @@ import os
log = logging.getLogger(__name__)
# TODO (cpennington): This was implemented in an attempt to improve performance,
# but the actual improvement wasn't measured (and it was implemented late at night).
# We should check if it hurts, and whether there's a better way of doing lazy loading
class LazyLoadingDict(MutableMapping):
"""
A dictionary object that lazily loads its contents from a provided
function on reads (of members that haven't already been set).
"""
def __init__(self, loader):
'''
On the first read from this dictionary, it will call loader() to
populate its contents. loader() must return something dict-like. Any
elements set before the first read will be preserved.
'''
self._contents = {}
self._loaded = False
self._loader = loader
self._deleted = set()
def __getitem__(self, name):
if not (self._loaded or name in self._contents or name in self._deleted):
self.load()
return self._contents[name]
def __setitem__(self, name, value):
self._contents[name] = value
self._deleted.discard(name)
def __delitem__(self, name):
del self._contents[name]
self._deleted.add(name)
def __contains__(self, name):
self.load()
return name in self._contents
def __len__(self):
self.load()
return len(self._contents)
def __iter__(self):
self.load()
return iter(self._contents)
def __repr__(self):
self.load()
return repr(self._contents)
def load(self):
if self._loaded:
return
loaded_contents = self._loader()
loaded_contents.update(self._contents)
self._contents = loaded_contents
self._loaded = True
# # TODO (cpennington): This was implemented in an attempt to improve performance,
# # but the actual improvement wasn't measured (and it was implemented late at night).
# # We should check if it hurts, and whether there's a better way of doing lazy loading
# class LazyLoadingDict(MutableMapping):
# """
# A dictionary object that lazily loads its contents from a provided
# function on reads (of members that haven't already been set).
# """
# def __init__(self, loader):
# '''
# On the first read from this dictionary, it will call loader() to
# populate its contents. loader() must return something dict-like. Any
# elements set before the first read will be preserved.
# '''
# self._contents = {}
# self._loaded = False
# self._loader = loader
# self._deleted = set()
# def __getitem__(self, name):
# if not (self._loaded or name in self._contents or name in self._deleted):
# self.load()
# return self._contents[name]
# def __setitem__(self, name, value):
# self._contents[name] = value
# self._deleted.discard(name)
# def __delitem__(self, name):
# del self._contents[name]
# self._deleted.add(name)
# def __contains__(self, name):
# self.load()
# return name in self._contents
# def __len__(self):
# self.load()
# return len(self._contents)
# def __iter__(self):
# self.load()
# return iter(self._contents)
# def __repr__(self):
# self.load()
# return repr(self._contents)
# def load(self):
# if self._loaded:
# return
# loaded_contents = self._loader()
# loaded_contents.update(self._contents)
# self._contents = loaded_contents
# self._loaded = True
_AttrMapBase = namedtuple('_AttrMap', 'metadata_key to_metadata from_metadata')
......@@ -230,11 +229,13 @@ class XmlDescriptor(XModuleDescriptor):
cls.clean_metadata_from_xml(definition_xml)
return cls.definition_from_xml(definition_xml, system)
# VS[compat] -- just have the url_name lookup once translation is done
slug = xml_object.get('url_name', xml_object.get('slug'))
return cls(
system,
LazyLoadingDict(definition_loader),
definition,
location=location,
metadata=LazyLoadingDict(metadata_loader),
metadata=metadata,
)
@classmethod
......
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