Commit 8c42e0f5 by Calen Pennington

Import course objects first, so that later updates that try and edit the course object don't fail

parent 040abfcc
...@@ -89,53 +89,8 @@ def verify_content_links(module, base_dir, static_content_store, link, remap_dic ...@@ -89,53 +89,8 @@ def verify_content_links(module, base_dir, static_content_store, link, remap_dic
return link return link
def import_from_xml(store, data_dir, course_dirs=None,
default_class='xmodule.raw_module.RawDescriptor',
load_error_modules=True, static_content_store=None, target_location_namespace=None):
"""
Import the specified xml data_dir into the "store" modulestore,
using org and course as the location org and course.
course_dirs: If specified, the list of course_dirs to load. Otherwise, load
all course dirs
target_location_namespace is the namespace [passed as Location] (i.e. {tag},{org},{course}) that all modules in the should be remapped to
after import off disk. We do this remapping as a post-processing step because there's logic in the importing which
expects a 'url_name' as an identifier to where things are on disk e.g. ../policies/<url_name>/policy.json as well as metadata keys in
the policy.json. so we need to keep the original url_name during import
"""
module_store = XMLModuleStore(
data_dir,
default_class=default_class,
course_dirs=course_dirs,
load_error_modules=load_error_modules
)
# NOTE: the XmlModuleStore does not implement get_items() which would be a preferable means
# to enumerate the entire collection of course modules. It will be left as a TBD to implement that
# method on XmlModuleStore.
course_items = []
for course_id in module_store.modules.keys():
course_data_path = None
course_location = None
# Quick scan to get course Location as well as the course_data_path
for module in module_store.modules[course_id].itervalues():
if module.category == 'course':
course_data_path = path(data_dir) / module.data_dir
course_location = module.location
if static_content_store is not None:
_namespace_rename = target_location_namespace if target_location_namespace is not None else module_store.modules[course_id].location
# first pass to find everything in /static/
import_static_content(module_store.modules[course_id], course_location, course_data_path, static_content_store,
_namespace_rename, subpath='static')
for module in module_store.modules[course_id].itervalues():
def import_module_from_xml(modulestore, static_content_store, course_data_path, module, target_location_namespace=None):
# remap module to the new namespace # remap module to the new namespace
if target_location_namespace is not None: if target_location_namespace is not None:
# This looks a bit wonky as we need to also change the 'name' of the imported course to be what # This looks a bit wonky as we need to also change the 'name' of the imported course to be what
...@@ -160,26 +115,6 @@ def import_from_xml(store, data_dir, course_dirs=None, ...@@ -160,26 +115,6 @@ def import_from_xml(store, data_dir, course_dirs=None,
module.definition['children'] = new_locs module.definition['children'] = new_locs
if module.category == 'course':
# HACK: for now we don't support progress tabs. There's a special metadata configuration setting for this.
module.hide_progress_tab = True
# cdodge: more hacks (what else). Seems like we have a problem when importing a course (like 6.002) which
# does not have any tabs defined in the policy file. The import goes fine and then displays fine in LMS,
# but if someone tries to add a new tab in the CMS, then the LMS barfs because it expects that -
# if there is *any* tabs - then there at least needs to be some predefined ones
if module.tabs is None or len(module.tabs) == 0:
module.tabs = [{"type": "courseware"},
{"type": "course_info", "name": "Course Info"},
{"type": "discussion", "name": "Discussion"},
{"type": "wiki", "name": "Wiki"}] # note, add 'progress' when we can support it on Edge
# a bit of a hack, but typically the "course image" which is shown on marketing pages is hard coded to /images/course_image.jpg
# so let's make sure we import in case there are no other references to it in the modules
verify_content_links(module, course_data_path, static_content_store, '/static/images/course_image.jpg')
course_items.append(module)
if hasattr(module, 'data'): if hasattr(module, 'data'):
# cdodge: now go through any link references to '/static/' and make sure we've imported # cdodge: now go through any link references to '/static/' and make sure we've imported
# it as a StaticContent asset # it as a StaticContent asset
...@@ -203,10 +138,10 @@ def import_from_xml(store, data_dir, course_dirs=None, ...@@ -203,10 +138,10 @@ def import_from_xml(store, data_dir, course_dirs=None,
except Exception: except Exception:
logging.exception("failed to rewrite links on {0}. Continuing...".format(module.location)) logging.exception("failed to rewrite links on {0}. Continuing...".format(module.location))
store.update_item(module.location, module.data) modulestore.update_item(module.location, module.data)
if module.has_children: if module.has_children:
store.update_children(module.location, module.children) modulestore.update_children(module.location, module.children)
metadata = {} metadata = {}
for field in module.fields + module.lms.fields: for field in module.fields + module.lms.fields:
...@@ -216,7 +151,83 @@ def import_from_xml(store, data_dir, course_dirs=None, ...@@ -216,7 +151,83 @@ def import_from_xml(store, data_dir, course_dirs=None,
field.name in module._model_data): field.name in module._model_data):
metadata[field.name] = module._model_data[field.name] metadata[field.name] = module._model_data[field.name]
store.update_metadata(module.location, metadata) modulestore.update_metadata(module.location, metadata)
def import_course_from_xml(modulestore, static_content_store, course_data_path, module, target_location_namespace=None):
# HACK: for now we don't support progress tabs. There's a special metadata configuration setting for this.
module.hide_progress_tab = True
# cdodge: more hacks (what else). Seems like we have a problem when importing a course (like 6.002) which
# does not have any tabs defined in the policy file. The import goes fine and then displays fine in LMS,
# but if someone tries to add a new tab in the CMS, then the LMS barfs because it expects that -
# if there is *any* tabs - then there at least needs to be some predefined ones
if module.tabs is None or len(module.tabs) == 0:
module.tabs = [{"type": "courseware"},
{"type": "course_info", "name": "Course Info"},
{"type": "discussion", "name": "Discussion"},
{"type": "wiki", "name": "Wiki"}] # note, add 'progress' when we can support it on Edge
# a bit of a hack, but typically the "course image" which is shown on marketing pages is hard coded to /images/course_image.jpg
# so let's make sure we import in case there are no other references to it in the modules
verify_content_links(module, course_data_path, static_content_store, '/static/images/course_image.jpg')
import_module_from_xml(modulestore, static_content_store, course_data_path, module, target_location_namespace)
def import_from_xml(store, data_dir, course_dirs=None,
default_class='xmodule.raw_module.RawDescriptor',
load_error_modules=True, static_content_store=None, target_location_namespace=None):
"""
Import the specified xml data_dir into the "store" modulestore,
using org and course as the location org and course.
course_dirs: If specified, the list of course_dirs to load. Otherwise, load
all course dirs
target_location_namespace is the namespace [passed as Location] (i.e. {tag},{org},{course}) that all modules in the should be remapped to
after import off disk. We do this remapping as a post-processing step because there's logic in the importing which
expects a 'url_name' as an identifier to where things are on disk e.g. ../policies/<url_name>/policy.json as well as metadata keys in
the policy.json. so we need to keep the original url_name during import
"""
module_store = XMLModuleStore(
data_dir,
default_class=default_class,
course_dirs=course_dirs,
load_error_modules=load_error_modules
)
# NOTE: the XmlModuleStore does not implement get_items() which would be a preferable means
# to enumerate the entire collection of course modules. It will be left as a TBD to implement that
# method on XmlModuleStore.
course_items = []
for course_id in module_store.modules.keys():
course_data_path = None
course_location = None
# Quick scan to get course Location as well as the course_data_path
for module in module_store.modules[course_id].itervalues():
if module.category == 'course':
course_data_path = path(data_dir) / module.data_dir
course_location = module.location
if static_content_store is not None:
_namespace_rename = target_location_namespace if target_location_namespace is not None else module_store.modules[course_id].location
# first pass to find everything in /static/
import_static_content(module_store.modules[course_id], course_location, course_data_path, static_content_store,
_namespace_rename, subpath='static')
# Import course modules first, because importing some of the children requires the course to exist
for module in module_store.modules[course_id].itervalues():
if module.category == 'course':
import_course_from_xml(store, static_content_store, course_data_path, module, target_location_namespace)
# Import the rest of the modules
for module in module_store.modules[course_id].itervalues():
if module.category != 'course':
import_module_from_xml(store, static_content_store, course_data_path, module, target_location_namespace)
return module_store, course_items return module_store, course_items
......
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