def import_children(course, element, parent, parent_dpath): """ Create LearningResource instances for each element of an XML tree. Args: course (learningresources.models.Course): Course element (lxml.etree): XML element within xbundle parent (learningresources.models.LearningResource): Parent LearningResource parent_dpath (unicode): parent description path Returns: None """ # pylint: disable=too-many-locals title = element.attrib.get("display_name", MissingTitle.for_title_field) desc_path = title if desc_path == MissingTitle.for_title_field: desc_path = MissingTitle.for_desc_path_field mpath = etree.ElementTree(element).getpath(element) dpath = join_description_paths(parent_dpath, desc_path) resource = create_resource( course=course, parent=parent, resource_type=element.tag, title=title, content_xml=etree.tostring(element), mpath=mpath, url_name=element.attrib.get("url_name", None), dpath=dpath, ) # temp variable to store static assets for bulk insert static_assets_to_save = set() target = "/static/" if element.tag == "video": subname = get_video_sub(element) if subname != "": assets = StaticAsset.objects.filter( course__id=resource.course_id, asset=course_asset_basepath(course, subname), ) for asset in assets: static_assets_to_save.add((resource, asset)) else: # Recursively find all sub-elements, looking for anything which # refers to /static/. Then make the association between the # LearningResource and StaticAsset if the StaticAsset exists. # This is like doing soup.findAll("a") and checking for whether # "/static/" is in the href, which would work but also requires # more code to check for link, img, iframe, script, and others, # and within those, check for href or src existing. soup = BeautifulSoup(etree.tostring(element), 'lxml') for child in soup.findAll(): for _, val in child.attrs.items(): try: if val.startswith(target): path = val[len(target):] try: asset = StaticAsset.objects.get( course__id=resource.course_id, asset=course_asset_basepath(course, path), ) static_assets_to_save.add((resource, asset)) except StaticAsset.DoesNotExist: continue except AttributeError: continue # not a string # Bulk insert of static assets # Using this approach to avoid signals during the learning resource .save() # Each signal triggers a reindex of the learning resource that is useless # during import because all the learning resources are indexed in bulk at # the end of the import anyway ThroughModel = LearningResource.static_assets.through ThroughModel.objects.bulk_create([ ThroughModel(learningresource_id=resource.id, staticasset_id=asset.id) for resource, asset in static_assets_to_save ]) for child in element.getchildren(): if child.tag in DESCRIPTOR_TAGS: import_children(course, child, resource, dpath)
def import_children(course, element, parent, parent_dpath): """ Create LearningResource instances for each element of an XML tree. Args: course (learningresources.models.Course): Course element (lxml.etree): XML element within xbundle parent (learningresources.models.LearningResource): Parent LearningResource parent_dpath (unicode): parent description path Returns: None """ # pylint: disable=too-many-locals title = element.attrib.get("display_name", "MISSING") mpath = etree.ElementTree(element).getpath(element) dpath = join_description_paths(parent_dpath, title) resource = create_resource( course=course, parent=parent, resource_type=element.tag, title=title, content_xml=etree.tostring(element), mpath=mpath, url_name=element.attrib.get("url_name", None), dpath=dpath, ) target = "/static/" if element.tag == "video": subname = get_video_sub(element) if subname != "": assets = StaticAsset.objects.filter( course__id=resource.course_id, asset=course_asset_basepath(course, subname), ) for asset in assets: resource.static_assets.add(asset) else: # Recursively find all sub-elements, looking for anything which # refers to /static/. Then make the association between the # LearningResource and StaticAsset if the StaticAsset exists. # This is like doing soup.findAll("a") and checking for whether # "/static/" is in the href, which would work but also requires # more code to check for link, img, iframe, script, and others, # and within those, check for href or src existing. soup = BeautifulSoup(etree.tostring(element), 'lxml') for child in soup.findAll(): for _, val in child.attrs.items(): try: if val.startswith(target): path = val[len(target):] try: asset = StaticAsset.objects.get( course__id=resource.course_id, asset=course_asset_basepath(course, path), ) resource.static_assets.add(asset) except StaticAsset.DoesNotExist: continue except AttributeError: continue # not a string for child in element.getchildren(): if child.tag in DESCRIPTOR_TAGS: import_children(course, child, resource, dpath)
def import_children(course, element, parent, parent_dpath): """ Create LearningResource instances for each element of an XML tree. Args: course (learningresources.models.Course): Course element (lxml.etree): XML element within xbundle parent (learningresources.models.LearningResource): Parent LearningResource parent_dpath (unicode): parent description path Returns: None """ # pylint: disable=too-many-locals title = element.attrib.get( "display_name", MissingTitle.for_title_field) desc_path = title if desc_path == MissingTitle.for_title_field: desc_path = MissingTitle.for_desc_path_field mpath = etree.ElementTree(element).getpath(element) dpath = join_description_paths(parent_dpath, desc_path) resource = create_resource( course=course, parent=parent, resource_type=element.tag, title=title, content_xml=etree.tostring(element), mpath=mpath, url_name=element.attrib.get("url_name", None), dpath=dpath, ) # temp variable to store static assets for bulk insert static_assets_to_save = set() target = "/static/" if element.tag == "video": subname = get_video_sub(element) if subname != "": assets = StaticAsset.objects.filter( course__id=resource.course_id, asset=course_asset_basepath(course, subname), ) for asset in assets: static_assets_to_save.add((resource, asset)) else: # Recursively find all sub-elements, looking for anything which # refers to /static/. Then make the association between the # LearningResource and StaticAsset if the StaticAsset exists. # This is like doing soup.findAll("a") and checking for whether # "/static/" is in the href, which would work but also requires # more code to check for link, img, iframe, script, and others, # and within those, check for href or src existing. soup = BeautifulSoup(etree.tostring(element), 'lxml') for child in soup.findAll(): for _, val in child.attrs.items(): try: if val.startswith(target): path = val[len(target):] try: asset = StaticAsset.objects.get( course__id=resource.course_id, asset=course_asset_basepath(course, path), ) static_assets_to_save.add((resource, asset)) except StaticAsset.DoesNotExist: continue except AttributeError: continue # not a string # Bulk insert of static assets # Using this approach to avoid signals during the learning resource .save() # Each signal triggers a reindex of the learning resource that is useless # during import because all the learning resources are indexed in bulk at # the end of the import anyway ThroughModel = LearningResource.static_assets.through ThroughModel.objects.bulk_create( [ ThroughModel( learningresource_id=resource.id, staticasset_id=asset.id ) for resource, asset in static_assets_to_save ] ) for child in element.getchildren(): if child.tag in DESCRIPTOR_TAGS: import_children(course, child, resource, dpath)