def post(self): """Creates a new learner group.""" title = self.normalized_payload.get('group_title') description = self.normalized_payload.get('group_description') invited_student_usernames = self.normalized_payload.get( 'invited_student_usernames') subtopic_page_ids = self.normalized_payload.get('subtopic_page_ids') story_ids = self.normalized_payload.get('story_ids') invited_student_ids = user_services.get_multi_user_ids_from_usernames( invited_student_usernames) new_learner_grp_id = learner_group_fetchers.get_new_learner_group_id() learner_group = learner_group_services.create_learner_group( new_learner_grp_id, title, description, [self.user_id], invited_student_ids, subtopic_page_ids, story_ids ) self.render_json({ 'id': learner_group.group_id, 'title': learner_group.title, 'description': learner_group.description, 'facilitator_usernames': user_services.get_usernames( learner_group.facilitator_user_ids), 'student_usernames': user_services.get_usernames( learner_group.student_user_ids), 'invited_student_usernames': user_services.get_usernames( learner_group.invited_student_user_ids), 'subtopic_page_ids': learner_group.subtopic_page_ids, 'story_ids': learner_group.story_ids })
def get(self, learner_group_id): """Handles GET requests for facilitator's view of learner group.""" is_valid_request = learner_group_services.is_user_facilitator( self.user_id, learner_group_id) if not is_valid_request: raise self.UnauthorizedUserException( 'You are not a facilitator of this learner group.') learner_group = learner_group_fetchers.get_learner_group_by_id( learner_group_id) self.render_json({ 'id': learner_group.group_id, 'title': learner_group.title, 'description': learner_group.description, 'facilitator_usernames': user_services.get_usernames( learner_group.facilitator_user_ids), 'student_usernames': user_services.get_usernames( learner_group.student_user_ids), 'invited_student_usernames': user_services.get_usernames( learner_group.invited_student_user_ids), 'subtopic_page_ids': learner_group.subtopic_page_ids, 'story_ids': learner_group.story_ids })
def get(self): """Handles GET requests.""" urlsafe_start_cursor = self.request.get('cursor') query_type = self.request.get('query_type') if query_type == 'all_non_private_commits': all_commits, new_urlsafe_start_cursor, more = ( exp_services.get_next_page_of_all_non_private_commits( urlsafe_start_cursor=urlsafe_start_cursor)) else: raise self.PageNotFoundException exp_ids = set([commit.exploration_id for commit in all_commits]) exp_ids_to_exp_data = ( exp_services.get_exploration_titles_and_categories(exp_ids)) unique_user_ids = list(set(commit.user_id for commit in all_commits)) unique_usernames = user_services.get_usernames(unique_user_ids) user_id_to_username = dict( python_utils.ZIP(unique_user_ids, unique_usernames)) all_commit_dicts = [] for commit in all_commits: commit_dict = commit.to_dict() commit_dict['username'] = user_id_to_username[commit.user_id] all_commit_dicts.append(commit_dict) self.render_json({ 'results': all_commit_dicts, 'cursor': new_urlsafe_start_cursor, 'more': more, 'exp_ids_to_exp_data': exp_ids_to_exp_data, })
def put(self, learner_group_id): """Updates an existing learner group.""" title = self.normalized_payload.get('group_title') description = self.normalized_payload.get('group_description') student_usernames = self.normalized_payload.get('student_usernames') invited_student_usernames = self.normalized_payload.get( 'invited_student_usernames') subtopic_page_ids = self.normalized_payload.get('subtopic_page_ids') story_ids = self.normalized_payload.get('story_ids') # Check if user is the facilitator of the learner group, as only # facilitators have the right to update a learner group. is_valid_request = learner_group_services.is_user_facilitator( self.user_id, learner_group_id ) if not is_valid_request: raise self.UnauthorizedUserException( 'You are not a facilitator of this learner group.') student_ids = user_services.get_multi_user_ids_from_usernames( student_usernames ) invited_student_ids = user_services.get_multi_user_ids_from_usernames( invited_student_usernames ) learner_group = learner_group_services.update_learner_group( learner_group_id, title, description, [self.user_id], student_ids, invited_student_ids, subtopic_page_ids, story_ids ) self.render_json({ 'id': learner_group.group_id, 'title': learner_group.title, 'description': learner_group.description, 'facilitator_usernames': user_services.get_usernames( learner_group.facilitator_user_ids), 'student_usernames': user_services.get_usernames( learner_group.student_user_ids), 'invited_student_usernames': user_services.get_usernames( learner_group.invited_student_user_ids), 'subtopic_page_ids': learner_group.subtopic_page_ids, 'story_ids': learner_group.story_ids })
def _deassign_role(committer, removed_user_id, activity_id, activity_type): """Deassigns given user from their current role in the activity. Args: committer: UserActionsInfo. UserActionsInfo object for the user who is performing the action. removed_user_id: str. ID of the user who is being deassigned from the activity. activity_id: str. ID of the activity. activity_type: str. The type of activity. Possible values: constants.ACTIVITY_TYPE_EXPLORATION, constants.ACTIVITY_TYPE_COLLECTION. Raises: Exception. UnauthorizedUserException: Could not deassign role. Exception. This user does not have any role for the given activity. """ committer_id = committer.user_id activity_rights = _get_activity_rights(activity_type, activity_id) if not check_can_modify_activity_roles(committer, activity_rights): logging.error('User %s tried to remove user %s from an activity %s ' 'but was refused permission.' % (committer_id, removed_user_id, activity_id)) raise Exception('UnauthorizedUserException: Could not deassign role.') if activity_rights.is_owner(removed_user_id): old_role = rights_domain.ROLE_OWNER activity_rights.owner_ids.remove(removed_user_id) elif activity_rights.is_editor(removed_user_id): old_role = rights_domain.ROLE_EDITOR activity_rights.editor_ids.remove(removed_user_id) elif activity_rights.is_voice_artist(removed_user_id): old_role = rights_domain.ROLE_VOICE_ARTIST activity_rights.voice_artist_ids.remove(removed_user_id) elif activity_rights.is_viewer(removed_user_id): old_role = rights_domain.ROLE_VIEWER activity_rights.viewer_ids.remove(removed_user_id) else: raise Exception('This user does not have any role in %s with ID %s' % (activity_type, activity_id)) assignee_username = user_services.get_usernames(removed_user_id)[0] if assignee_username is None: assignee_username = '******' commit_message = 'Remove %s from role %s for %s' % ( assignee_username, old_role, activity_type) commit_cmds = [{ 'cmd': rights_domain.CMD_REMOVE_ROLE, 'removed_user_id': removed_user_id, 'old_role': old_role, }] _save_activity_rights(committer_id, activity_rights, activity_type, commit_message, commit_cmds) _update_activity_summary(activity_type, activity_rights)
def test_get_usernames(self): user_ids = ['test1', feconf.SYSTEM_COMMITTER_ID, 'test2'] usernames = ['name1', feconf.SYSTEM_COMMITTER_ID, 'name2'] user_emails = [ '*****@*****.**', feconf.SYSTEM_EMAIL_ADDRESS, '*****@*****.**' ] for uid, email, name in zip(user_ids, user_emails, usernames): if uid != feconf.SYSTEM_COMMITTER_ID: user_services.create_new_user(uid, email) user_services.set_username(uid, name) # Handle usernames that exists. self.assertEqual(usernames, user_services.get_usernames(user_ids)) # Return empty list when no user id passed. self.assertEqual([], user_services.get_usernames([])) # Return None for usernames that don't exists. self.assertEqual([None, 'name1'], user_services.get_usernames(['fakeUser', 'test1']))
def send_emails_to_subscribers(creator_id, exploration_id, exploration_title): """Sends an email to all the subscribers of the creators when the creator publishes an exploration. Args: creator_id: str. The id of the creator who has published an exploration and to whose subscribers we are sending emails. exploration_id: str. The id of the exploration which the creator has published. exploration_title: str. The title of the exploration which the creator has published. """ creator_name = user_services.get_username(creator_id) email_subject = ('%s has published a new exploration!' % creator_name) email_body_template = ( 'Hi %s,<br>' '<br>' '%s has published a new exploration! You can play it here: ' '<a href="https://www.oppia.org/explore/%s">%s</a><br>' '<br>' 'Thanks, and happy learning!<br>' '<br>' 'Best wishes,<br>' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return if not feconf.CAN_SEND_SUBSCRIPTION_EMAILS: log_new_error('This app cannot send subscription emails to users.') return recipient_list = subscription_services.get_all_subscribers_of_creator( creator_id) recipients_usernames = user_services.get_usernames(recipient_list) recipients_preferences = user_services.get_users_email_preferences( recipient_list) for index, username in enumerate(recipients_usernames): if recipients_preferences[index].can_receive_subscription_email: email_body = email_body_template % ( username, creator_name, exploration_id, exploration_title, EMAIL_FOOTER.value) _send_email(recipient_list[index], feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_SUBSCRIPTION_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def send_emails_to_subscribers(creator_id, exploration_id, exploration_title): """Sends an email to all the subscribers of the creators when the creator publishes an exploration. Args: creator_id: str. The id of the creator who has published an exploration and to whose subscribers we are sending emails. exploration_id: str. The id of the exploration which the creator has published. exploration_title: str. The title of the exploration which the creator has published. """ creator_name = user_services.get_username(creator_id) email_subject = ('%s has published a new exploration!' % creator_name) email_body_template = ( 'Hi %s,<br>' '<br>' '%s has published a new exploration! You can play it here: ' '<a href="https://www.oppia.org/explore/%s">%s</a><br>' '<br>' 'Thanks, and happy learning!<br>' '<br>' 'Best wishes,<br>' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return if not feconf.CAN_SEND_SUBSCRIPTION_EMAILS: log_new_error('This app cannot send subscription emails to users.') return recipient_list = subscription_services.get_all_subscribers_of_creator( creator_id) recipients_usernames = user_services.get_usernames(recipient_list) recipients_preferences = user_services.get_users_email_preferences( recipient_list) for index, username in enumerate(recipients_usernames): if recipients_preferences[index].can_receive_subscription_email: email_body = email_body_template % ( username, creator_name, exploration_id, exploration_title, EMAIL_FOOTER.value) _send_email( recipient_list[index], feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_SUBSCRIPTION_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def get(self, exploration_id): """Handles GET requests.""" snapshots = exp_services.get_exploration_snapshots_metadata( exploration_id) # Patch `snapshots` to use the editor's display name. snapshots_committer_ids = [ snapshot['committer_id'] for snapshot in snapshots] committer_usernames = user_services.get_usernames( snapshots_committer_ids) for index, snapshot in enumerate(snapshots): snapshot['committer_id'] = committer_usernames[index] self.render_json({ 'snapshots': snapshots, })
def get(self): """Handles GET requests.""" if self.user_id is None: raise self.PageNotFoundException job_queued_msec, recent_notifications = ( user_jobs_continuous.DashboardRecentUpdatesAggregator. get_recent_notifications( # pylint: disable=line-too-long self.user_id)) last_seen_msec = ( subscription_services.get_last_seen_notifications_msec( self.user_id)) # Replace author_ids with their usernames. author_ids = [ notification['author_id'] for notification in recent_notifications if notification['author_id'] ] author_usernames = user_services.get_usernames(author_ids) author_id_to_username = { None: '', } for ind, author_id in enumerate(author_ids): author_id_to_username[author_id] = author_usernames[ind] for notification in recent_notifications: notification['author_username'] = ( author_id_to_username[notification['author_id']]) del notification['author_id'] subscription_services.record_user_has_seen_notifications( self.user_id, job_queued_msec if job_queued_msec else 0.0) self.values.update({ # This may be None if no job has ever run for this user. 'job_queued_msec': job_queued_msec, # This may be None if this is the first time the user has seen # the dashboard. 'last_seen_msec': last_seen_msec, 'recent_notifications': recent_notifications, }) self.render_json(self.values)
def get(self): """Handles GET requests.""" if self.user_id is None: raise self.PageNotFoundException job_queued_msec, recent_updates = ( user_jobs.DashboardRecentUpdatesAggregator.get_recent_updates( self.user_id)) last_seen_msec = ( subscription_services.get_last_seen_notifications_msec( self.user_id)) # Replace author_ids with their usernames. author_ids = [ update['author_id'] for update in recent_updates if update['author_id'] ] author_usernames = user_services.get_usernames(author_ids) author_id_to_username = { None: '', } for ind in range(len(author_ids)): author_id_to_username[author_ids[ind]] = author_usernames[ind] for update in recent_updates: update['author_username'] = ( author_id_to_username[update['author_id']]) del update['author_id'] subscription_services.record_user_has_seen_notifications( self.user_id, job_queued_msec if job_queued_msec else 0.0) self.values.update({ # This may be None if no job has ever run for this user. 'job_queued_msec': job_queued_msec, # This may be None if this is the first time the user has seen # the dashboard. 'last_seen_msec': last_seen_msec, 'recent_updates': recent_updates, }) self.render_json(self.values)
def get(self): """Handles GET requests.""" if self.user_id is None: raise self.PageNotFoundException job_queued_msec, recent_notifications = ( user_jobs_continuous.DashboardRecentUpdatesAggregator.get_recent_notifications( # pylint: disable=line-too-long self.user_id)) last_seen_msec = ( subscription_services.get_last_seen_notifications_msec( self.user_id)) # Replace author_ids with their usernames. author_ids = [ notification['author_id'] for notification in recent_notifications if notification['author_id']] author_usernames = user_services.get_usernames(author_ids) author_id_to_username = { None: '', } for ind, author_id in enumerate(author_ids): author_id_to_username[author_id] = author_usernames[ind] for notification in recent_notifications: notification['author_username'] = ( author_id_to_username[notification['author_id']]) del notification['author_id'] subscription_services.record_user_has_seen_notifications( self.user_id, job_queued_msec if job_queued_msec else 0.0) self.values.update({ # This may be None if no job has ever run for this user. 'job_queued_msec': job_queued_msec, # This may be None if this is the first time the user has seen # the dashboard. 'last_seen_msec': last_seen_msec, 'recent_notifications': recent_notifications, }) self.render_json(self.values)
def get(self): """Handles GET requests.""" if self.user_id is None: raise self.PageNotFoundException job_queued_msec, recent_updates = ( user_jobs.DashboardRecentUpdatesAggregator.get_recent_updates( self.user_id)) last_seen_msec = ( subscription_services.get_last_seen_notifications_msec( self.user_id)) # Replace author_ids with their usernames. author_ids = [ update['author_id'] for update in recent_updates if update['author_id']] author_usernames = user_services.get_usernames(author_ids) author_id_to_username = { None: '', } for ind in range(len(author_ids)): author_id_to_username[author_ids[ind]] = author_usernames[ind] for update in recent_updates: update['author_username'] = ( author_id_to_username[update['author_id']]) del update['author_id'] subscription_services.record_user_has_seen_notifications( self.user_id, job_queued_msec if job_queued_msec else 0.0) self.values.update({ # This may be None if no job has ever run for this user. 'job_queued_msec': job_queued_msec, # This may be None if this is the first time the user has seen # the dashboard. 'last_seen_msec': last_seen_msec, 'recent_updates': recent_updates, }) self.render_json(self.values)
def get(self): """Handles GET requests for the facilitator dashboard.""" learner_groups = ( learner_group_fetchers.get_learner_groups_of_facilitator( self.user_id) ) learner_groups_data = [] for learner_group in learner_groups: learner_groups_data.append({ 'id': learner_group.group_id, 'title': learner_group.title, 'description': learner_group.description, 'facilitator_usernames': user_services.get_usernames( self.user_id), 'students_count': len(learner_group.student_user_ids) }) self.render_json({ 'learner_groups_list': learner_groups_data })
def get(self): """Handles GET requests.""" if self.user_id is None: raise self.PageNotFoundException job_queued_msec, recent_notifications = user_jobs.DashboardRecentUpdatesAggregator.get_recent_notifications( self.user_id ) last_seen_msec = subscription_services.get_last_seen_notifications_msec(self.user_id) # Replace author_ids with their usernames. author_ids = [notification["author_id"] for notification in recent_notifications if notification["author_id"]] author_usernames = user_services.get_usernames(author_ids) author_id_to_username = {None: ""} for ind in range(len(author_ids)): author_id_to_username[author_ids[ind]] = author_usernames[ind] for notification in recent_notifications: notification["author_username"] = author_id_to_username[notification["author_id"]] del notification["author_id"] subscription_services.record_user_has_seen_notifications( self.user_id, job_queued_msec if job_queued_msec else 0.0 ) self.values.update( { # This may be None if no job has ever run for this user. "job_queued_msec": job_queued_msec, # This may be None if this is the first time the user has seen # the dashboard. "last_seen_msec": last_seen_msec, "recent_notifications": recent_notifications, } ) self.render_json(self.values)