Skip to content
Snippets Groups Projects
Commit 3a6450c3 authored by Ned Batchelder's avatar Ned Batchelder
Browse files

Use XModuleDescriptor.parse_xml to interpret XML.

parent c36adf84
Branches
Tags
No related merge requests found
...@@ -17,6 +17,47 @@ setup( ...@@ -17,6 +17,47 @@ setup(
# See http://guide.python-distribute.org/creation.html#entry-points # See http://guide.python-distribute.org/creation.html#entry-points
# for a description of entry_points # for a description of entry_points
entry_points={ entry_points={
'xblock.v1': [
"abtest = xmodule.abtest_module:ABTestDescriptor",
"book = xmodule.backcompat_module:TranslateCustomTagDescriptor",
"chapter = xmodule.seq_module:SequenceDescriptor",
"combinedopenended = xmodule.combined_open_ended_module:CombinedOpenEndedDescriptor",
"conditional = xmodule.conditional_module:ConditionalDescriptor",
"course = xmodule.course_module:CourseDescriptor",
"customtag = xmodule.template_module:CustomTagDescriptor",
"discuss = xmodule.backcompat_module:TranslateCustomTagDescriptor",
"html = xmodule.html_module:HtmlDescriptor",
"image = xmodule.backcompat_module:TranslateCustomTagDescriptor",
"error = xmodule.error_module:ErrorDescriptor",
"peergrading = xmodule.peer_grading_module:PeerGradingDescriptor",
"poll_question = xmodule.poll_module:PollDescriptor",
"problem = xmodule.capa_module:CapaDescriptor",
"problemset = xmodule.seq_module:SequenceDescriptor",
"randomize = xmodule.randomize_module:RandomizeDescriptor",
"section = xmodule.backcompat_module:SemanticSectionDescriptor",
"sequential = xmodule.seq_module:SequenceDescriptor",
"slides = xmodule.backcompat_module:TranslateCustomTagDescriptor",
"timelimit = xmodule.timelimit_module:TimeLimitDescriptor",
"vertical = xmodule.vertical_module:VerticalDescriptor",
"video = xmodule.video_module:VideoDescriptor",
"videoalpha = xmodule.video_module:VideoDescriptor",
"videodev = xmodule.backcompat_module:TranslateCustomTagDescriptor",
"videosequence = xmodule.seq_module:SequenceDescriptor",
"discussion = xmodule.discussion_module:DiscussionDescriptor",
"course_info = xmodule.html_module:CourseInfoDescriptor",
"static_tab = xmodule.html_module:StaticTabDescriptor",
"custom_tag_template = xmodule.raw_module:RawDescriptor",
"about = xmodule.html_module:AboutDescriptor",
"wrapper = xmodule.wrapper_module:WrapperDescriptor",
"graphical_slider_tool = xmodule.gst_module:GraphicalSliderToolDescriptor",
"annotatable = xmodule.annotatable_module:AnnotatableDescriptor",
"foldit = xmodule.foldit_module:FolditDescriptor",
"word_cloud = xmodule.word_cloud_module:WordCloudDescriptor",
"hidden = xmodule.hidden_module:HiddenDescriptor",
"raw = xmodule.raw_module:RawDescriptor",
"crowdsource_hinter = xmodule.crowdsource_hinter:CrowdsourceHinterDescriptor",
"lti = xmodule.lti_module:LTIModuleDescriptor"
],
'xmodule.v1': [ 'xmodule.v1': [
"abtest = xmodule.abtest_module:ABTestDescriptor", "abtest = xmodule.abtest_module:ABTestDescriptor",
"book = xmodule.backcompat_module:TranslateCustomTagDescriptor", "book = xmodule.backcompat_module:TranslateCustomTagDescriptor",
......
...@@ -20,8 +20,10 @@ from xmodule.mako_module import MakoDescriptorSystem ...@@ -20,8 +20,10 @@ from xmodule.mako_module import MakoDescriptorSystem
from xmodule.x_module import XModuleDescriptor, XMLParsingSystem from xmodule.x_module import XModuleDescriptor, XMLParsingSystem
from xmodule.html_module import HtmlDescriptor from xmodule.html_module import HtmlDescriptor
from xblock.core import XBlock
from xblock.fields import ScopeIds from xblock.fields import ScopeIds
from xblock.field_data import DictFieldData from xblock.field_data import DictFieldData
from xblock.plugin import PluginMissingError
from . import ModuleStoreBase, Location, XML_MODULESTORE_TYPE from . import ModuleStoreBase, Location, XML_MODULESTORE_TYPE
...@@ -163,7 +165,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem): ...@@ -163,7 +165,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
make_name_unique(xml_data) make_name_unique(xml_data)
descriptor = XModuleDescriptor.load_from_xml( descriptor = create_block_from_xml(
etree.tostring(xml_data, encoding='unicode'), self, self.org, etree.tostring(xml_data, encoding='unicode'), self, self.org,
self.course, xmlstore.default_class) self.course, xmlstore.default_class)
except Exception as err: except Exception as err:
...@@ -219,6 +221,38 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem): ...@@ -219,6 +221,38 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
) )
def create_block_from_xml(xml_data, system, org=None, course=None, default_class=None):
"""
Create an XBlock instance from XML data.
`xml_data' is a string containing valid xml.
`system` is an XMLParsingSystem.
`org` and `course` are optional strings that will be used in the generated
block's url identifiers.
`default_class` is the class to instantiate of the XML indicates a class
that can't be loaded.
Returns the fully instantiated XBlock.
"""
node = etree.fromstring(xml_data)
raw_class = XBlock.load_class(node.tag, default_class)
xblock_class = system.mixologist.mix(raw_class)
# leave next line commented out - useful for low-level debugging
# log.debug('[create_block_from_xml] tag=%s, class=%s' % (node.tag, xblock_class))
url_name = node.get('url_name', node.get('slug'))
location = Location('i4x', org, course, node.tag, url_name)
scope_ids = ScopeIds(None, location.category, location, location)
xblock = xblock_class.parse_xml(node, system, scope_ids)
return xblock
class ParentTracker(object): class ParentTracker(object):
"""A simple class to factor out the logic for tracking location parent pointers.""" """A simple class to factor out the logic for tracking location parent pointers."""
def __init__(self): def __init__(self):
......
...@@ -524,32 +524,15 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock): ...@@ -524,32 +524,15 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
return cls.metadata_translations.get(key, key) return cls.metadata_translations.get(key, key)
# ================================= XML PARSING ============================ # ================================= XML PARSING ============================
@staticmethod @classmethod
def load_from_xml(xml_data, def parse_xml(cls, node, runtime, keys):
system,
org=None,
course=None,
default_class=None):
""" """
This method instantiates the correct subclass of XModuleDescriptor based Interpret the parsed XML in `node`, creating an XModuleDescriptor.
on the contents of xml_data.
xml_data must be a string containing valid xml
system is an XMLParsingSystem
org and course are optional strings that will be used in the generated
module's url identifiers
""" """
class_ = system.mixologist.mix(XModuleDescriptor.load_class( xml = etree.tostring(node)
etree.fromstring(xml_data).tag, # TODO: change from_xml to not take org and course, it can use self.system.
default_class block = cls.from_xml(xml, runtime, runtime.org, runtime.course)
)) return block
# leave next line, commented out - useful for low-level debugging
# log.debug('[XModuleDescriptor.load_from_xml] tag=%s, class_=%s' % (
# etree.fromstring(xml_data).tag,class_))
return class_.from_xml(xml_data, system, org, course)
@classmethod @classmethod
def from_xml(cls, xml_data, system, org=None, course=None): def from_xml(cls, xml_data, system, org=None, course=None):
...@@ -713,7 +696,9 @@ class DescriptorSystem(Runtime): ...@@ -713,7 +696,9 @@ class DescriptorSystem(Runtime):
that you're about to re-raise---let the caller track them. that you're about to re-raise---let the caller track them.
""" """
super(DescriptorSystem, self).__init__(**kwargs) # Right now, usage_store is unused, and field_data is always supplanted
# with an explicit field_data during construct_xblock, so None's suffice.
super(DescriptorSystem, self).__init__(usage_store=None, field_data=None, **kwargs)
self.load_item = load_item self.load_item = load_item
self.resources_fs = resources_fs self.resources_fs = resources_fs
...@@ -835,7 +820,10 @@ class ModuleSystem(Runtime): ...@@ -835,7 +820,10 @@ class ModuleSystem(Runtime):
not to allow the execution of unsafe, unsandboxed code. not to allow the execution of unsafe, unsandboxed code.
""" """
super(ModuleSystem, self).__init__(**kwargs)
# Right now, usage_store is unused, and field_data is always supplanted
# with an explicit field_data during construct_xblock, so None's suffice.
super(ModuleSystem, self).__init__(usage_store=None, field_data=None, **kwargs)
self.ajax_url = ajax_url self.ajax_url = ajax_url
self.xqueue = xqueue self.xqueue = xqueue
......
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