Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 47 additions & 44 deletions common/lib/xmodule/setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,47 @@
from setuptools import setup, find_packages

XMODULES = [
"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",
]

setup(
name="XModule",
version="0.1",
Expand All @@ -11,55 +53,16 @@
'path.py',
],
package_data={
'xmodule': ['js/module/*']
'xmodule': ['js/module/*'],
},

# See http://guide.python-distribute.org/creation.html#entry-points
# for a description of entry_points
entry_points={
'xmodule.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"
],
'xblock.v1': XMODULES,
'xmodule.v1': XMODULES,
'console_scripts': [
'xmodule_assets = xmodule.static_content:main',
]
}
],
},
)
4 changes: 2 additions & 2 deletions common/lib/xmodule/xmodule/error_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ def _construct(cls, system, contents, error_msg, location):
})
return system.construct_xblock_from_class(
cls,
field_data,
# The error module doesn't use scoped data, and thus doesn't need
# real scope keys
ScopeIds('error', None, location, location)
ScopeIds('error', None, location, location),
field_data,
)

def get_context(self):
Expand Down
7 changes: 3 additions & 4 deletions common/lib/xmodule/xmodule/modulestore/mongo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def load_item(self, location):

field_data = DbModel(kvs)
scope_ids = ScopeIds(None, category, location, location)
module = self.construct_xblock_from_class(class_, field_data, scope_ids)
module = self.construct_xblock_from_class(class_, scope_ids, field_data)
if self.cached_metadata is not None:
# parent container pointers don't differentiate between draft and non-draft
# so when we do the lookup, we should do so with a non-draft location
Expand Down Expand Up @@ -621,12 +621,11 @@ def create_xmodule(self, location, definition_data=None, metadata=None, system=N
dbmodel = self._create_new_field_data(location.category, location, definition_data, metadata)
xmodule = system.construct_xblock_from_class(
xblock_class,
dbmodel,

# We're loading a descriptor, so student_id is meaningless
# We also don't have separate notions of definition and usage ids yet,
# so we use the location for both.
ScopeIds(None, location.category, location, location)
ScopeIds(None, location.category, location, location),
dbmodel,
)
# decache any pending field settings from init
xmodule.save()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ def xblock_from_json(self, class_, usage_id, json_data, course_entry_override=No
try:
module = self.construct_xblock_from_class(
class_,
ScopeIds(None, json_data.get('category'), definition_id, block_locator),
field_data,
ScopeIds(None, json_data.get('category'), definition_id, block_locator)
)
except Exception:
log.warning("Failed to load descriptor", exc_info=True)
Expand Down
49 changes: 41 additions & 8 deletions common/lib/xmodule/xmodule/modulestore/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
from xmodule.errortracker import make_error_tracker, exc_info_to_str
from xmodule.course_module import CourseDescriptor
from xmodule.mako_module import MakoDescriptorSystem
from xmodule.x_module import XModuleDescriptor, XMLParsingSystem
from xmodule.x_module import XMLParsingSystem, XModuleDescriptor

from xmodule.html_module import HtmlDescriptor
from xblock.core import XBlock
from xblock.fields import ScopeIds
from xblock.field_data import DictFieldData

Expand Down Expand Up @@ -63,7 +64,7 @@ def __init__(self, xmlstore, course_id, course_dir,
self.load_error_modules = load_error_modules

def process_xml(xml):
"""Takes an xml string, and returns a XModuleDescriptor created from
"""Takes an xml string, and returns a XBlock created from
that xml.
"""

Expand Down Expand Up @@ -163,7 +164,7 @@ def fallback_name(orig_name=None):

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:
Expand Down Expand Up @@ -219,6 +220,38 @@ def fallback_name(orig_name=None):
)


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 = XModuleDescriptor.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):
Expand Down Expand Up @@ -278,8 +311,8 @@ class to use if none is specified in entry_points
super(XMLModuleStore, self).__init__(**kwargs)

self.data_dir = path(data_dir)
self.modules = defaultdict(dict) # course_id -> dict(location -> XModuleDescriptor)
self.courses = {} # course_dir -> XModuleDescriptor for the course
self.modules = defaultdict(dict) # course_id -> dict(location -> XBlock)
self.courses = {} # course_dir -> XBlock for the course
self.errored_courses = {} # course_dir -> errorlog, for dirs that failed to load

self.load_error_modules = load_error_modules
Expand Down Expand Up @@ -477,11 +510,11 @@ def _load_extra_content(self, system, course_descriptor, category, path, course_
loc = Location('i4x', course_descriptor.location.org, course_descriptor.location.course, category, slug)
module = system.construct_xblock_from_class(
HtmlDescriptor,
DictFieldData({'data': html, 'location': loc, 'category': category}),
# We're loading a descriptor, so student_id is meaningless
# We also don't have separate notions of definition and usage ids yet,
# so we use the location for both
ScopeIds(None, category, loc, loc),
DictFieldData({'data': html, 'location': loc, 'category': category}),
)
# VS[compat]:
# Hack because we need to pull in the 'display_name' for static tabs (because we need to edit them)
Expand All @@ -500,7 +533,7 @@ def _load_extra_content(self, system, course_descriptor, category, path, course_

def get_instance(self, course_id, location, depth=0):
"""
Returns an XModuleDescriptor instance for the item at
Returns an XBlock instance for the item at
location, with the policy for course_id. (In case two xml
dirs have different content at the same location, return the
one for this course_id.)
Expand Down Expand Up @@ -528,7 +561,7 @@ def has_item(self, course_id, location):

def get_item(self, location, depth=0):
"""
Returns an XModuleDescriptor instance for the item at location.
Returns an XBlock instance for the item at location.

If any segment of the location is None except revision, raises
xmodule.modulestore.exceptions.InsufficientSpecificationError
Expand Down
2 changes: 1 addition & 1 deletion common/lib/xmodule/xmodule/tests/test_editing_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def setUp(self):
TabsEditingDescriptor.tabs = self.tabs
self.descriptor = system.construct_xblock_from_class(
TabsEditingDescriptor,
field_data=DictFieldData({}),
scope_ids=ScopeIds(None, None, None, None),
field_data=DictFieldData({}),
)

def test_get_css(self):
Expand Down
2 changes: 1 addition & 1 deletion common/lib/xmodule/xmodule/tests/test_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ def setUp(self):
system = get_test_descriptor_system()
self.descriptor = system.construct_xblock_from_class(
VideoDescriptor,
field_data=DictFieldData({}),
scope_ids=ScopeIds(None, None, None, None),
field_data=DictFieldData({}),
)

def test_get_context(self):
Expand Down
4 changes: 2 additions & 2 deletions common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ def leaf_descriptor(self, descriptor_cls):
runtime.render_template = lambda *args, **kwargs: u'{!r}, {!r}'.format(args, kwargs)
return runtime.construct_xblock_from_class(
descriptor_cls,
ScopeIds(None, descriptor_cls.__name__, location, location),
DictFieldData({}),
ScopeIds(None, descriptor_cls.__name__, location, location)
)

def leaf_module(self, descriptor_cls):
Expand All @@ -109,10 +109,10 @@ def container_descriptor(self, descriptor_cls):
runtime.render_template = lambda *args, **kwargs: u'{!r}, {!r}'.format(args, kwargs)
return runtime.construct_xblock_from_class(
descriptor_cls,
ScopeIds(None, descriptor_cls.__name__, location, location),
DictFieldData({
'children': range(3)
}),
ScopeIds(None, descriptor_cls.__name__, location, location)
)

def container_module(self, descriptor_cls, depth):
Expand Down
2 changes: 1 addition & 1 deletion common/lib/xmodule/xmodule/tests/test_xml_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ def get_xml_editable_fields(self, field_data):
runtime = get_test_descriptor_system()
return runtime.construct_xblock_from_class(
XmlDescriptor,
scope_ids=Mock(),
field_data=field_data,
scope_ids=Mock()
).editable_metadata_fields

def get_descriptor(self, field_data):
Expand Down
11 changes: 6 additions & 5 deletions common/lib/xmodule/xmodule/tests/xml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import pprint
from mock import Mock

from xmodule.x_module import XMLParsingSystem, XModuleDescriptor
from xmodule.x_module import XMLParsingSystem
from xmodule.mako_module import MakoDescriptorSystem
from xmodule.modulestore.xml import create_block_from_xml


class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable=abstract-method
Expand All @@ -28,8 +29,8 @@ def __init__(self, xml_import_data):
)

def process_xml(self, xml): # pylint: disable=method-hidden
"""Parse `xml` as an XModuleDescriptor, and add it to `self._descriptors`"""
descriptor = XModuleDescriptor.load_from_xml(xml, self, self.org, self.course, self.default_class)
"""Parse `xml` as an XBlock, and add it to `self._descriptors`"""
descriptor = create_block_from_xml(xml, self, self.org, self.course, self.default_class)
self._descriptors[descriptor.location.url()] = descriptor
return descriptor

Expand All @@ -39,8 +40,8 @@ def load_item(self, location): # pylint: disable=method-hidden


class XModuleXmlImportTest(object):
"""Base class for tests that use basic `XModuleDescriptor.load_from_xml` xml parsing"""
"""Base class for tests that use basic XML parsing"""
def process_xml(self, xml_import_data):
"""Use the `xml_import_data` to import an :class:`XModuleDescriptor` from xml"""
"""Use the `xml_import_data` to import an :class:`XBlock` from XML."""
system = InMemorySystem(xml_import_data)
return system.process_xml(xml_import_data.xml_string)
5 changes: 2 additions & 3 deletions common/lib/xmodule/xmodule/video_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,11 @@ def from_xml(cls, xml_data, system, org=None, course=None):
field_data = DbModel(kvs)
video = system.construct_xblock_from_class(
cls,
field_data,

# We're loading a descriptor, so student_id is meaningless
# We also don't have separate notions of definition and usage ids yet,
# so we use the location for both
ScopeIds(None, location.category, location, location)
ScopeIds(None, location.category, location, location),
field_data,
)
return video

Expand Down
Loading