def get(self): """Handles GET requests.""" if self.user_id is None: raise self.PageNotFoundException subscribed_summaries = ( exp_services.get_exploration_summaries_matching_ids( subscription_services.get_exploration_ids_subscribed_to( self.user_id))) def _get_intro_card_color(category): return ( feconf.CATEGORIES_TO_COLORS[category] if category in feconf.CATEGORIES_TO_COLORS else feconf.DEFAULT_COLOR) explorations_list = [] for exp_summary in subscribed_summaries: if exp_summary is None: continue feedback_thread_analytics = feedback_services.get_thread_analytics( exp_summary.id) explorations_list.append({ 'id': exp_summary.id, 'title': exp_summary.title, 'category': exp_summary.category, 'objective': exp_summary.objective, 'language_code': exp_summary.language_code, 'last_updated': utils.get_time_in_millisecs( exp_summary.exploration_model_last_updated), 'created_on': utils.get_time_in_millisecs( exp_summary.exploration_model_created_on), 'status': exp_summary.status, 'community_owned': exp_summary.community_owned, 'is_editable': True, 'thumbnail_icon_url': ( utils.get_thumbnail_icon_url_for_category( exp_summary.category)), 'thumbnail_bg_color': utils.get_hex_color_for_category( exp_summary.category), 'ratings': exp_summary.ratings, 'num_open_threads': ( feedback_thread_analytics.num_open_threads), 'num_total_threads': ( feedback_thread_analytics.num_total_threads), }) explorations_list = sorted( explorations_list, key=lambda x: (x['num_open_threads'], x['last_updated']), reverse=True) self.values.update({ 'explorations_list': explorations_list, }) self.render_json(self.values)
def _get_displayable_exp_summary_dicts( exploration_summaries, include_contributors=True): """Given a list of exploration summary domain objects, returns a list, with the same number of elements, of the corresponding human-readable exploration summary dicts. If include_contributors is False, the resulting dicts will not have a 'human_readable_contributors_summary' attribute. This assumes that all the exploration summary domain objects passed in are valid (i.e., none of them are None). """ exploration_ids = [ exploration_summary.id for exploration_summary in exploration_summaries] view_counts = ( stats_jobs_continuous.StatisticsAggregator.get_views_multi( exploration_ids)) displayable_exp_summaries = [] for ind, exploration_summary in enumerate(exploration_summaries): if not exploration_summary: continue summary_dict = { 'id': exploration_summary.id, 'title': exploration_summary.title, 'activity_type': rights_manager.ACTIVITY_TYPE_EXPLORATION, 'category': exploration_summary.category, 'objective': exploration_summary.objective, 'language_code': exploration_summary.language_code, 'last_updated_msec': utils.get_time_in_millisecs( exploration_summary.exploration_model_last_updated ), 'status': exploration_summary.status, 'ratings': exploration_summary.ratings, 'community_owned': exploration_summary.community_owned, 'tags': exploration_summary.tags, 'thumbnail_icon_url': utils.get_thumbnail_icon_url_for_category( exploration_summary.category), 'thumbnail_bg_color': utils.get_hex_color_for_category( exploration_summary.category), 'num_views': view_counts[ind], } if include_contributors: summary_dict['human_readable_contributors_summary'] = ( get_human_readable_contributors_summary( exploration_summary.contributors_summary)) displayable_exp_summaries.append(summary_dict) return displayable_exp_summaries
def _get_displayable_collection_summary_dicts(collection_summaries): """Gets a summary of collections in human readable form. Args: collection_summaries: list(CollectionSummary). List of collection summary domain object. Return: list(dict). A list of exploration summary dicts in human readable form. Example: [ { 'category': u'A category', 'community_owned': False, 'id': 'eid2', 'language_code': 'en', 'num_views': 0, 'objective': u'An objective', 'status': 'public', 'tags': [], 'thumbnail_bg_color': '#a33f40', 'thumbnail_icon_url': self.get_static_asset_url( '/images/subjects/Lightbulb.svg'), 'title': u'Exploration 2 Albert title', }, ] """ displayable_collection_summaries = [] for collection_summary in collection_summaries: if collection_summary and collection_summary.status != ( rights_manager.ACTIVITY_STATUS_PRIVATE): displayable_collection_summaries.append({ 'id': collection_summary.id, 'title': collection_summary.title, 'category': collection_summary.category, 'activity_type': feconf.ACTIVITY_TYPE_COLLECTION, 'objective': collection_summary.objective, 'language_code': collection_summary.language_code, 'tags': collection_summary.tags, 'node_count': collection_summary.node_count, 'last_updated_msec': utils.get_time_in_millisecs( collection_summary.collection_model_last_updated), '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)}) return displayable_collection_summaries
def get(self): """Handles GET requests.""" # TODO(sll): Figure out what to do about explorations in categories # other than those explicitly listed. query_string = self.request.get('q') search_cursor = self.request.get('cursor', None) exp_summaries_list, search_cursor = ( exp_services.get_exploration_summaries_matching_query( query_string, cursor=search_cursor)) explorations_list = [{ 'id': exp_summary.id, 'title': exp_summary.title, 'category': exp_summary.category, 'objective': exp_summary.objective, 'language_code': exp_summary.language_code, 'last_updated_msec': utils.get_time_in_millisecs( exp_summary.exploration_model_last_updated), 'status': exp_summary.status, 'ratings': exp_summary.ratings, 'community_owned': exp_summary.community_owned, # TODO(sll): Replace these with per-category thumbnails. 'thumbnail_icon_url': utils.get_thumbnail_icon_url_for_category( exp_summary.category), 'thumbnail_bg_color': utils.get_hex_color_for_category( exp_summary.category), } for exp_summary in exp_summaries_list] if len(explorations_list) == feconf.DEFAULT_QUERY_LIMIT: logging.error( '%s explorations were fetched to load the gallery page. ' 'You may be running up against the default query limits.' % feconf.DEFAULT_QUERY_LIMIT) preferred_language_codes = [feconf.DEFAULT_LANGUAGE_CODE] if self.user_id: user_settings = user_services.get_user_settings(self.user_id) preferred_language_codes = user_settings.preferred_language_codes self.values.update({ 'explorations_list': explorations_list, 'preferred_language_codes': preferred_language_codes, 'search_cursor': search_cursor, }) self.render_json(self.values)
def get_displayable_exp_summary_dicts_matching_ids(exploration_ids): """Given a list of exploration ids, filters the list for explorations that are currently non-private and not deleted, and returns a list of dicts of the corresponding exploration summaries. Please use this function when needing summary information to display on exploration summary tiles in the frontend. """ displayable_exp_summaries = [] exploration_summaries = ( exp_services.get_exploration_summaries_matching_ids(exploration_ids)) view_counts = ( stats_jobs_continuous.StatisticsAggregator.get_views_multi( exploration_ids)) for ind, exploration_summary in enumerate(exploration_summaries): if exploration_summary and exploration_summary.status != ( rights_manager.ACTIVITY_STATUS_PRIVATE): displayable_exp_summaries.append({ 'id': exploration_summary.id, 'title': exploration_summary.title, 'category': exploration_summary.category, 'objective': exploration_summary.objective, 'language_code': exploration_summary.language_code, 'last_updated_msec': utils.get_time_in_millisecs( exploration_summary.exploration_model_last_updated ), 'status': exploration_summary.status, 'ratings': exploration_summary.ratings, 'community_owned': exploration_summary.community_owned, 'human_readable_contributors_summary': get_human_readable_contributors_summary( exploration_summary.contributors_summary), 'tags': exploration_summary.tags, 'thumbnail_icon_url': utils.get_thumbnail_icon_url_for_category( exploration_summary.category), 'thumbnail_bg_color': utils.get_hex_color_for_category( exploration_summary.category), 'num_views': view_counts[ind], }) return displayable_exp_summaries
def _get_displayable_collection_summary_dicts(collection_summaries): displayable_collection_summaries = [] for collection_summary in collection_summaries: if collection_summary and collection_summary.status != ( rights_manager.ACTIVITY_STATUS_PRIVATE): displayable_collection_summaries.append({ 'id': collection_summary.id, 'title': collection_summary.title, 'category': collection_summary.category, 'activity_type': rights_manager.ACTIVITY_TYPE_COLLECTION, 'objective': collection_summary.objective, 'language_code': collection_summary.language_code, 'tags': collection_summary.tags, 'node_count': collection_summary.node_count, 'last_updated_msec': utils.get_time_in_millisecs( collection_summary.collection_model_last_updated), '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)}) return displayable_collection_summaries
def get(self): """Handles GET requests.""" try: exp_ids = json.loads(self.request.get('stringified_exp_ids')) except Exception: raise self.PageNotFoundException if (not isinstance(exp_ids, list) or not all([ isinstance(exp_id, basestring) for exp_id in exp_ids])): raise self.PageNotFoundException exp_summaries = exp_services.get_exploration_summaries_matching_ids( exp_ids) self.values.update({ 'summaries': [(None if exp_summary is None else { 'id': exp_summary.id, 'title': exp_summary.title, 'category': exp_summary.category, 'objective': exp_summary.objective, 'language_code': exp_summary.language_code, 'last_updated': utils.get_time_in_millisecs( exp_summary.exploration_model_last_updated), 'status': exp_summary.status, 'ratings': exp_summary.ratings, 'community_owned': exp_summary.community_owned, 'contributor_names': user_services.get_human_readable_user_ids( exp_summary.contributor_ids), 'tags': exp_summary.tags, 'thumbnail_icon_url': ( utils.get_thumbnail_icon_url_for_category( exp_summary.category)), 'thumbnail_bg_color': utils.get_hex_color_for_category( exp_summary.category), }) for exp_summary in exp_summaries] }) self.render_json(self.values)
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) # We need to do the filtering because some activities that were # originally subscribed to may have been deleted since. subscribed_exploration_summaries = [ summary for summary in exp_services.get_exploration_summaries_matching_ids( subscription_services.get_exploration_ids_subscribed_to( self.user_id)) if summary is not None] subscribed_collection_summaries = [ summary for summary in collection_services.get_collection_summaries_matching_ids( subscription_services.get_collection_ids_subscribed_to( self.user_id)) if summary is not None] exploration_ids_subscribed_to = [ summary.id for summary in subscribed_exploration_summaries] exp_summary_dicts = summary_services.get_displayable_exp_summary_dicts( subscribed_exploration_summaries) collection_summary_dicts = [] feedback_thread_analytics = ( feedback_services.get_thread_analytics_multi( exploration_ids_subscribed_to)) # TODO(bhenning): Update this to use unresolved answers from # stats_services once the training interface is enabled and it's cheaper # to retrieve top answers from stats_services. for ind, exploration in enumerate(exp_summary_dicts): exploration.update(feedback_thread_analytics[ind].to_dict()) exp_summary_dicts = sorted( exp_summary_dicts, 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_dicts.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) }) 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'])) subscriber_ids = subscription_services.get_all_subscribers_of_creator( self.user_id) subscribers_settings = user_services.get_users_settings(subscriber_ids) subscribers_list = [] for index, subscriber_settings in enumerate(subscribers_settings): subscriber_summary = { 'subscriber_picture_data_url': ( subscriber_settings.profile_picture_data_url), 'subscriber_username': subscriber_settings.username, 'subscriber_impact': ( user_services.get_user_impact_score(subscriber_ids[index])) } subscribers_list.append(subscriber_summary) self.values.update({ 'explorations_list': exp_summary_dicts, 'collections_list': collection_summary_dicts, 'dashboard_stats': dashboard_stats, 'last_week_stats': last_week_stats, 'subscribers_list': subscribers_list }) self.render_json(self.values)
def get(self, collection_id): """Populates the data on the individual collection page.""" try: collection = collection_services.get_collection_by_id( collection_id) except Exception as e: raise self.PageNotFoundException(e) exp_ids = collection.exploration_ids exp_summaries = ( exp_services.get_exploration_summaries_matching_ids(exp_ids)) exp_summaries_dict = { exp_id: exp_summaries[ind] for (ind, exp_id) in enumerate(exp_ids) } # TODO(bhenning): Users should not be recommended explorations they # have completed outside the context of a collection. next_exploration_ids = None completed_exploration_ids = None if self.user_id: completed_exploration_ids = ( collection_services.get_completed_exploration_ids( self.user_id, collection_id)) next_exploration_ids = collection.get_next_exploration_ids( completed_exploration_ids) else: # If the user is not logged in or they have not completed any of # the explorations yet within the context of this collection, # recommend the initial explorations. next_exploration_ids = collection.init_exploration_ids completed_exploration_ids = [] collection_dict = collection.to_dict() collection_dict['next_exploration_ids'] = next_exploration_ids collection_dict['completed_exploration_ids'] = ( completed_exploration_ids) # Insert an 'exploration' dict into each collection node, where the # dict includes meta information about the exploration (ID and title). for collection_node in collection_dict['nodes']: summary = exp_summaries_dict.get(collection_node['exploration_id']) collection_node['exploration'] = { 'id': collection_node['exploration_id'], 'title': summary.title if summary else None, 'category': summary.category if summary else None, 'objective': summary.objective if summary else None, 'ratings': summary.ratings if summary else None, 'last_updated_msec': utils.get_time_in_millisecs( summary.exploration_model_last_updated ) if summary else None, 'thumbnail_icon_url': utils.get_thumbnail_icon_url_for_category( summary.category), 'thumbnail_bg_color': utils.get_hex_color_for_category( summary.category), } self.values.update({ 'can_edit': ( self.user_id and rights_manager.Actor(self.user_id).can_edit( rights_manager.ACTIVITY_TYPE_COLLECTION, collection_id)), 'collection': collection_dict, 'info_card_image_url': utils.get_info_card_url_for_category( collection.category), 'is_logged_in': bool(self.user_id), 'session_id': utils.generate_new_session_id(), }) self.render_json(self.values)
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_count_for_default_rule( exploration_ids_subscribed_to)) 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']] if exploration['id'] in unresolved_answers_dict else 0 ) }) 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, '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) }) 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)
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) 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)))) explorations_list = summary_services.get_displayable_exp_summary_dicts( subscribed_exploration_summaries) collections_list = [] feedback_thread_analytics = ( feedback_services.get_thread_analytics_multi( exploration_ids_subscribed_to)) for ind, exploration in enumerate(explorations_list): exploration.update(feedback_thread_analytics[ind].to_dict()) explorations_list = sorted( explorations_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. collections_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, '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), }) self.values.update({ 'explorations_list': explorations_list, 'collections_list': collections_list, 'dashboard_stats': user_services.get_user_dashboard_stats( self.user_id) }) self.render_json(self.values)
def get(self): """Handles GET requests.""" def _round_average_ratings(rating): """Returns the rounded average rating to display on the creator dashboard. Args: rating: float. The rating of the lesson. Returns: float. The rounded average value of rating. """ return python_utils.ROUND( rating, feconf.AVERAGE_RATINGS_DASHBOARD_PRECISION) subscribed_exploration_summaries = ( exp_fetchers.get_exploration_summaries_subscribed_to(self.user_id)) subscribed_collection_summaries = ( collection_services.get_collection_summaries_subscribed_to( self.user_id)) exploration_ids_subscribed_to = [ summary.id for summary in subscribed_exploration_summaries ] exp_summary_dicts = summary_services.get_displayable_exp_summary_dicts( subscribed_exploration_summaries) collection_summary_dicts = [] feedback_thread_analytics = ( feedback_services.get_thread_analytics_multi( exploration_ids_subscribed_to)) # TODO(bhenning): Update this to use unresolved answers from # stats_services once the training interface is enabled and it's cheaper # to retrieve top answers from stats_services. for ind, exploration in enumerate(exp_summary_dicts): exploration.update(feedback_thread_analytics[ind].to_dict()) exp_summary_dicts = sorted( exp_summary_dicts, key=lambda x: (x['num_open_threads'], x['last_updated_msec']), reverse=True) topic_summaries = topic_fetchers.get_all_topic_summaries() topic_summary_dicts = [ summary.to_dict() for summary in topic_summaries ] if role_services.ACTION_CREATE_COLLECTION in self.user.actions: 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_dicts.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_msec': 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_services.get_dashboard_stats(self.user_id) dashboard_stats.update({ 'total_open_feedback': feedback_services.get_total_open_threads(feedback_thread_analytics) }) 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 len(list(last_week_stats.keys())) != 1: logging.exception( '\'last_week_stats\' should contain only one key-value pair' ' denoting last week dashboard stats of the user keyed by a' ' datetime string.') last_week_stats = None if last_week_stats: # 'last_week_stats' is a dict with only one key-value pair denoting # last week dashboard stats of the user keyed by a datetime string. datetime_of_stats = list(last_week_stats.keys())[0] last_week_stats_average_ratings = (list( last_week_stats.values())[0].get('average_ratings')) if last_week_stats_average_ratings: last_week_stats[datetime_of_stats]['average_ratings'] = ( _round_average_ratings(last_week_stats_average_ratings)) subscriber_ids = subscription_services.get_all_subscribers_of_creator( self.user_id) subscribers_settings = user_services.get_users_settings(subscriber_ids) subscribers_list = [] for index, subscriber_settings in enumerate(subscribers_settings): subscriber_summary = { 'subscriber_picture_data_url': (subscriber_settings.profile_picture_data_url), 'subscriber_username': subscriber_settings.username, 'subscriber_impact': (user_services.get_user_impact_score(subscriber_ids[index])) } subscribers_list.append(subscriber_summary) user_settings = user_services.get_user_settings(self.user_id, strict=False) creator_dashboard_display_pref = ( user_settings.creator_dashboard_display_pref) suggestions_created_by_user = suggestion_services.query_suggestions([ ('author_id', self.user_id), ('suggestion_type', feconf.SUGGESTION_TYPE_EDIT_STATE_CONTENT) ]) suggestions_which_can_be_reviewed = ( suggestion_services. get_all_suggestions_that_can_be_reviewed_by_user(self.user_id)) for s in suggestions_created_by_user: s.populate_old_value_of_change() for s in suggestions_which_can_be_reviewed: s.populate_old_value_of_change() suggestion_dicts_created_by_user = ([ s.to_dict() for s in suggestions_created_by_user ]) suggestion_dicts_which_can_be_reviewed = ([ s.to_dict() for s in suggestions_which_can_be_reviewed ]) ids_of_suggestions_created_by_user = ([ s['suggestion_id'] for s in suggestion_dicts_created_by_user ]) ids_of_suggestions_which_can_be_reviewed = ([ s['suggestion_id'] for s in suggestion_dicts_which_can_be_reviewed ]) threads_linked_to_suggestions_by_user = ([ t.to_dict() for t in feedback_services.get_multiple_threads( ids_of_suggestions_created_by_user) ]) threads_linked_to_suggestions_which_can_be_reviewed = ([ t.to_dict() for t in feedback_services.get_multiple_threads( ids_of_suggestions_which_can_be_reviewed) ]) self.values.update({ 'explorations_list': exp_summary_dicts, 'collections_list': collection_summary_dicts, 'dashboard_stats': dashboard_stats, 'last_week_stats': last_week_stats, 'subscribers_list': subscribers_list, 'display_preference': creator_dashboard_display_pref, 'threads_for_created_suggestions_list': (threads_linked_to_suggestions_by_user), 'threads_for_suggestions_to_review_list': (threads_linked_to_suggestions_which_can_be_reviewed), 'created_suggestions_list': suggestion_dicts_created_by_user, 'suggestions_to_review_list': (suggestion_dicts_which_can_be_reviewed), 'topic_summary_dicts': topic_summary_dicts }) self.render_json(self.values)
def get(self): """Handles GET requests.""" def _get_intro_card_color(category): return (constants.CATEGORIES_TO_COLORS[category] if category in constants.CATEGORIES_TO_COLORS else constants.DEFAULT_COLOR) def _round_average_ratings(rating): return round(rating, feconf.AVERAGE_RATINGS_DASHBOARD_PRECISION) # We need to do the filtering because some activities that were # originally subscribed to may have been deleted since. subscribed_exploration_summaries = [ summary for summary in exp_services.get_exploration_summaries_matching_ids( subscription_services.get_exploration_ids_subscribed_to( self.user_id)) if summary is not None ] subscribed_collection_summaries = [ summary for summary in collection_services.get_collection_summaries_matching_ids( subscription_services.get_collection_ids_subscribed_to( self.user_id)) if summary is not None ] exploration_ids_subscribed_to = [ summary.id for summary in subscribed_exploration_summaries ] exp_summary_dicts = summary_services.get_displayable_exp_summary_dicts( subscribed_exploration_summaries) collection_summary_dicts = [] feedback_thread_analytics = ( feedback_services.get_thread_analytics_multi( exploration_ids_subscribed_to)) # TODO(bhenning): Update this to use unresolved answers from # stats_services once the training interface is enabled and it's cheaper # to retrieve top answers from stats_services. for ind, exploration in enumerate(exp_summary_dicts): exploration.update(feedback_thread_analytics[ind].to_dict()) exp_summary_dicts = sorted( exp_summary_dicts, key=lambda x: (x['num_open_threads'], x['last_updated_msec']), reverse=True) if feconf.ENABLE_NEW_STRUCTURES: topic_summaries = topic_services.get_all_topic_summaries() topic_summary_dicts = [ summary.to_dict() for summary in topic_summaries ] if role_services.ACTION_CREATE_COLLECTION in self.user.actions: 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_dicts.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) }) 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'])) subscriber_ids = subscription_services.get_all_subscribers_of_creator( self.user_id) subscribers_settings = user_services.get_users_settings(subscriber_ids) subscribers_list = [] for index, subscriber_settings in enumerate(subscribers_settings): subscriber_summary = { 'subscriber_picture_data_url': (subscriber_settings.profile_picture_data_url), 'subscriber_username': subscriber_settings.username, 'subscriber_impact': (user_services.get_user_impact_score(subscriber_ids[index])) } subscribers_list.append(subscriber_summary) user_settings = user_services.get_user_settings(self.user_id, strict=False) creator_dashboard_display_pref = ( user_settings.creator_dashboard_display_pref) suggestions_created_by_user = suggestion_services.query_suggestions([ ('author_id', self.user_id), ('suggestion_type', suggestion_models.SUGGESTION_TYPE_EDIT_STATE_CONTENT) ]) suggestions_which_can_be_reviewed = ( suggestion_services. get_all_suggestions_that_can_be_reviewed_by_user(self.user_id)) for s in suggestions_created_by_user: s.populate_old_value_of_change() for s in suggestions_which_can_be_reviewed: s.populate_old_value_of_change() suggestion_dicts_created_by_user = ([ s.to_dict() for s in suggestions_created_by_user ]) suggestion_dicts_which_can_be_reviewed = ([ s.to_dict() for s in suggestions_which_can_be_reviewed ]) ids_of_suggestions_created_by_user = ([ s['suggestion_id'] for s in suggestion_dicts_created_by_user ]) ids_of_suggestions_which_can_be_reviewed = ([ s['suggestion_id'] for s in suggestion_dicts_which_can_be_reviewed ]) threads_linked_to_suggestions_by_user = ([ t.to_dict() for t in feedback_services.get_multiple_threads( ids_of_suggestions_created_by_user) ]) threads_linked_to_suggestions_which_can_be_reviewed = ([ t.to_dict() for t in feedback_services.get_multiple_threads( ids_of_suggestions_which_can_be_reviewed) ]) self.values.update({ 'explorations_list': exp_summary_dicts, 'collections_list': collection_summary_dicts, 'dashboard_stats': dashboard_stats, 'last_week_stats': last_week_stats, 'subscribers_list': subscribers_list, 'display_preference': creator_dashboard_display_pref, 'threads_for_created_suggestions_list': (threads_linked_to_suggestions_by_user), 'threads_for_suggestions_to_review_list': (threads_linked_to_suggestions_which_can_be_reviewed), 'created_suggestions_list': suggestion_dicts_created_by_user, 'suggestions_to_review_list': suggestion_dicts_which_can_be_reviewed }) if feconf.ENABLE_NEW_STRUCTURES: self.values.update({'topic_summary_dicts': topic_summary_dicts}) self.render_json(self.values)
def get_displayable_exp_summary_dicts(exploration_summaries): """Gets a summary of explorations in human readable form. Given a list of exploration summary domain objects, returns a list, with the same number of elements, of the corresponding human-readable exploration summary dicts. This assumes that all the exploration summary domain objects passed in are valid (i.e., none of them are None). Args: exploration_summaries: list(ExplorationSummary). List of exploration summary objects. Returns: list(dict). A list of exploration summary dicts in human readable form. Example: [ { 'category': u'A category', 'community_owned': False, 'id': 'eid2', 'language_code': 'en', 'num_views': 0, 'objective': u'An objective', 'status': 'public', 'tags': [], 'thumbnail_bg_color': '#a33f40', 'thumbnail_icon_url': self.get_static_asset_url( '/images/subjects/Lightbulb.svg'), 'title': u'Exploration 2 Albert title', }, ] """ exp_version_references = [ exp_domain.ExpVersionReference(exp_summary.id, exp_summary.version) for exp_summary in exploration_summaries ] exp_stats_list = stats_services.get_exploration_stats_multi( exp_version_references) view_counts = [exp_stats.num_starts for exp_stats in exp_stats_list] displayable_exp_summaries = [] for ind, exploration_summary in enumerate(exploration_summaries): if exploration_summary: summary_dict = { 'id': exploration_summary.id, 'title': exploration_summary.title, 'activity_type': constants.ACTIVITY_TYPE_EXPLORATION, 'category': exploration_summary.category, 'created_on_msec': utils.get_time_in_millisecs( exploration_summary.exploration_model_created_on), 'objective': exploration_summary.objective, 'language_code': exploration_summary.language_code, 'last_updated_msec': utils.get_time_in_millisecs( exploration_summary.exploration_model_last_updated), 'human_readable_contributors_summary': (get_human_readable_contributors_summary( exploration_summary.contributors_summary)), 'status': exploration_summary.status, 'ratings': exploration_summary.ratings, 'community_owned': exploration_summary.community_owned, 'tags': exploration_summary.tags, 'thumbnail_icon_url': utils.get_thumbnail_icon_url_for_category( exploration_summary.category), 'thumbnail_bg_color': utils.get_hex_color_for_category(exploration_summary.category), 'num_views': view_counts[ind], } displayable_exp_summaries.append(summary_dict) return displayable_exp_summaries
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) # We need to do the filtering because some activities that were # originally subscribed to may have been deleted since. subscribed_exploration_summaries = [ summary for summary in exp_services.get_exploration_summaries_matching_ids( subscription_services.get_exploration_ids_subscribed_to( self.user_id)) if summary is not None ] subscribed_collection_summaries = [ summary for summary in collection_services.get_collection_summaries_matching_ids( subscription_services.get_collection_ids_subscribed_to( self.user_id)) if summary is not None ] exploration_ids_subscribed_to = [ summary.id for summary in subscribed_exploration_summaries ] exp_summary_dicts = summary_services.get_displayable_exp_summary_dicts( subscribed_exploration_summaries) collection_summary_dicts = [] feedback_thread_analytics = ( feedback_services.get_thread_analytics_multi( exploration_ids_subscribed_to)) # TODO(bhenning): Update this to use unresolved answers from # stats_services once the training interface is enabled and it's cheaper # to retrieve top answers from stats_services. for ind, exploration in enumerate(exp_summary_dicts): exploration.update(feedback_thread_analytics[ind].to_dict()) exp_summary_dicts = sorted( exp_summary_dicts, 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_dicts.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) }) 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'])) subscriber_ids = subscription_services.get_all_subscribers_of_creator( self.user_id) subscribers_settings = user_services.get_users_settings(subscriber_ids) subscribers_list = [] for index, subscriber_settings in enumerate(subscribers_settings): subscriber_summary = { 'subscriber_picture_data_url': (subscriber_settings.profile_picture_data_url), 'subscriber_username': subscriber_settings.username, 'subscriber_impact': (user_services.get_user_impact_score(subscriber_ids[index])) } subscribers_list.append(subscriber_summary) self.values.update({ 'explorations_list': exp_summary_dicts, 'collections_list': collection_summary_dicts, 'dashboard_stats': dashboard_stats, 'last_week_stats': last_week_stats, 'subscribers_list': subscribers_list }) self.render_json(self.values)
def get_displayable_exp_summary_dicts(exploration_summaries): """Gets a summary of explorations in human readable form. Given a list of exploration summary domain objects, returns a list, with the same number of elements, of the corresponding human-readable exploration summary dicts. This assumes that all the exploration summary domain objects passed in are valid (i.e., none of them are None). Args: exploration_summaries: list(ExplorationSummary). List of exploration summary objects. Return: list(dict). A list of exploration summary dicts in human readable form. Example: [ { 'category': u'A category', 'community_owned': False, 'id': 'eid2', 'language_code': 'en', 'num_views': 0, 'objective': u'An objective', 'status': 'public', 'tags': [], 'thumbnail_bg_color': '#a33f40', 'thumbnail_icon_url': self.get_static_asset_url( '/images/subjects/Lightbulb.svg'), 'title': u'Exploration 2 Albert title', }, ] """ exploration_ids = [ exploration_summary.id for exploration_summary in exploration_summaries] view_counts = ( stats_jobs_continuous.StatisticsAggregator.get_views_multi( exploration_ids)) displayable_exp_summaries = [] for ind, exploration_summary in enumerate(exploration_summaries): if not exploration_summary: continue summary_dict = { 'id': exploration_summary.id, 'title': exploration_summary.title, 'activity_type': feconf.ACTIVITY_TYPE_EXPLORATION, 'category': exploration_summary.category, 'created_on_msec': utils.get_time_in_millisecs( exploration_summary.exploration_model_created_on), 'objective': exploration_summary.objective, 'language_code': exploration_summary.language_code, 'last_updated_msec': utils.get_time_in_millisecs( exploration_summary.exploration_model_last_updated ), 'human_readable_contributors_summary': ( get_human_readable_contributors_summary( exploration_summary.contributors_summary) ), 'status': exploration_summary.status, 'ratings': exploration_summary.ratings, 'community_owned': exploration_summary.community_owned, 'tags': exploration_summary.tags, 'thumbnail_icon_url': utils.get_thumbnail_icon_url_for_category( exploration_summary.category), 'thumbnail_bg_color': utils.get_hex_color_for_category( exploration_summary.category), 'num_views': view_counts[ind], } displayable_exp_summaries.append(summary_dict) return displayable_exp_summaries
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_count_for_default_rule( exploration_ids_subscribed_to)) 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']] if exploration['id'] in unresolved_answers_dict else 0) }) 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, '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) }) 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)