Fix metadata inheritance
* with xml datastore, re-do all inheritance once the whole course is loaded
This commit is contained in:
@@ -55,6 +55,9 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
|
||||
if json_data is None:
|
||||
return self.modulestore.get_item(location)
|
||||
else:
|
||||
# TODO (vshnayder): metadata inheritance is somewhat broken because mongo, doesn't
|
||||
# always load an entire course. We're punting on this until after launch, and then
|
||||
# will build a proper course policy framework.
|
||||
return XModuleDescriptor.load_from_json(json_data, self, self.default_class)
|
||||
|
||||
|
||||
|
||||
@@ -213,6 +213,12 @@ class XMLModuleStore(ModuleStoreBase):
|
||||
system = ImportSystem(self, org, course, course_dir, tracker)
|
||||
|
||||
course_descriptor = system.process_xml(etree.tostring(course_data))
|
||||
# NOTE: The descriptors end up loading somewhat bottom up, which
|
||||
# breaks metadata inheritance via get_children(). Instead
|
||||
# (actually, in addition to, for now), we do a final inheritance pass
|
||||
# after we have the course descriptor.
|
||||
XModuleDescriptor.compute_inherited_metadata(course_descriptor)
|
||||
|
||||
log.debug('========> Done with course import from {0}'.format(course_dir))
|
||||
return course_descriptor
|
||||
|
||||
|
||||
@@ -8,8 +8,11 @@ from xmodule.x_module import XMLParsingSystem, XModuleDescriptor
|
||||
from xmodule.xml_module import is_pointer_tag
|
||||
from xmodule.errortracker import make_error_tracker
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.xml import XMLModuleStore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
|
||||
from .test_export import DATA_DIR
|
||||
|
||||
ORG = 'test_org'
|
||||
COURSE = 'test_course'
|
||||
|
||||
@@ -185,3 +188,22 @@ class ImportTestCase(unittest.TestCase):
|
||||
chapter_xml = etree.fromstring(f.read())
|
||||
self.assertEqual(chapter_xml.tag, 'chapter')
|
||||
self.assertFalse('graceperiod' in chapter_xml.attrib)
|
||||
|
||||
def test_metadata_inherit(self):
|
||||
"""Make sure that metadata is inherited properly"""
|
||||
|
||||
print "Starting import"
|
||||
initial_import = XMLModuleStore(DATA_DIR, eager=True, course_dirs=['toy'])
|
||||
|
||||
courses = initial_import.get_courses()
|
||||
self.assertEquals(len(courses), 1)
|
||||
course = courses[0]
|
||||
|
||||
def check_for_key(key, node):
|
||||
"recursive check for presence of key"
|
||||
print "Checking {}".format(node.location.url())
|
||||
self.assertTrue(key in node.metadata)
|
||||
for c in node.get_children():
|
||||
check_for_key(key, c)
|
||||
|
||||
check_for_key('graceperiod', course)
|
||||
|
||||
@@ -403,6 +403,21 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
|
||||
return dict((k,v) for k,v in self.metadata.items()
|
||||
if k not in self._inherited_metadata)
|
||||
|
||||
@staticmethod
|
||||
def compute_inherited_metadata(course):
|
||||
"""Given a course descriptor, traverse the entire course tree and do
|
||||
metadata inheritance. Should be called after importing a course.
|
||||
|
||||
NOTE: This means that there is no such thing as lazy loading at the
|
||||
moment--this accesses all the children."""
|
||||
def do_inherit(node):
|
||||
for c in node.get_children():
|
||||
c.inherit_metadata(node.metadata)
|
||||
do_inherit(c)
|
||||
|
||||
do_inherit(course)
|
||||
|
||||
|
||||
def inherit_metadata(self, metadata):
|
||||
"""
|
||||
Updates this module with metadata inherited from a containing module.
|
||||
@@ -415,6 +430,7 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
|
||||
if attr not in self.metadata and attr in metadata:
|
||||
self._inherited_metadata.add(attr)
|
||||
self.metadata[attr] = metadata[attr]
|
||||
print "final self.metadata: {}".format(self.metadata)
|
||||
|
||||
def get_children(self):
|
||||
"""Returns a list of XModuleDescriptor instances for the children of
|
||||
@@ -423,6 +439,9 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
|
||||
self._child_instances = []
|
||||
for child_loc in self.definition.get('children', []):
|
||||
child = self.system.load_item(child_loc)
|
||||
# TODO (vshnayder): this should go away once we have
|
||||
# proper inheritance support in mongo. The xml
|
||||
# datastore does all inheritance on course load.
|
||||
child.inherit_metadata(self.metadata)
|
||||
self._child_instances.append(child)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user