def get(self, story_id): """Populates the data on the individual story page.""" story = story_fetchers.get_story_by_id(story_id, strict=False) topic_id = story.corresponding_topic_id topic = topic_fetchers.get_topic_by_id(topic_id, strict=False) skill_ids = topic.get_all_skill_ids() skill_summaries = skill_services.get_multi_skill_summaries(skill_ids) skill_summary_dicts = [summary.to_dict() for summary in skill_summaries] classroom_url_fragment = ( classroom_services.get_classroom_url_fragment_for_topic_id( topic.id)) for story_reference in topic.canonical_story_references: if story_reference.story_id == story_id: story_is_published = story_reference.story_is_published self.values.update({ 'story': story.to_dict(), 'topic_name': topic.name, 'story_is_published': story_is_published, 'skill_summaries': skill_summary_dicts, 'topic_url_fragment': topic.url_fragment, 'classroom_url_fragment': classroom_url_fragment }) self.render_json(self.values)
def get(self, topic_id): """Populates the data on the individual topic page.""" topic = topic_fetchers.get_topic_by_id(topic_id, strict=False) if topic is None: raise self.PageNotFoundException( Exception('The topic with the given id doesn\'t exist.')) skill_id_to_description_dict, deleted_skill_ids = ( skill_services.get_descriptions_of_skills( topic.get_all_skill_ids())) topics = topic_fetchers.get_all_topics() grouped_skill_summary_dicts = {} skill_id_to_rubrics_dict = {} for topic_object in topics: skill_id_to_rubrics_dict_local, deleted_skill_ids = ( skill_services.get_rubrics_of_skills( topic_object.get_all_skill_ids())) skill_id_to_rubrics_dict.update(skill_id_to_rubrics_dict_local) if deleted_skill_ids: deleted_skills_string = ', '.join(deleted_skill_ids) logging.error( 'The deleted skills: %s are still present in topic with ' 'id %s' % (deleted_skills_string, topic_id)) if feconf.CAN_SEND_EMAILS: email_manager.send_mail_to_admin( 'Deleted skills present in topic', 'The deleted skills: %s are still present in ' 'topic with id %s' % (deleted_skills_string, topic_id)) skill_summaries = skill_services.get_multi_skill_summaries( topic_object.get_all_skill_ids()) skill_summary_dicts = [ summary.to_dict() for summary in skill_summaries ] grouped_skill_summary_dicts[ topic_object.name] = skill_summary_dicts classroom_url_fragment = ( classroom_services.get_classroom_url_fragment_for_topic_id( topic_id)) skill_question_count_dict = {} for skill_id in topic.get_all_skill_ids(): skill_question_count_dict[skill_id] = ( question_services.get_total_question_count_for_skill_ids( [skill_id])) self.values.update({ 'classroom_url_fragment': classroom_url_fragment, 'topic_dict': topic.to_dict(), 'grouped_skill_summary_dicts': grouped_skill_summary_dicts, 'skill_question_count_dict': skill_question_count_dict, 'skill_id_to_description_dict': skill_id_to_description_dict, 'skill_id_to_rubrics_dict': skill_id_to_rubrics_dict }) self.render_json(self.values)
def get_canonical_story_dicts( user_id: str, topic: topic_domain.Topic ) -> List[CannonicalStoryDict]: """Returns a list of canonical story dicts in the topic. Args: user_id: str. The ID of the user. topic: Topic. The topic domain object. Returns: list(dict). A list of canonical story dicts in the given topic. """ canonical_story_ids: List[str] = topic.get_canonical_story_ids( include_only_published=True) canonical_story_summaries: List[Optional[story_domain.StorySummary]] = [ story_fetchers.get_story_summary_by_id( canonical_story_id) for canonical_story_id in canonical_story_ids] canonical_story_dicts = [] for story_summary in canonical_story_summaries: # Ruling out the possibility of None for mypy type checking. assert story_summary is not None pending_and_all_nodes_in_story = ( story_fetchers.get_pending_and_all_nodes_in_story( user_id, story_summary.id)) all_nodes = pending_and_all_nodes_in_story['all_nodes'] pending_nodes = pending_and_all_nodes_in_story['pending_nodes'] pending_node_titles = [node.title for node in pending_nodes] completed_node_titles = utils.compute_list_difference( story_summary.node_titles, pending_node_titles) # Here, the return type of 'to_human_readable_dict()' method is # HumanReadableStorySummaryDict which does not have topic_url_fragment, # story_is_published and other keys. To overcome this missing keys # issues, we defined a CannonicalStoryDict and assigned it to the # `story_summary_dict`. Due this a conflict in type assignment is # raised which cause MyPy to throw `Incompatible types in assignment` # error. Thus to avoid error, we used ignore here. story_summary_dict: CannonicalStoryDict = ( story_summary.to_human_readable_dict() # type: ignore[assignment] ) story_summary_dict['topic_url_fragment'] = topic.url_fragment story_summary_dict['classroom_url_fragment'] = ( classroom_services.get_classroom_url_fragment_for_topic_id( topic.id)) story_summary_dict['story_is_published'] = True story_summary_dict['completed_node_titles'] = completed_node_titles story_summary_dict['all_node_dicts'] = [ node.to_dict() for node in all_nodes] canonical_story_dicts.append(story_summary_dict) return canonical_story_dicts
def test_get_classroom_url_fragment_for_topic_id(self): topic_id = topic_services.get_new_topic_id() config_services.set_property( self.user_id_admin, 'classroom_pages_data', [{ 'name': 'math', 'url_fragment': 'math-one', 'topic_ids': [topic_id], 'course_details': '', 'topic_list_intro': '' }]) classroom_url_fragment = ( classroom_services.get_classroom_url_fragment_for_topic_id( topic_id)) self.assertEqual(classroom_url_fragment, 'math-one')
def test_return_default_if_associated_classroom_is_not_found(self): topic_id = topic_services.get_new_topic_id() config_services.set_property( self.user_id_admin, 'classroom_pages_data', [{ 'name': 'math', 'url_fragment': 'math-two', 'topic_ids': [], 'course_details': '', 'topic_list_intro': '' }]) classroom_url_fragment = ( classroom_services.get_classroom_url_fragment_for_topic_id( topic_id)) self.assertNotEqual(classroom_url_fragment, 'math-two') self.assertEqual( classroom_url_fragment, constants.CLASSROOM_URL_FRAGMENT_FOR_UNATTACHED_TOPICS)
def get_canonical_story_dicts(user_id, topic): """Returns a list of canonical story dicts in the topic. Args: user_id: str. The ID of the user. topic: Topic. The topic domain object. Returns: list(dict). A list of canonical story dicts in the given topic. """ canonical_story_ids = topic.get_canonical_story_ids( include_only_published=True) canonical_story_summaries = [ story_fetchers.get_story_summary_by_id(canonical_story_id) for canonical_story_id in canonical_story_ids ] canonical_story_dicts = [] for story_summary in canonical_story_summaries: pending_and_all_nodes_in_story = ( story_fetchers.get_pending_and_all_nodes_in_story( user_id, story_summary.id)) all_nodes = pending_and_all_nodes_in_story['all_nodes'] pending_nodes = pending_and_all_nodes_in_story['pending_nodes'] pending_node_titles = [node.title for node in pending_nodes] completed_node_titles = utils.compute_list_difference( story_summary.node_titles, pending_node_titles) story_summary_dict = story_summary.to_human_readable_dict() story_summary_dict['topic_url_fragment'] = topic.url_fragment story_summary_dict['classroom_url_fragment'] = ( classroom_services.get_classroom_url_fragment_for_topic_id( topic.id)) story_summary_dict['story_is_published'] = True story_summary_dict['completed_node_titles'] = completed_node_titles story_summary_dict['all_node_dicts'] = [ node.to_dict() for node in all_nodes ] canonical_story_dicts.append(story_summary_dict) return canonical_story_dicts