Exemple #1
0
 def test_unresolved_answers_count_for_multiple_states(self):
     with self.swap(jobs_registry, 'ALL_CONTINUOUS_COMPUTATION_MANAGERS',
                    self.ALL_CC_MANAGERS_FOR_TESTS):
         exp_1 = self._create_and_update_fake_exploration('eid1')
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']),
             self._get_default_dict_when_no_unresolved_answers(['eid1']))
         self._record_answer('a1', exp_1, exp_1.init_state_name)
         self._record_answer('a1', exp_1, self.STATE_2_NAME)
         self._record_answer('a2', exp_1, self.STATE_2_NAME)
         self._run_aggregator_job()
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']),
             {
                 'eid1': {
                     'frequency':
                     3,
                     'unresolved_answers': [{
                         'frequency': 1,
                         'answer': 'a1',
                         'state': exp_1.init_state_name
                     }, {
                         'frequency': 1,
                         'answer': 'a1',
                         'state': self.STATE_2_NAME
                     }, {
                         'frequency': 1,
                         'answer': 'a2',
                         'state': self.STATE_2_NAME
                     }]
                 }
             })
 def test_unresolved_answers_count_for_multiple_states(self):
     with self.swap(
         jobs_registry, 'ALL_CONTINUOUS_COMPUTATION_MANAGERS',
         self.ALL_CC_MANAGERS_FOR_TESTS):
         exp_1 = self._create_and_update_fake_exploration('eid1')
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']),
             self._get_default_dict_when_no_unresolved_answers(['eid1']))
         self._record_answer('a1', exp_1, exp_1.init_state_name)
         self._record_answer('a1', exp_1, self.STATE_2_NAME)
         self._record_answer('a2', exp_1, self.STATE_2_NAME)
         self._run_aggregator_job()
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']), {
                     'eid1': {
                         'frequency': 3,
                         'unresolved_answers': [{
                             'frequency': 1,
                             'answer': 'a1',
                             'state': exp_1.init_state_name
                         }, {
                             'frequency': 1,
                             'answer': 'a1',
                             'state': self.STATE_2_NAME
                         }, {
                             'frequency': 1,
                             'answer': 'a2',
                             'state': self.STATE_2_NAME
                         }]
                     }
                 })
 def test_unresolved_answers_for_multiple_explorations(self):
     exp_1 = self._create_and_update_fake_exploration('eid1')
     exp_2 = self._create_and_update_fake_exploration('eid2')
     exp_3 = self._create_and_update_fake_exploration('eid3')
     self.assertEquals(
         stats_services.get_exps_unresolved_answers_for_default_rule(
             ['eid1', 'eid2', 'eid3']),
         self._get_default_dict_when_no_unresolved_answers(
             ['eid1', 'eid2', 'eid3']))
     event_services.AnswerSubmissionEventHandler.record(
         'eid1', 1, exp_1.init_state_name, self.DEFAULT_RULESPEC_STR, 'a1')
     event_services.AnswerSubmissionEventHandler.record(
         'eid2', 1, exp_2.init_state_name, self.DEFAULT_RULESPEC_STR, 'a3')
     event_services.AnswerSubmissionEventHandler.record(
         'eid2', 1, exp_2.init_state_name, self.DEFAULT_RULESPEC_STR, 'a2')
     event_services.AnswerSubmissionEventHandler.record(
         'eid3', 1, exp_3.init_state_name, self.DEFAULT_RULESPEC_STR, 'a2')
     self.assertEquals(
         stats_services.get_exps_unresolved_answers_for_default_rule(
             ['eid1', 'eid2', 'eid3']), {
                 'eid1': {'count': 1, 'unresolved_answers': [
                     {'count': 1, 'value': 'a1',
                      'state': exp_1.init_state_name}
                 ]},
                 'eid2': {'count': 2, 'unresolved_answers': [
                     {'count': 1, 'value': 'a3',
                      'state': exp_2.init_state_name},
                     {'count': 1, 'value': 'a2',
                      'state': exp_2.init_state_name}
                 ]},
                 'eid3': {'count': 1, 'unresolved_answers': [
                     {'count': 1, 'value': 'a2',
                      'state': exp_3.init_state_name}
                 ]}
             })
 def test_unresolved_answers_count_for_non_default_rules(self):
     exp_1 = self._create_and_update_fake_exploration('eid1')
     self.assertEquals(
         stats_services.get_exps_unresolved_answers_for_default_rule(
             ['eid1']), self._get_default_dict_when_no_unresolved_answers(
                 ['eid1']))
     event_services.AnswerSubmissionEventHandler.record(
         'eid1', 1, exp_1.init_state_name, self.CLASSIFIER_RULESPEC_STR, 'a1'
     )
     event_services.AnswerSubmissionEventHandler.record(
         'eid1', 1, self.STATE_2_NAME, self.CLASSIFIER_RULESPEC_STR, 'a1')
     self.assertEquals(
         stats_services.get_exps_unresolved_answers_for_default_rule(
             ['eid1']), self._get_default_dict_when_no_unresolved_answers(
                 ['eid1']))
 def test_unresolved_answers_count_for_non_default_rules(self):
     with self.swap(
         jobs_registry, 'ALL_CONTINUOUS_COMPUTATION_MANAGERS',
         self.ALL_CC_MANAGERS_FOR_TESTS):
         exp_1 = self._create_and_update_fake_exploration('eid1')
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']),
             self._get_default_dict_when_no_unresolved_answers(['eid1']))
         self._record_answer(
             'a1', exp_1, exp_1.init_state_name,
             classification=exp_domain.STATISTICAL_CLASSIFICATION)
         self._record_answer(
             'a1', exp_1, self.STATE_2_NAME,
             classification=exp_domain.STATISTICAL_CLASSIFICATION)
         self._run_aggregator_job()
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']),
             self._get_default_dict_when_no_unresolved_answers(['eid1']))
Exemple #6
0
 def test_unresolved_answers_count_for_non_default_rules(self):
     with self.swap(jobs_registry, 'ALL_CONTINUOUS_COMPUTATION_MANAGERS',
                    self.ALL_CC_MANAGERS_FOR_TESTS):
         exp_1 = self._create_and_update_fake_exploration('eid1')
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']),
             self._get_default_dict_when_no_unresolved_answers(['eid1']))
         self._record_answer(
             'a1',
             exp_1,
             exp_1.init_state_name,
             classification=exp_domain.STATISTICAL_CLASSIFICATION)
         self._record_answer(
             'a1',
             exp_1,
             self.STATE_2_NAME,
             classification=exp_domain.STATISTICAL_CLASSIFICATION)
         self._run_aggregator_job()
         self.assertEqual(
             stats_services.get_exps_unresolved_answers_for_default_rule(
                 ['eid1']),
             self._get_default_dict_when_no_unresolved_answers(['eid1']))
Exemple #7
0
    def get(self):
        """Handles GET requests."""
        if self.user_id is None:
            raise self.PageNotFoundException

        def _get_intro_card_color(category):
            return (
                feconf.CATEGORIES_TO_COLORS[category] if
                category in feconf.CATEGORIES_TO_COLORS else
                feconf.DEFAULT_COLOR)

        def _round_average_ratings(rating):
            return round(rating, feconf.AVERAGE_RATINGS_DASHBOARD_PRECISION)

        exploration_ids_subscribed_to = (
            subscription_services.get_exploration_ids_subscribed_to(
                self.user_id))

        subscribed_exploration_summaries = filter(None, (
            exp_services.get_exploration_summaries_matching_ids(
                exploration_ids_subscribed_to)))
        subscribed_collection_summaries = filter(None, (
            collection_services.get_collection_summaries_matching_ids(
                subscription_services.get_collection_ids_subscribed_to(
                    self.user_id))))

        exp_summary_list = summary_services.get_displayable_exp_summary_dicts(
            subscribed_exploration_summaries)
        collection_summary_list = []

        feedback_thread_analytics = (
            feedback_services.get_thread_analytics_multi(
                exploration_ids_subscribed_to))

        unresolved_answers_dict = (
            stats_services.get_exps_unresolved_answers_for_default_rule(
                exploration_ids_subscribed_to))

        total_unresolved_answers = 0

        for ind, exploration in enumerate(exp_summary_list):
            exploration.update(feedback_thread_analytics[ind].to_dict())
            exploration.update({
                'num_unresolved_answers': (
                    unresolved_answers_dict[exploration['id']]['count']
                    if exploration['id'] in unresolved_answers_dict else 0
                ),
                'top_unresolved_answers': (
                    unresolved_answers_dict[exploration['id']]
                    ['unresolved_answers']
                    [:feconf.TOP_UNRESOLVED_ANSWERS_COUNT_DASHBOARD]
                )
            })
            total_unresolved_answers += exploration['num_unresolved_answers']

        exp_summary_list = sorted(
            exp_summary_list,
            key=lambda x: (x['num_open_threads'], x['last_updated_msec']),
            reverse=True)

        if (self.username in
                config_domain.WHITELISTED_COLLECTION_EDITOR_USERNAMES.value):
            for collection_summary in subscribed_collection_summaries:
                # TODO(sll): Reuse _get_displayable_collection_summary_dicts()
                # in summary_services, instead of replicating it like this.
                collection_summary_list.append({
                    'id': collection_summary.id,
                    'title': collection_summary.title,
                    'category': collection_summary.category,
                    'objective': collection_summary.objective,
                    'language_code': collection_summary.language_code,
                    'last_updated': utils.get_time_in_millisecs(
                        collection_summary.collection_model_last_updated),
                    'created_on': utils.get_time_in_millisecs(
                        collection_summary.collection_model_created_on),
                    'status': collection_summary.status,
                    'node_count': collection_summary.node_count,
                    'community_owned': collection_summary.community_owned,
                    'thumbnail_icon_url': (
                        utils.get_thumbnail_icon_url_for_category(
                            collection_summary.category)),
                    'thumbnail_bg_color': utils.get_hex_color_for_category(
                        collection_summary.category),
                })

        dashboard_stats = (
            user_jobs_continuous.UserStatsAggregator.get_dashboard_stats(
                self.user_id))
        dashboard_stats.update({
            'total_open_feedback': feedback_services.get_total_open_threads(
                feedback_thread_analytics),
            'total_unresolved_answers': total_unresolved_answers
        })
        if dashboard_stats and dashboard_stats.get('average_ratings'):
            dashboard_stats['average_ratings'] = (
                _round_average_ratings(dashboard_stats['average_ratings']))

        last_week_stats = (
            user_services.get_last_week_dashboard_stats(self.user_id))
        if last_week_stats and last_week_stats.get('average_ratings'):
            last_week_stats['average_ratings'] = (
                _round_average_ratings(last_week_stats['average_ratings']))

        self.values.update({
            'explorations_list': exp_summary_list,
            'collections_list': collection_summary_list,
            'dashboard_stats': dashboard_stats,
            'last_week_stats': last_week_stats
        })
        self.render_json(self.values)
Exemple #8
0
    def get(self):
        """Handles GET requests."""
        if self.user_id is None:
            raise self.PageNotFoundException

        def _get_intro_card_color(category):
            return (feconf.CATEGORIES_TO_COLORS[category] if category
                    in feconf.CATEGORIES_TO_COLORS else feconf.DEFAULT_COLOR)

        def _round_average_ratings(rating):
            return round(rating, feconf.AVERAGE_RATINGS_DASHBOARD_PRECISION)

        exploration_ids_subscribed_to = (
            subscription_services.get_exploration_ids_subscribed_to(
                self.user_id))

        subscribed_exploration_summaries = filter(
            None, (exp_services.get_exploration_summaries_matching_ids(
                exploration_ids_subscribed_to)))
        subscribed_collection_summaries = filter(
            None, (collection_services.get_collection_summaries_matching_ids(
                subscription_services.get_collection_ids_subscribed_to(
                    self.user_id))))

        exp_summary_list = summary_services.get_displayable_exp_summary_dicts(
            subscribed_exploration_summaries)
        collection_summary_list = []

        feedback_thread_analytics = (
            feedback_services.get_thread_analytics_multi(
                exploration_ids_subscribed_to))

        unresolved_answers_dict = (
            stats_services.get_exps_unresolved_answers_for_default_rule(
                exploration_ids_subscribed_to))

        total_unresolved_answers = 0

        for ind, exploration in enumerate(exp_summary_list):
            exploration.update(feedback_thread_analytics[ind].to_dict())
            exploration.update({
                'num_unresolved_answers':
                (unresolved_answers_dict[exploration['id']]['count']
                 if exploration['id'] in unresolved_answers_dict else 0),
                'top_unresolved_answers':
                (unresolved_answers_dict[
                    exploration['id']]['unresolved_answers']
                 [:feconf.TOP_UNRESOLVED_ANSWERS_COUNT_DASHBOARD])
            })
            total_unresolved_answers += exploration['num_unresolved_answers']

        exp_summary_list = sorted(
            exp_summary_list,
            key=lambda x: (x['num_open_threads'], x['last_updated_msec']),
            reverse=True)

        if (self.username in
                config_domain.WHITELISTED_COLLECTION_EDITOR_USERNAMES.value):
            for collection_summary in subscribed_collection_summaries:
                # TODO(sll): Reuse _get_displayable_collection_summary_dicts()
                # in summary_services, instead of replicating it like this.
                collection_summary_list.append({
                    'id':
                    collection_summary.id,
                    'title':
                    collection_summary.title,
                    'category':
                    collection_summary.category,
                    'objective':
                    collection_summary.objective,
                    'language_code':
                    collection_summary.language_code,
                    'last_updated':
                    utils.get_time_in_millisecs(
                        collection_summary.collection_model_last_updated),
                    'created_on':
                    utils.get_time_in_millisecs(
                        collection_summary.collection_model_created_on),
                    'status':
                    collection_summary.status,
                    'node_count':
                    collection_summary.node_count,
                    'community_owned':
                    collection_summary.community_owned,
                    'thumbnail_icon_url':
                    (utils.get_thumbnail_icon_url_for_category(
                        collection_summary.category)),
                    'thumbnail_bg_color':
                    utils.get_hex_color_for_category(
                        collection_summary.category),
                })

        dashboard_stats = (
            user_jobs_continuous.UserStatsAggregator.get_dashboard_stats(
                self.user_id))
        dashboard_stats.update({
            'total_open_feedback':
            feedback_services.get_total_open_threads(
                feedback_thread_analytics),
            'total_unresolved_answers':
            total_unresolved_answers
        })
        if dashboard_stats and dashboard_stats.get('average_ratings'):
            dashboard_stats['average_ratings'] = (_round_average_ratings(
                dashboard_stats['average_ratings']))

        last_week_stats = (user_services.get_last_week_dashboard_stats(
            self.user_id))
        if last_week_stats and last_week_stats.get('average_ratings'):
            last_week_stats['average_ratings'] = (_round_average_ratings(
                last_week_stats['average_ratings']))

        self.values.update({
            'explorations_list': exp_summary_list,
            'collections_list': collection_summary_list,
            'dashboard_stats': dashboard_stats,
            'last_week_stats': last_week_stats
        })
        self.render_json(self.values)