def delete_topic(committer_id, topic_id, force_deletion=False): """Deletes the topic with the given topic_id. Args: committer_id: str. ID of the committer. topic_id: str. ID of the topic to be deleted. force_deletion: bool. If true, the topic and its history are fully deleted and are unrecoverable. Otherwise, the topic and all its history are marked as deleted, but the corresponding models are still retained in the datastore. This last option is the preferred one. Raises: ValueError: User does not have enough rights to delete a topic. """ topic_rights_model = topic_models.TopicRightsModel.get(topic_id) topic_rights_model.delete(committer_id, feconf.COMMIT_MESSAGE_TOPIC_DELETED, force_deletion=force_deletion) # Delete the summary of the topic (regardless of whether # force_deletion is True or not). delete_topic_summary(topic_id) topic_model = topic_models.TopicModel.get(topic_id) for subtopic in topic_model.subtopics: subtopic_page_services.delete_subtopic_page(committer_id, topic_id, subtopic['id']) topic_model.delete(committer_id, feconf.COMMIT_MESSAGE_TOPIC_DELETED, force_deletion=force_deletion) # This must come after the topic is retrieved. Otherwise the memcache # key will be reinstated. topic_memcache_key = topic_fetchers.get_topic_memcache_key(topic_id) memcache_services.delete(topic_memcache_key)
def _save_topic(committer_id, topic, commit_message, change_list): """Validates a topic and commits it to persistent storage. If successful, increments the version number of the incoming topic domain object by 1. Args: committer_id: str. ID of the given committer. topic: Topic. The topic domain object to be saved. commit_message: str. The commit message. change_list: list(TopicChange). List of changes applied to a topic. Raises: Exception: Received invalid change list. Exception: The topic model and the incoming topic domain object have different version numbers. """ if not change_list: raise Exception( 'Unexpected error: received an invalid change list when trying to ' 'save topic %s: %s' % (topic.id, change_list)) topic.validate() topic_model = topic_models.TopicModel.get(topic.id, strict=False) # Topic model cannot be None as topic is passed as parameter here and that # is only possible if a topic model with that topic id exists. Also this is # a private function and so it cannot be called independently with any # topic object. if topic.version > topic_model.version: raise Exception( 'Unexpected error: trying to update version %s of topic ' 'from version %s. Please reload the page and try again.' % (topic_model.version, topic.version)) elif topic.version < topic_model.version: raise Exception( 'Trying to update version %s of topic from version %s, ' 'which is too old. Please reload the page and try again.' % (topic_model.version, topic.version)) topic_model.description = topic.description topic_model.name = topic.name topic_model.canonical_story_references = [ reference.to_dict() for reference in topic.canonical_story_references ] topic_model.additional_story_references = [ reference.to_dict() for reference in topic.additional_story_references ] topic_model.uncategorized_skill_ids = topic.uncategorized_skill_ids topic_model.subtopics = [ subtopic.to_dict() for subtopic in topic.subtopics ] topic_model.subtopic_schema_version = topic.subtopic_schema_version topic_model.story_reference_schema_version = ( topic.story_reference_schema_version) topic_model.next_subtopic_id = topic.next_subtopic_id topic_model.language_code = topic.language_code change_dicts = [change.to_dict() for change in change_list] topic_model.commit(committer_id, commit_message, change_dicts) memcache_services.delete(topic_fetchers.get_topic_memcache_key(topic.id)) topic.version += 1