Use XModuleDescriptor.parse_xml to interpret XML.
This commit is contained in:
@@ -17,6 +17,47 @@ setup(
|
||||
# See http://guide.python-distribute.org/creation.html#entry-points
|
||||
# for a description of 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': [
|
||||
"abtest = xmodule.abtest_module:ABTestDescriptor",
|
||||
"book = xmodule.backcompat_module:TranslateCustomTagDescriptor",
|
||||
|
||||
@@ -20,8 +20,10 @@ from xmodule.mako_module import MakoDescriptorSystem
|
||||
from xmodule.x_module import XModuleDescriptor, XMLParsingSystem
|
||||
|
||||
from xmodule.html_module import HtmlDescriptor
|
||||
from xblock.core import XBlock
|
||||
from xblock.fields import ScopeIds
|
||||
from xblock.field_data import DictFieldData
|
||||
from xblock.plugin import PluginMissingError
|
||||
|
||||
from . import ModuleStoreBase, Location, XML_MODULESTORE_TYPE
|
||||
|
||||
@@ -163,7 +165,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
|
||||
|
||||
make_name_unique(xml_data)
|
||||
|
||||
descriptor = XModuleDescriptor.load_from_xml(
|
||||
descriptor = create_block_from_xml(
|
||||
etree.tostring(xml_data, encoding='unicode'), self, self.org,
|
||||
self.course, xmlstore.default_class)
|
||||
except Exception as err:
|
||||
@@ -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):
|
||||
"""A simple class to factor out the logic for tracking location parent pointers."""
|
||||
def __init__(self):
|
||||
|
||||
@@ -524,32 +524,15 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
|
||||
return cls.metadata_translations.get(key, key)
|
||||
|
||||
# ================================= XML PARSING ============================
|
||||
@staticmethod
|
||||
def load_from_xml(xml_data,
|
||||
system,
|
||||
org=None,
|
||||
course=None,
|
||||
default_class=None):
|
||||
@classmethod
|
||||
def parse_xml(cls, node, runtime, keys):
|
||||
"""
|
||||
This method instantiates the correct subclass of XModuleDescriptor based
|
||||
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
|
||||
Interpret the parsed XML in `node`, creating an XModuleDescriptor.
|
||||
"""
|
||||
class_ = system.mixologist.mix(XModuleDescriptor.load_class(
|
||||
etree.fromstring(xml_data).tag,
|
||||
default_class
|
||||
))
|
||||
# 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)
|
||||
xml = etree.tostring(node)
|
||||
# TODO: change from_xml to not take org and course, it can use self.system.
|
||||
block = cls.from_xml(xml, runtime, runtime.org, runtime.course)
|
||||
return block
|
||||
|
||||
@classmethod
|
||||
def from_xml(cls, xml_data, system, org=None, course=None):
|
||||
@@ -713,7 +696,9 @@ class DescriptorSystem(Runtime):
|
||||
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.resources_fs = resources_fs
|
||||
@@ -835,7 +820,10 @@ class ModuleSystem(Runtime):
|
||||
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.xqueue = xqueue
|
||||
|
||||
Reference in New Issue
Block a user