def test_get_exploration_rights_for_nonexistent_exploration(self): NON_EXP_ID = "this_exp_does_not_exist_id" with self.assertRaisesRegexp( Exception, "Entity for class ExplorationRightsModel with id " "this_exp_does_not_exist_id not found" ): rights_manager.get_exploration_rights(NON_EXP_ID) self.assertIsNone(rights_manager.get_exploration_rights(NON_EXP_ID, strict=False))
def test_get_exploration_rights_for_nonexistent_exploration(self): non_exp_id = 'this_exp_does_not_exist_id' with self.assertRaisesRegexp( Exception, 'Entity for class ExplorationRightsModel with id ' 'this_exp_does_not_exist_id not found' ): rights_manager.get_exploration_rights(non_exp_id) self.assertIsNone( rights_manager.get_exploration_rights(non_exp_id, strict=False))
def update_exploration_status_in_search(exp_id): rights = rights_manager.get_exploration_rights(exp_id) if rights.status == rights_manager.EXPLORATION_STATUS_PRIVATE: delete_documents_from_search_index([exp_id]) else: patch_exploration_search_document( rights.id, _exp_rights_to_search_dict(rights))
def _get_exploration_data(self, exploration_id): """Returns a description of the given exploration.""" exploration = exp_services.get_exploration_by_id(exploration_id) states = {} for state_name in exploration.states: state_frontend_dict = exploration.export_state_to_frontend_dict( state_name) state_frontend_dict['unresolved_answers'] = ( stats_services.get_unresolved_answers_for_default_rule( exploration_id, state_name)) states[state_name] = state_frontend_dict return { 'exploration_id': exploration_id, 'init_state_name': exploration.init_state_name, 'category': exploration.category, 'title': exploration.title, 'states': states, 'param_changes': exploration.param_change_dicts, 'param_specs': exploration.param_specs_dict, 'version': exploration.version, 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict(), }
def revert_exploration( committer_id, exploration_id, current_version, revert_to_version): """Reverts an exploration to the given version number. Commits changes.""" exploration_model = exp_models.ExplorationModel.get( exploration_id, strict=False) if current_version > exploration_model.version: raise Exception( 'Unexpected error: trying to update version %s of exploration ' 'from version %s. Please reload the page and try again.' % (exploration_model.version, current_version)) elif current_version < exploration_model.version: raise Exception( 'Trying to update version %s of exploration from version %s, ' 'which is too old. Please reload the page and try again.' % (exploration_model.version, current_version)) # Validate the previous version of the exploration before committing the # change. exploration = get_exploration_by_id( exploration_id, version=revert_to_version) exploration_rights = rights_manager.get_exploration_rights(exploration.id) if exploration_rights.status != rights_manager.EXPLORATION_STATUS_PRIVATE: exploration.validate(strict=True) else: exploration.validate() exploration_model.revert( committer_id, 'Reverted exploration to version %s' % revert_to_version, revert_to_version) memcache_services.delete(_get_exploration_memcache_key(exploration_id))
def _get_search_rank(exp_id): """Returns an integer determining the document's rank in search. Featured explorations get a ranking bump, and so do explorations that have been more recently updated. Good ratings will increase the ranking and bad ones will lower it. """ # TODO(sll): Improve this calculation. _STATUS_PUBLICIZED_BONUS = 30 exploration = get_exploration_by_id(exp_id) rights = rights_manager.get_exploration_rights(exp_id) summary = get_exploration_summary_by_id(exp_id) rank = ( _STATUS_PUBLICIZED_BONUS if rights.status == rights_manager.EXPLORATION_STATUS_PUBLICIZED else 0) if summary.ratings: RATING_WEIGHTINGS = {'1': -5, '2': -2, '3': 2, '4': 5, '5': 10} for rating_value in summary.ratings: rank += ( summary.ratings[rating_value] * RATING_WEIGHTINGS[rating_value]) _BEGINNING_OF_TIME = datetime.datetime(2013, 6, 30) time_delta_days = int((exploration.last_updated - _BEGINNING_OF_TIME).days) if time_delta_days == 0: rank += 80 elif time_delta_days == 1: rank += 50 elif 2 <= time_delta_days <= 7: rank += 35 return rank
def _get_all_recipient_ids(exploration_id, thread_id, author_id): """Fetches all authors of the exploration excluding the given author and all the other recipients. Args: exploration_id: str. thread_id: str. author_id: str. One author of the given exploration_id. Returns: tuple of (batch_recipients, other_recipients) batch_recipients: set(str). The user_ids of the authors excluding the given author. other_recipients: set(str). The user_ids of the other participants in this thread, excluding owners of the exploration and the given author. """ exploration_rights = rights_manager.get_exploration_rights(exploration_id) owner_ids = set(exploration_rights.owner_ids) participant_ids = get_all_thread_participants(exploration_id, thread_id) sender_id = set([author_id]) batch_recipient_ids = owner_ids - sender_id other_recipient_ids = participant_ids - batch_recipient_ids - sender_id return (batch_recipient_ids, other_recipient_ids)
def put(self, exploration_id): """Updates the publication status of the given exploration, and sends an email to all its owners. """ exploration = exp_services.get_exploration_by_id(exploration_id) action = self.payload.get('action') email_body = self.payload.get('email_body') version = self.payload.get('version') _require_valid_version(version, exploration.version) if action not in feconf.VALID_MODERATOR_ACTIONS: raise self.InvalidInputException('Invalid moderator action.') # If moderator emails can be sent, check that all the prerequisites are # satisfied, otherwise do nothing. if feconf.REQUIRE_EMAIL_ON_MODERATOR_ACTION: if not email_body: raise self.InvalidInputException( 'Moderator actions should include an email to the ' 'recipient.') email_manager.require_moderator_email_prereqs_are_satisfied() # Perform the moderator action. if action == 'unpublish_exploration': rights_manager.unpublish_exploration( self.user_id, exploration_id) exp_services.delete_documents_from_search_index([ exploration_id]) elif action == 'publicize_exploration': try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration( self.user_id, exploration_id) else: raise self.InvalidInputException( 'No change was made to this exploration.') exp_rights = rights_manager.get_exploration_rights(exploration_id) # If moderator emails can be sent, send an email to the all owners of # the exploration notifying them of the change. if feconf.REQUIRE_EMAIL_ON_MODERATOR_ACTION: for owner_id in exp_rights.owner_ids: email_manager.send_moderator_action_email( self.user_id, owner_id, feconf.VALID_MODERATOR_ACTIONS[action]['email_intent'], exploration.title, email_body) self.render_json({ 'rights': exp_rights.to_dict(), })
def _save_exploration( committer_id, exploration, commit_message, change_list): """Validates an exploration and commits it to persistent storage. If successful, increments the version number of the incoming exploration domain object by 1. """ if change_list is None: change_list = [] exploration_rights = rights_manager.get_exploration_rights(exploration.id) if exploration_rights.status != rights_manager.EXPLORATION_STATUS_PRIVATE: exploration.validate(strict=True) else: exploration.validate() exploration_model = exp_models.ExplorationModel.get( exploration.id, strict=False) if exploration_model is None: exploration_model = exp_models.ExplorationModel(id=exploration.id) else: if exploration.version > exploration_model.version: raise Exception( 'Unexpected error: trying to update version %s of exploration ' 'from version %s. Please reload the page and try again.' % (exploration_model.version, exploration.version)) elif exploration.version < exploration_model.version: raise Exception( 'Trying to update version %s of exploration from version %s, ' 'which is too old. Please reload the page and try again.' % (exploration_model.version, exploration.version)) exploration_model.category = exploration.category exploration_model.title = exploration.title exploration_model.objective = exploration.objective exploration_model.language_code = exploration.language_code exploration_model.skill_tags = exploration.skill_tags exploration_model.blurb = exploration.blurb exploration_model.author_notes = exploration.author_notes exploration_model.default_skin = exploration.default_skin exploration_model.init_state_name = exploration.init_state_name exploration_model.states = { state_name: state.to_dict() for (state_name, state) in exploration.states.iteritems()} exploration_model.param_specs = exploration.param_specs_dict exploration_model.param_changes = exploration.param_change_dicts exploration_model.commit( committer_id, commit_message, change_list) memcache_services.delete(_get_exploration_memcache_key(exploration.id)) event_services.ExplorationContentChangeEventHandler.record(exploration.id) index_explorations_given_ids([exploration.id]) exploration.version += 1
def post(self): payload = json.loads(self.request.body) exploration_id = payload["exploration_id"] thread_id = payload["thread_id"] exploration_rights = rights_manager.get_exploration_rights(exploration_id) exploration = exp_services.get_exploration_by_id(exploration_id) suggestion = feedback_services.get_suggestion(exploration_id, thread_id) email_manager.send_suggestion_email( exploration.title, exploration.id, suggestion.author_id, exploration_rights.owner_ids )
def map(item): if item.deleted: return exploration_rights = rights_manager.get_exploration_rights( item.id, strict=False) if exploration_rights is None: return if (exploration_rights.status == feconf.ACTIVITY_STATUS_PRIVATE and exploration_rights.viewable_if_private): yield (item.id, item.title.encode('utf-8'))
def _get_exploration_data( self, exploration_id, apply_draft=False, version=None): """Returns a description of the given exploration.""" try: if apply_draft: exploration = exp_services.get_exp_with_draft_applied( exploration_id, self.user_id) else: exploration = exp_services.get_exploration_by_id( exploration_id, version=version) except: raise self.PageNotFoundException states = {} for state_name in exploration.states: state_dict = exploration.states[state_name].to_dict() states[state_name] = state_dict exp_user_data = user_models.ExplorationUserDataModel.get( self.user_id, exploration_id) draft_changes = (exp_user_data.draft_change_list if exp_user_data and exp_user_data.draft_change_list else None) is_version_of_draft_valid = ( exp_services.is_version_of_draft_valid( exploration_id, exp_user_data.draft_change_list_exp_version) if exp_user_data and exp_user_data.draft_change_list_exp_version else None) exploration_email_preferences = ( user_services.get_email_preferences_for_exploration( self.user_id, exploration_id)) editor_dict = { 'category': exploration.category, 'exploration_id': exploration_id, 'init_state_name': exploration.init_state_name, 'language_code': exploration.language_code, 'objective': exploration.objective, 'param_changes': exploration.param_change_dicts, 'param_specs': exploration.param_specs_dict, 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict(), 'show_state_editor_tutorial_on_load': ( self.user_id and not self.has_seen_editor_tutorial), 'skin_customizations': exploration.skin_instance.to_dict()[ 'skin_customizations'], 'states': states, 'tags': exploration.tags, 'title': exploration.title, 'version': exploration.version, 'is_version_of_draft_valid': is_version_of_draft_valid, 'draft_changes': draft_changes, 'email_preferences': exploration_email_preferences.to_dict() } return editor_dict
def test_first_published_time_of_exploration_that_is_unpublished(self): """This tests that, if an exploration is published, unpublished, and then published again, the job uses the first publication time as the value for first_published_msec. """ self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.set_admins([self.ADMIN_USERNAME]) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) self.save_new_valid_exploration( self.EXP_ID, owner_id, end_state_name='End') rights_manager.publish_exploration(owner_id, self.EXP_ID) job_class = exp_jobs_one_off.ExplorationFirstPublishedOneOffJob job_id = job_class.create_new() exp_jobs_one_off.ExplorationFirstPublishedOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() exploration_rights = rights_manager.get_exploration_rights(self.EXP_ID) # Test to see whether first_published_msec was correctly updated. exp_first_published = exploration_rights.first_published_msec exp_rights_model = exp_models.ExplorationRightsModel.get(self.EXP_ID) last_updated_time_msec = utils.get_time_in_millisecs( exp_rights_model.last_updated) self.assertLess( exp_first_published, last_updated_time_msec) rights_manager.unpublish_exploration(admin_id, self.EXP_ID) rights_manager.publish_exploration(owner_id, self.EXP_ID) job_id = job_class.create_new() exp_jobs_one_off.ExplorationFirstPublishedOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() # Test to see whether first_published_msec remains the same despite the # republication. exploration_rights = rights_manager.get_exploration_rights(self.EXP_ID) self.assertEqual( exp_first_published, exploration_rights.first_published_msec)
def add_message_to_email_buffer(author_id, exploration_id, thread_id, message_id): exploration_rights = rights_manager.get_exploration_rights(exploration_id) feedback_message_reference = feedback_domain.FeedbackMessageReference( exploration_id, thread_id, message_id) for owner_id in exploration_rights.owner_ids: owner_preferences = user_services.get_email_preferences(owner_id) if (owner_id != author_id and owner_preferences['can_receive_feedback_message_email']): transaction_services.run_in_transaction( _add_feedback_message_reference, owner_id, feedback_message_reference)
def reduce(exp_id, stringified_commit_times_msecs): exploration_rights = rights_manager.get_exploration_rights( exp_id, strict=False) if exploration_rights is None: return commit_times_msecs = [ ast.literal_eval(commit_time_string) for commit_time_string in stringified_commit_times_msecs] first_published_msec = min(commit_times_msecs) rights_manager.update_activity_first_published_msec( feconf.ACTIVITY_TYPE_EXPLORATION, exp_id, first_published_msec)
def map(item): if item.deleted: return exploration = exp_services.get_exploration_from_model(item) exp_rights = rights_manager.get_exploration_rights(item.id) try: if exp_rights.status == rights_manager.ACTIVITY_STATUS_PRIVATE: exploration.validate() else: exploration.validate(strict=True) except utils.ValidationError as e: yield (item.id, unicode(e).encode('utf-8'))
def _exp_to_search_dict(exp): rights = rights_manager.get_exploration_rights(exp.id) doc = { 'id': exp.id, 'language_code': exp.language_code, 'title': exp.title, 'category': exp.category, 'skills': exp.skill_tags, 'blurb': exp.blurb, 'objective': exp.objective, 'author_notes': exp.author_notes, 'rank': _get_search_rank(exp.id), } doc.update(_exp_rights_to_search_dict(rights)) return doc
def map(item): from core.domain import exp_services from core.domain import rights_manager if item.deleted: return exploration = exp_services.get_exploration_from_model(item) exp_summary = rights_manager.get_exploration_rights(item.id) try: if exp_summary.status == rights_manager.EXPLORATION_STATUS_PRIVATE: exploration.validate() else: exploration.validate(strict=True) except utils.ValidationError as e: yield (item.id, unicode(e).encode('utf-8'))
def map(item): exp_id = item.get_unversioned_instance_id() exp_rights = rights_manager.get_exploration_rights( exp_id, strict=False) if exp_rights is None: return exp_first_published_msec = exp_rights.first_published_msec # First contribution time in msec is only set from contributions to # explorations that are currently published. if not rights_manager.is_exploration_private(exp_id): created_on_msec = utils.get_time_in_millisecs(item.created_on) yield ( item.committer_id, max(exp_first_published_msec, created_on_msec) )
def _get_search_rank(exp_id): """Returns an integer determining the document's rank in search. Featured explorations get a ranking bump, and so do explorations that have been more recently updated. """ # TODO(sll): Improve this calculation. exploration = get_exploration_by_id(exp_id) rights = rights_manager.get_exploration_rights(exp_id) rank = ( 3000 if rights.status == rights_manager.EXPLORATION_STATUS_PUBLICIZED else 0) _BEGINNING_OF_TIME = datetime.datetime(2013, 6, 30) time_delta_days = (exploration.last_updated - _BEGINNING_OF_TIME).days rank += int(time_delta_days) return rank
def _get_exploration_data(self, exploration_id, version=None): """Returns a description of the given exploration.""" try: exploration = exp_services.get_exploration_by_id( exploration_id, version=version) except: raise self.PageNotFoundException states = {} for state_name in exploration.states: state_dict = exploration.states[state_name].to_dict() state_dict['unresolved_answers'] = ( stats_services.get_top_unresolved_answers_for_default_rule( exploration_id, state_name)) states[state_name] = state_dict editor_dict = { 'category': exploration.category, 'exploration_id': exploration_id, 'init_state_name': exploration.init_state_name, 'language_code': exploration.language_code, 'objective': exploration.objective, 'param_changes': exploration.param_change_dicts, 'param_specs': exploration.param_specs_dict, 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict(), 'show_state_editor_tutorial_on_load': ( self.user_id and not self.user_has_started_state_editor_tutorial), 'skin_customizations': exploration.skin_instance.to_dict()[ 'skin_customizations'], 'states': states, 'tags': exploration.tags, 'title': exploration.title, 'version': exploration.version, } if feconf.SHOW_SKIN_CHOOSER: editor_dict['all_skin_ids'] = ( skins_services.Registry.get_all_skin_ids()) editor_dict['default_skin_id'] = exploration.default_skin return editor_dict
def _get_exploration_data(self, exploration_id): """Returns a description of the given exploration.""" try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException states = {} for state_name in exploration.states: state_frontend_dict = exploration.export_state_to_frontend_dict( state_name) state_frontend_dict['unresolved_answers'] = ( stats_services.get_top_unresolved_answers_for_default_rule( exploration_id, state_name)) states[state_name] = state_frontend_dict editor_dict = { 'exploration_id': exploration_id, 'init_state_name': exploration.init_state_name, 'category': exploration.category, 'objective': exploration.objective, 'title': exploration.title, 'states': states, 'param_changes': exploration.param_change_dicts, 'param_specs': exploration.param_specs_dict, 'version': exploration.version, 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict(), } if feconf.SHOW_SKIN_CHOOSER: editor_dict['all_skin_ids'] = ( skins_services.Registry.get_all_skin_ids()) editor_dict['default_skin_id'] = exploration.default_skin return editor_dict
def get(self, exploration_id): """Populates the data on the individual exploration page. Args: exploration_id: str. The ID of the exploration. """ version = self.request.get('v') version = int(version) if version else None try: exploration = exp_fetchers.get_exploration_by_id(exploration_id, version=version) except Exception as e: raise self.PageNotFoundException(e) exploration_rights = rights_manager.get_exploration_rights( exploration_id, strict=False) user_settings = user_services.get_user_settings(self.user_id) preferred_audio_language_code = None if user_settings is not None: preferred_audio_language_code = ( user_settings.preferred_audio_language_code) # Retrieve all classifiers for the exploration. state_classifier_mapping = {} classifier_training_jobs = ( classifier_services.get_classifier_training_jobs( exploration_id, exploration.version, list(exploration.states.keys()))) for index, state_name in enumerate(exploration.states.keys()): if classifier_training_jobs[index] is not None: classifier_data = classifier_training_jobs[ index].classifier_data algorithm_id = classifier_training_jobs[index].algorithm_id data_schema_version = ( classifier_training_jobs[index].data_schema_version) state_classifier_mapping[state_name] = { 'algorithm_id': algorithm_id, 'classifier_data': classifier_data, 'data_schema_version': data_schema_version } self.values.update({ 'can_edit': (rights_manager.check_can_edit_activity(self.user, exploration_rights)), 'exploration': exploration.to_player_dict(), 'exploration_id': exploration_id, 'is_logged_in': bool(self.user_id), 'session_id': utils.generate_new_session_id(), 'version': exploration.version, 'preferred_audio_language_code': preferred_audio_language_code, 'state_classifier_mapping': state_classifier_mapping, 'auto_tts_enabled': exploration.auto_tts_enabled, 'correctness_feedback_enabled': (exploration.correctness_feedback_enabled), 'record_playthrough_probability': (config_domain.RECORD_PLAYTHROUGH_PROBABILITY.value) }) self.render_json(self.values)
def put(self, exploration_id): """Updates the editing rights for the given exploration.""" exploration = exp_services.get_exploration_by_id(exploration_id) version = self.payload.get('version') _require_valid_version(version, exploration.version) is_public = self.payload.get('is_public') is_publicized = self.payload.get('is_publicized') is_community_owned = self.payload.get('is_community_owned') new_member_email = self.payload.get('new_member_email') new_member_role = self.payload.get('new_member_role') if new_member_email: if not rights_manager.Actor(self.user_id).can_modify_roles( exploration_id): raise self.UnauthorizedUserException( 'Only an owner of this exploration can add or change ' 'roles.') new_member_id = user_services.get_user_id_from_email( new_member_email) if new_member_id is None: raise Exception( 'Sorry, we could not find a user with this email address.') user_services.get_or_create_user(new_member_id, new_member_email) rights_manager.assign_role( self.user_id, exploration_id, new_member_id, new_member_role) elif is_public is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_public: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publish_exploration( self.user_id, exploration_id) else: rights_manager.unpublish_exploration( self.user_id, exploration_id) elif is_publicized is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_publicized: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration( self.user_id, exploration_id) else: rights_manager.unpublicize_exploration( self.user_id, exploration_id) elif is_community_owned: exploration = exp_services.get_exploration_by_id(exploration_id) try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.release_ownership(self.user_id, exploration_id) else: raise self.InvalidInputException( 'No change was made to this exploration.') self.render_json({ 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict() })
def _should_index(exp): rights = rights_manager.get_exploration_rights(exp.id) return rights.status != rights_manager.EXPLORATION_STATUS_PRIVATE
def put(self, exploration_id): """Updates the editing rights for the given exploration.""" exploration = exp_services.get_exploration_by_id(exploration_id) version = self.payload.get('version') _require_valid_version(version, exploration.version) is_public = self.payload.get('is_public') is_publicized = self.payload.get('is_publicized') is_community_owned = self.payload.get('is_community_owned') new_member_username = self.payload.get('new_member_username') new_member_role = self.payload.get('new_member_role') viewable_if_private = self.payload.get('viewable_if_private') if new_member_username: if not rights_manager.Actor( self.user_id).can_modify_roles( rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id): raise self.UnauthorizedUserException( 'Only an owner of this exploration can add or change ' 'roles.') new_member_id = user_services.get_user_id_from_username( new_member_username) if new_member_id is None: raise Exception( 'Sorry, we could not find the specified user.') rights_manager.assign_role_for_exploration( self.user_id, exploration_id, new_member_id, new_member_role) elif is_public is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_public: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) exp_services.publish_exploration_and_update_user_profiles( self.user_id, exploration_id) exp_services.index_explorations_given_ids([exploration_id]) else: rights_manager.unpublish_exploration( self.user_id, exploration_id) exp_services.delete_documents_from_search_index([ exploration_id]) elif is_publicized is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_publicized: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration( self.user_id, exploration_id) else: rights_manager.unpublicize_exploration( self.user_id, exploration_id) elif is_community_owned: exploration = exp_services.get_exploration_by_id(exploration_id) try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.release_ownership_of_exploration( self.user_id, exploration_id) elif viewable_if_private is not None: rights_manager.set_private_viewability_of_exploration( self.user_id, exploration_id, viewable_if_private) else: raise self.InvalidInputException( 'No change was made to this exploration.') self.render_json({ 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict() })
def put(self, exploration_id): """Updates the editing rights for the given exploration.""" exploration = exp_services.get_exploration_by_id(exploration_id) version = self.payload.get('version') _require_valid_version(version, exploration.version) is_public = self.payload.get('is_public') is_publicized = self.payload.get('is_publicized') is_community_owned = self.payload.get('is_community_owned') new_member_username = self.payload.get('new_member_username') new_member_role = self.payload.get('new_member_role') viewable_if_private = self.payload.get('viewable_if_private') if new_member_username: if not rights_manager.Actor(self.user_id).can_modify_roles( rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id): raise self.UnauthorizedUserException( 'Only an owner of this exploration can add or change ' 'roles.') new_member_id = user_services.get_user_id_from_username( new_member_username) if new_member_id is None: raise Exception('Sorry, we could not find the specified user.') rights_manager.assign_role_for_exploration(self.user_id, exploration_id, new_member_id, new_member_role) elif is_public is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_public: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publish_exploration(self.user_id, exploration_id) exp_services.index_explorations_given_ids([exploration_id]) else: rights_manager.unpublish_exploration(self.user_id, exploration_id) exp_services.delete_documents_from_search_index( [exploration_id]) elif is_publicized is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_publicized: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration(self.user_id, exploration_id) else: rights_manager.unpublicize_exploration(self.user_id, exploration_id) elif is_community_owned: exploration = exp_services.get_exploration_by_id(exploration_id) try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.release_ownership_of_exploration( self.user_id, exploration_id) elif viewable_if_private is not None: rights_manager.set_private_viewability_of_exploration( self.user_id, exploration_id, viewable_if_private) else: raise self.InvalidInputException( 'No change was made to this exploration.') self.render_json({ 'rights': rights_manager.get_exploration_rights(exploration_id).to_dict() })