def import_module_from_xml(modulestore, static_content_store, course_data_path, module, target_location_namespace=None, verbose=False): # remap module to the new namespace 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 # the caller passed in if module.location.category != 'course': module.location = module.location._replace( tag=target_location_namespace.tag, org=target_location_namespace.org, course=target_location_namespace.course) else: module.location = module.location._replace( tag=target_location_namespace.tag, org=target_location_namespace.org, course=target_location_namespace.course, name=target_location_namespace.name) # then remap children pointers since they too will be re-namespaced if module.has_children: children_locs = module.children new_locs = [] for child in children_locs: child_loc = Location(child) new_child_loc = child_loc._replace( tag=target_location_namespace.tag, org=target_location_namespace.org, course=target_location_namespace.course) new_locs.append(new_child_loc.url()) module.children = new_locs if hasattr(module, 'data'): # cdodge: now go through any link references to '/static/' and make sure we've imported # it as a StaticContent asset try: remap_dict = {} # use the rewrite_links as a utility means to enumerate through all links # in the module data. We use that to load that reference into our asset store # IMPORTANT: There appears to be a bug in lxml.rewrite_link which makes us not be able to # do the rewrites natively in that code. # For example, what I'm seeing is <img src='foo.jpg' /> -> <img src='bar.jpg'> # Note the dropped element closing tag. This causes the LMS to fail when rendering modules - that's # no good, so we have to do this kludge if isinstance(module.data, str) or isinstance(module.data, unicode): # some module 'data' fields are non strings which blows up the link traversal code lxml_rewrite_links(module.data, lambda link: verify_content_links( module, course_data_path, static_content_store, link, remap_dict)) for key in remap_dict.keys(): module.data = module.data.replace(key, remap_dict[key]) except Exception: logging.exception( "failed to rewrite links on {0}. Continuing...".format(module.location)) modulestore.update_item(module.location, module.data) if module.has_children: modulestore.update_children(module.location, module.children) modulestore.update_metadata(module.location, own_metadata(module))
def import_module(module, store, course_data_path, static_content_store, allow_not_found=False): content = {} for field in module.fields: if field.scope != Scope.content: continue try: content[field.name] = module._model_data[field.name] except KeyError: # Ignore any missing keys in _model_data pass module_data = {} if 'data' in content: module_data = content['data'] # cdodge: now go through any link references to '/static/' and make sure we've imported # it as a StaticContent asset try: remap_dict = {} # use the rewrite_links as a utility means to enumerate through all links # in the module data. We use that to load that reference into our asset store # IMPORTANT: There appears to be a bug in lxml.rewrite_link which makes us not be able to # do the rewrites natively in that code. # For example, what I'm seeing is <img src='foo.jpg' /> -> <img src='bar.jpg'> # Note the dropped element closing tag. This causes the LMS to fail when rendering modules - that's # no good, so we have to do this kludge if isinstance(module_data, str) or isinstance(module_data, unicode): # some module 'data' fields are non strings which blows up the link traversal code lxml_rewrite_links(module_data, lambda link: verify_content_links( module, course_data_path, static_content_store, link, remap_dict)) for key in remap_dict.keys(): module_data = module_data.replace(key, remap_dict[key]) except Exception: logging.exception( "failed to rewrite links on {0}. Continuing...".format(module.location)) else: module_data = content if allow_not_found: store.update_item( module.location, module_data, allow_not_found=allow_not_found) else: store.update_item(module.location, module_data) if hasattr(module, 'children') and module.children != []: store.update_children(module.location, module.children) # NOTE: It's important to use own_metadata here to avoid writing # inherited metadata everywhere. store.update_metadata(module.location, dict(own_metadata(module)))
def rewrite_links(input_html, callback, **kwargs): """Thin wrapper around lxml's `rewrite_links()` that prevents extra HTML markup from being produced when there's no root tag present in the input HTML. This is needed as a workaround for #3889, and it simply wraps the input text within `<div>...</div>` tags. """ return lxml_rewrite_links(u'<div>%s</div>' % input_html, callback, **kwargs)
def import_module(module, store, course_data_path, static_content_store, allow_not_found=False): content = {} for field in module.fields: if field.scope != Scope.content: continue try: content[field.name] = module._model_data[field.name] except KeyError: # Ignore any missing keys in _model_data pass module_data = {} if 'data' in content: module_data = content['data'] # cdodge: now go through any link references to '/static/' and make sure we've imported # it as a StaticContent asset try: remap_dict = {} # use the rewrite_links as a utility means to enumerate through all links # in the module data. We use that to load that reference into our asset store # IMPORTANT: There appears to be a bug in lxml.rewrite_link which makes us not be able to # do the rewrites natively in that code. # For example, what I'm seeing is <img src='foo.jpg' /> -> <img src='bar.jpg'> # Note the dropped element closing tag. This causes the LMS to fail when rendering modules - that's # no good, so we have to do this kludge if isinstance(module_data, str) or isinstance( module_data, unicode ): # some module 'data' fields are non strings which blows up the link traversal code lxml_rewrite_links( module_data, lambda link: verify_content_links( module, course_data_path, static_content_store, link, remap_dict)) for key in remap_dict.keys(): module_data = module_data.replace(key, remap_dict[key]) except Exception: logging.exception( "failed to rewrite links on {0}. Continuing...".format( module.location)) else: module_data = content if allow_not_found: store.update_item(module.location, module_data, allow_not_found=allow_not_found) else: store.update_item(module.location, module_data) if hasattr(module, 'children') and module.children != []: store.update_children(module.location, module.children) # NOTE: It's important to use own_metadata here to avoid writing # inherited metadata everywhere. store.update_metadata(module.location, dict(own_metadata(module)))
def import_module_from_xml(modulestore, static_content_store, course_data_path, module, target_location_namespace=None, verbose=False): # remap module to the new namespace 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 # the caller passed in if module.location.category != 'course': module.location = module.location._replace( tag=target_location_namespace.tag, org=target_location_namespace.org, course=target_location_namespace.course) else: module.location = module.location._replace( tag=target_location_namespace.tag, org=target_location_namespace.org, course=target_location_namespace.course, name=target_location_namespace.name) # then remap children pointers since they too will be re-namespaced if module.has_children: children_locs = module.children new_locs = [] for child in children_locs: child_loc = Location(child) new_child_loc = child_loc._replace( tag=target_location_namespace.tag, org=target_location_namespace.org, course=target_location_namespace.course) new_locs.append(new_child_loc.url()) module.children = new_locs if hasattr(module, 'data'): # cdodge: now go through any link references to '/static/' and make sure we've imported # it as a StaticContent asset try: remap_dict = {} # use the rewrite_links as a utility means to enumerate through all links # in the module data. We use that to load that reference into our asset store # IMPORTANT: There appears to be a bug in lxml.rewrite_link which makes us not be able to # do the rewrites natively in that code. # For example, what I'm seeing is <img src='foo.jpg' /> -> <img src='bar.jpg'> # Note the dropped element closing tag. This causes the LMS to fail when rendering modules - that's # no good, so we have to do this kludge if isinstance(module.data, str) or isinstance( module.data, unicode ): # some module 'data' fields are non strings which blows up the link traversal code lxml_rewrite_links( module.data, lambda link: verify_content_links( module, course_data_path, static_content_store, link, remap_dict)) for key in remap_dict.keys(): module.data = module.data.replace(key, remap_dict[key]) except Exception: logging.exception( "failed to rewrite links on {0}. Continuing...".format( module.location)) modulestore.update_item(module.location, module.data) if module.has_children: modulestore.update_children(module.location, module.children) modulestore.update_metadata(module.location, own_metadata(module))