def setUp(self) -> None: super(ExplorationOpportunitySummaryModelUnitTest, self).setUp() opportunity_models.ExplorationOpportunitySummaryModel( id='opportunity_id1', topic_id='topic_id1', topic_name='A topic', story_id='story_id1', story_title='A story title', chapter_title='A chapter title', content_count=20, incomplete_translation_language_codes=['hi', 'ar'], translation_counts={}, language_codes_needing_voice_artists=['en'], language_codes_with_assigned_voice_artists=[] ).put() opportunity_models.ExplorationOpportunitySummaryModel( id='opportunity_id2', topic_id='topic_id2', topic_name='A new topic', story_id='story_id2', story_title='A new story title', chapter_title='A new chapter title', content_count=120, incomplete_translation_language_codes=['hi'], translation_counts={}, language_codes_needing_voice_artists=['en'], language_codes_with_assigned_voice_artists=[] ).put()
def _generate_opportunities_related_to_topic( topic: topic_domain.Topic, stories_dict: Dict[str, story_domain.Story], exps_dict: Dict[str, exp_domain.Exploration] ) -> result.Result[ List[opportunity_models.ExplorationOpportunitySummaryModel], Exception ]: """Generate opportunities related to a topic. Args: topic: Topic. Topic for which to generate the opportunities. stories_dict: dict(str, Story). All stories in the datastore, keyed by their ID. exps_dict: dict(str, Exploration). All explorations in the datastore, keyed by their ID. Returns: dict(str, *). Metadata about the operation. Keys are: status: str. Whether the job succeeded or failed. job_result: JobRunResult. A detailed report of the status, including exception details if a failure occurred. models: list(ExplorationOpportunitySummaryModel). The models generated by the operation. """ try: story_ids = topic.get_canonical_story_ids() # type: ignore[no-untyped-call] existing_story_ids = ( set(stories_dict.keys()).intersection(story_ids)) exp_ids: List[str] = list(itertools.chain.from_iterable( stories_dict[story_id].story_contents.get_all_linked_exp_ids() for story_id in existing_story_ids)) existing_exp_ids = set(exps_dict.keys()).intersection(exp_ids) missing_story_ids = set(story_ids).difference(existing_story_ids) missing_exp_ids = set(exp_ids).difference(existing_exp_ids) if len(missing_exp_ids) > 0 or len(missing_story_ids) > 0: raise Exception( 'Failed to regenerate opportunities for topic id: %s, ' 'missing_exp_with_ids: %s, missing_story_with_ids: %s' % ( topic.id, list(missing_exp_ids), list(missing_story_ids))) exploration_opportunity_summary_list = [] stories = [ stories_dict[story_id] for story_id in existing_story_ids ] for story in stories: for exp_id in story.story_contents.get_all_linked_exp_ids(): exploration_opportunity_summary_list.append( opportunity_services.create_exp_opportunity_summary( # type: ignore[no-untyped-call] topic, story, exps_dict[exp_id])) exploration_opportunity_summary_model_list = [] with datastore_services.get_ndb_context(): for opportunity in exploration_opportunity_summary_list: model = ( opportunity_models.ExplorationOpportunitySummaryModel( id=opportunity.id, topic_id=opportunity.topic_id, topic_name=opportunity.topic_name, story_id=opportunity.story_id, story_title=opportunity.story_title, chapter_title=opportunity.chapter_title, content_count=opportunity.content_count, incomplete_translation_language_codes=( opportunity .incomplete_translation_language_codes ), translation_counts=opportunity.translation_counts, language_codes_needing_voice_artists=( opportunity .language_codes_needing_voice_artists ), language_codes_with_assigned_voice_artists=( opportunity .language_codes_with_assigned_voice_artists ) ) ) model.update_timestamps() exploration_opportunity_summary_model_list.append(model) return result.Ok(exploration_opportunity_summary_model_list) except Exception as e: return result.Err(e)