def convert_data_to_nodes(user, content_data, parent_node): """ Parse dict and create nodes accordingly """ try: root_mapping = {} parent_node = ContentNode.objects.get(pk=parent_node) sort_order = parent_node.children.count() + 1 existing_node_ids = ContentNode.objects.filter( parent_id=parent_node.pk).values_list('node_id', flat=True) with transaction.atomic(): for node_data in content_data: # Check if node id is already in the tree to avoid duplicates if node_data['node_id'] not in existing_node_ids: # Create the node new_node = create_node(node_data, parent_node, sort_order) # Create files associated with node map_files_to_node(user, new_node, node_data['files']) # Create questions associated with node create_exercises(user, new_node, node_data['questions']) sort_order += 1 # Track mapping between newly created node and node id root_mapping.update({node_data['node_id']: new_node.pk}) return root_mapping except KeyError as e: raise ObjectDoesNotExist("Error creating node: {0}".format(e.message))
def create_node_from_file(user, file_name, parent_node, sort_order): node_data = get_node_data_from_file(file_name) cur_node = ContentNode.objects.create( title=node_data['title'], tree_id=parent_node.tree_id, kind_id=node_data['kind'], node_id=node_data['node_id'], content_id=node_data['content_id'], description=node_data['description'], author=node_data['author'], aggregator=node_data.get('aggregator') or "", provider=node_data.get('provider') or "", license=node_data['license'], license_description=node_data['license_description'], copyright_holder=node_data['copyright_holder'] or "", parent=parent_node, extra_fields=node_data['extra_fields'], sort_order=sort_order, source_id=node_data['source_id'], source_domain=node_data['source_domain'], language_id=node_data.get('language'), role_visibility=node_data.get('role') or roles.LEARNER, ) # Create files associated with node map_files_to_node(user, cur_node, node_data['files']) # Create questions associated with node create_exercises(cur_node, node_data['questions']) return cur_node
def convert_data_to_nodes(user, content_data, parent_node): """ Parse dict and create nodes accordingly """ try: root_mapping = {} parent_node = ContentNode.objects.get(pk=parent_node) sort_order = parent_node.children.count() + 1 existing_node_ids = ContentNode.objects.filter(parent_id=parent_node.pk).values_list('node_id', flat=True) with transaction.atomic(): for node_data in content_data: # Check if node id is already in the tree to avoid duplicates if node_data['node_id'] not in existing_node_ids: # Create the node new_node = create_node(node_data, parent_node, sort_order) # Create files associated with node map_files_to_node(user, new_node, node_data['files']) # Create questions associated with node create_exercises(user, new_node, node_data['questions']) sort_order += 1 # Track mapping between newly created node and node id root_mapping.update({node_data['node_id']: new_node.pk}) return root_mapping except KeyError as e: raise ObjectDoesNotExist("Error creating node: {0}".format(e.message))
def test_internal_thumbnail(self): # Create exercise node (generated images are more predictable) node = ContentNode(title="Test Node", kind_id=content_kinds.VIDEO) node.save() file_data = [{ "preset": None, "filename": str(self.thumbnail_fobj), "language": "en", "size": self.thumbnail_fobj.file_size, }] map_files_to_node(self.user, node, file_data) self.assertTrue(isinstance(node.thumbnail_encoding, basestring)) thumbnail_data = json.loads(node.thumbnail_encoding) self.assertEqual(thumbnail_data['base64'], generated_base64encoding())
def convert_data_to_nodes(user, content_data, parent_node): """ Parse dict and create nodes accordingly """ try: root_mapping = {} parent_node = ContentNode.objects.get(pk=parent_node) sort_order = parent_node.children.count() + 1 existing_node_ids = ContentNode.objects.filter( parent_id=parent_node.pk).values_list('node_id', flat=True) with transaction.atomic(): for node_data in content_data: # Check if node id is already in the tree to avoid duplicates if node_data['node_id'] not in existing_node_ids: # Create the node new_node = create_node(node_data, parent_node, sort_order) # Create files associated with node map_files_to_node(user, new_node, node_data['files']) # Create questions associated exercise nodes create_exercises(user, new_node, node_data['questions']) sort_order += 1 # Create Slideshow slides (if slideshow kind) if node_data['kind'] == 'slideshow': extra_fields_unicode = node_data['extra_fields'] # Extra Fields comes as type<unicode> - convert it to a dict and get slideshow_data extra_fields_json = extra_fields_unicode.encode( "ascii", "ignore") extra_fields = json.loads(extra_fields_json) slides = create_slides( user, new_node, extra_fields.get('slideshow_data')) map_files_to_slideshow_slide_item( user, new_node, slides, node_data["files"]) # Track mapping between newly created node and node id root_mapping.update({node_data['node_id']: new_node.pk}) return root_mapping except KeyError as e: raise ObjectDoesNotExist("Error creating node: {0}".format(e.message))
def create_channel(channel_data, user): """ Set up channel """ # Set up initial channel channel, isNew = Channel.objects.get_or_create(id=channel_data['id']) # Add user as editor if channel is new or channel has no editors # Otherwise, check if user is an editor if isNew or channel.editors.count() == 0: channel.editors.add(user) elif user not in channel.editors.all(): raise SuspiciousOperation( "User is not authorized to edit this channel") extra_fields = channel_data.get('extra_fields') or {} if isinstance(extra_fields, basestring): extra_fields = json.loads(extra_fields) extra_fields.update({'ricecooker_version': channel.ricecooker_version}) channel.name = channel_data['name'] channel.description = channel_data['description'] channel.thumbnail = channel_data['thumbnail'] channel.deleted = False channel.source_id = channel_data.get('source_id') channel.source_domain = channel_data.get('source_domain') channel.source_url = channel_data.get( 'source_domain') if isNew else channel.source_url channel.ricecooker_version = channel_data.get('ricecooker_version') channel.language_id = channel_data.get('language') # older versions of ricecooker won't be sending this field. if 'tagline' in channel_data: channel.tagline = channel_data['tagline'] old_chef_tree = channel.chef_tree is_published = channel.main_tree is not None and channel.main_tree.published # Set up initial staging tree channel.chef_tree = ContentNode.objects.create( title=channel.name, kind_id=content_kinds.TOPIC, published=is_published, content_id=channel.id, node_id=channel.id, source_id=channel.source_id, source_domain=channel.source_domain, extra_fields=extra_fields, complete=True, ) files = channel_data.get("files") if files: map_files_to_node(user, channel.chef_tree, files) channel.chef_tree.save() channel.save() # Delete chef tree if it already exists if old_chef_tree and old_chef_tree != channel.staging_tree: # IMPORTANT: Do not remove this block, MPTT updating the deleted chefs block could hang the server with ContentNode.objects.disable_mptt_updates(): garbage_node = get_deleted_chefs_root() old_chef_tree.parent = garbage_node old_chef_tree.title = "Old chef tree for channel {}".format( channel.pk) old_chef_tree.save() return channel # Return new channel