def load_course(self, course_dir, tracker): """ Load a course into this module store course_path: Course directory name returns a CourseDescriptor for the course """ log.debug( '========> Starting course import from {0}'.format(course_dir)) with open(self.data_dir / course_dir / "course.xml") as course_file: # VS[compat] # TODO (cpennington): Remove this once all fall 2012 courses have # been imported into the cms from xml course_file = StringIO( clean_out_mako_templating(course_file.read())) course_data = etree.parse(course_file, parser=edx_xml_parser).getroot() org = course_data.get('org') if org is None: msg = ("No 'org' attribute set for course in {dir}. " "Using default 'edx'".format(dir=course_dir)) log.warning(msg) tracker(msg) org = 'edx' course = course_data.get('course') if course is None: msg = ("No 'course' attribute set for course in {dir}." " Using default '{default}'".format(dir=course_dir, default=course_dir)) log.warning(msg) tracker(msg) course = course_dir url_name = course_data.get('url_name', course_data.get('slug')) policy_dir = None if url_name: policy_dir = self.data_dir / course_dir / 'policies' / url_name policy_path = policy_dir / 'policy.json' policy = self.load_policy(policy_path, tracker) # VS[compat]: remove once courses use the policy dirs. if policy == {}: old_policy_path = self.data_dir / course_dir / 'policies' / '{0}.json'.format( url_name) policy = self.load_policy(old_policy_path, tracker) else: policy = {} # VS[compat] : 'name' is deprecated, but support it for now... if course_data.get('name'): url_name = Location.clean(course_data.get('name')) tracker("'name' is deprecated for module xml. Please use " "display_name and url_name.") else: raise ValueError( "Can't load a course without a 'url_name' " "(or 'name') set. Set url_name.") course_id = CourseDescriptor.make_id(org, course, url_name) system = ImportSystem( xmlstore=self, course_id=course_id, course_dir=course_dir, error_tracker=tracker, parent_tracker=self.parent_trackers[course_id], load_error_modules=self.load_error_modules, policy=policy, mixins=self.xblock_mixins, ) course_descriptor = system.process_xml( etree.tostring(course_data, encoding='unicode')) # If we fail to load the course, then skip the rest of the loading steps if isinstance(course_descriptor, ErrorDescriptor): return course_descriptor # 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. compute_inherited_metadata(course_descriptor) # now import all pieces of course_info which is expected to be stored # in <content_dir>/info or <content_dir>/info/<url_name> self.load_extra_content(system, course_descriptor, 'course_info', self.data_dir / course_dir / 'info', course_dir, url_name) # now import all static tabs which are expected to be stored in # in <content_dir>/tabs or <content_dir>/tabs/<url_name> self.load_extra_content(system, course_descriptor, 'static_tab', self.data_dir / course_dir / 'tabs', course_dir, url_name) self.load_extra_content(system, course_descriptor, 'custom_tag_template', self.data_dir / course_dir / 'custom_tags', course_dir, url_name) self.load_extra_content(system, course_descriptor, 'about', self.data_dir / course_dir / 'about', course_dir, url_name) log.debug('========> Done with course import from {0}'.format( course_dir)) return course_descriptor
def load_course(self, course_dir, tracker): """ Load a course into this module store course_path: Course directory name returns a CourseDescriptor for the course """ log.debug('========> Starting course import from {0}'.format(course_dir)) with open(self.data_dir / course_dir / "course.xml") as course_file: # VS[compat] # TODO (cpennington): Remove this once all fall 2012 courses have # been imported into the cms from xml course_file = StringIO(clean_out_mako_templating(course_file.read())) course_data = etree.parse(course_file, parser=edx_xml_parser).getroot() org = course_data.get('org') if org is None: msg = ("No 'org' attribute set for course in {dir}. " "Using default 'edx'".format(dir=course_dir)) log.warning(msg) tracker(msg) org = 'edx' course = course_data.get('course') if course is None: msg = ("No 'course' attribute set for course in {dir}." " Using default '{default}'".format(dir=course_dir, default=course_dir ) ) log.warning(msg) tracker(msg) course = course_dir url_name = course_data.get('url_name', course_data.get('slug')) policy_dir = None if url_name: policy_dir = self.data_dir / course_dir / 'policies' / url_name policy_path = policy_dir / 'policy.json' policy = self.load_policy(policy_path, tracker) # VS[compat]: remove once courses use the policy dirs. if policy == {}: old_policy_path = self.data_dir / course_dir / 'policies' / '{0}.json'.format(url_name) policy = self.load_policy(old_policy_path, tracker) else: policy = {} # VS[compat] : 'name' is deprecated, but support it for now... if course_data.get('name'): url_name = Location.clean(course_data.get('name')) tracker("'name' is deprecated for module xml. Please use " "display_name and url_name.") else: raise ValueError("Can't load a course without a 'url_name' " "(or 'name') set. Set url_name.") course_id = CourseDescriptor.make_id(org, course, url_name) system = ImportSystem( xmlstore=self, course_id=course_id, course_dir=course_dir, error_tracker=tracker, parent_tracker=self.parent_trackers[course_id], load_error_modules=self.load_error_modules, policy=policy, mixins=self.xblock_mixins, ) course_descriptor = system.process_xml(etree.tostring(course_data, encoding='unicode')) # If we fail to load the course, then skip the rest of the loading steps if isinstance(course_descriptor, ErrorDescriptor): return course_descriptor # 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. compute_inherited_metadata(course_descriptor) # now import all pieces of course_info which is expected to be stored # in <content_dir>/info or <content_dir>/info/<url_name> self.load_extra_content(system, course_descriptor, 'course_info', self.data_dir / course_dir / 'info', course_dir, url_name) # now import all static tabs which are expected to be stored in # in <content_dir>/tabs or <content_dir>/tabs/<url_name> self.load_extra_content(system, course_descriptor, 'static_tab', self.data_dir / course_dir / 'tabs', course_dir, url_name) self.load_extra_content(system, course_descriptor, 'custom_tag_template', self.data_dir / course_dir / 'custom_tags', course_dir, url_name) self.load_extra_content(system, course_descriptor, 'about', self.data_dir / course_dir / 'about', course_dir, url_name) log.debug('========> Done with course import from {0}'.format(course_dir)) return course_descriptor
def load_course(self, course_dir, course_ids, tracker): """ Load a course into this module store course_path: Course directory name returns a CourseDescriptor for the course """ log.debug("========> Starting course import from {0}".format(course_dir)) with open(self.data_dir / course_dir / "course.xml") as course_file: # VS[compat] # TODO (cpennington): Remove this once all fall 2012 courses have # been imported into the cms from xml course_file = StringIO(clean_out_mako_templating(course_file.read())) course_data = etree.parse(course_file, parser=edx_xml_parser).getroot() org = course_data.get("org") if org is None: msg = "No 'org' attribute set for course in {dir}. " "Using default 'edx'".format(dir=course_dir) log.warning(msg) tracker(msg) org = "edx" course = course_data.get("course") if course is None: msg = "No 'course' attribute set for course in {dir}." " Using default '{default}'".format( dir=course_dir, default=course_dir ) log.warning(msg) tracker(msg) course = course_dir url_name = course_data.get("url_name", course_data.get("slug")) policy_dir = None if url_name: policy_dir = self.data_dir / course_dir / "policies" / url_name policy_path = policy_dir / "policy.json" policy = self.load_policy(policy_path, tracker) # VS[compat]: remove once courses use the policy dirs. if policy == {}: old_policy_path = self.data_dir / course_dir / "policies" / "{0}.json".format(url_name) policy = self.load_policy(old_policy_path, tracker) else: policy = {} # VS[compat] : 'name' is deprecated, but support it for now... if course_data.get("name"): url_name = Location.clean(course_data.get("name")) tracker("'name' is deprecated for module xml. Please use " "display_name and url_name.") else: raise ValueError("Can't load a course without a 'url_name' " "(or 'name') set. Set url_name.") course_id = CourseDescriptor.make_id(org, course, url_name) if course_ids is not None and course_id not in course_ids: return None def get_policy(usage_id): """ Return the policy dictionary to be applied to the specified XBlock usage """ return policy.get(policy_key(usage_id), {}) services = {} if self.i18n_service: services["i18n"] = self.i18n_service system = ImportSystem( xmlstore=self, course_id=course_id, course_dir=course_dir, error_tracker=tracker, parent_tracker=self.parent_trackers[course_id], load_error_modules=self.load_error_modules, get_policy=get_policy, mixins=self.xblock_mixins, default_class=self.default_class, select=self.xblock_select, field_data=self.field_data, services=services, ) course_descriptor = system.process_xml(etree.tostring(course_data, encoding="unicode")) # If we fail to load the course, then skip the rest of the loading steps if isinstance(course_descriptor, ErrorDescriptor): return course_descriptor # 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. compute_inherited_metadata(course_descriptor) # now import all pieces of course_info which is expected to be stored # in <content_dir>/info or <content_dir>/info/<url_name> self.load_extra_content( system, course_descriptor, "course_info", self.data_dir / course_dir / "info", course_dir, url_name ) # now import all static tabs which are expected to be stored in # in <content_dir>/tabs or <content_dir>/tabs/<url_name> self.load_extra_content( system, course_descriptor, "static_tab", self.data_dir / course_dir / "tabs", course_dir, url_name ) self.load_extra_content( system, course_descriptor, "custom_tag_template", self.data_dir / course_dir / "custom_tags", course_dir, url_name, ) self.load_extra_content( system, course_descriptor, "about", self.data_dir / course_dir / "about", course_dir, url_name ) log.debug("========> Done with course import from {0}".format(course_dir)) return course_descriptor