Esempio n. 1
0
    def get(self, exploration_id, escaped_state_name):
        """Handles GET requests."""
        current_exploration = exp_fetchers.get_exploration_by_id(
            exploration_id)

        state_name = utils.unescape_encoded_uri_component(escaped_state_name)
        if state_name not in current_exploration.states:
            logging.error('Could not find state: %s' % state_name)
            logging.error('Available states: %s' %
                          (list(current_exploration.states.keys())))
            raise self.PageNotFoundException

        self.render_json({
            'visualizations_info':
            stats_services.get_visualizations_info(
                current_exploration.id, state_name,
                current_exploration.states[state_name].interaction.id),
        })
Esempio n. 2
0
def get_state_reference_for_exploration(exp_id, state_name):
    """Returns the generated state reference for the given exploration id and
    state name.

    Args:
        exp_id: str. ID of the exploration.
        state_name: str. Name of the state.

    Returns:
        str. The generated state reference.
    """
    exploration = exp_fetchers.get_exploration_by_id(exp_id)
    if not exploration.has_state_name(state_name):
        raise utils.InvalidInputException(
            'No state with the given state name was found in the '
            'exploration with id %s' % exp_id)
    return (stats_models.LearnerAnswerDetailsModel.
            get_state_reference_for_exploration(exp_id, state_name))
Esempio n. 3
0
    def _publish_exploration(self, exploration_id):
        """Publish an exploration.

        Args:
            exploration_id: str. Id of the exploration.

        Raises:
            InvalidInputException: Given exploration is invalid.
        """
        exploration = exp_fetchers.get_exploration_by_id(exploration_id)
        try:
            exploration.validate(strict=True)
        except utils.ValidationError as e:
            raise self.InvalidInputException(e)

        exp_services.publish_exploration_and_update_user_profiles(
            self.user, exploration_id)
        exp_services.index_explorations_given_ids([exploration_id])
Esempio n. 4
0
    def post(self):
        payload = json.loads(self.request.body)
        user_id = payload['user_id']
        reference_dict = payload['reference_dict']
        old_status = payload['old_status']
        new_status = payload['new_status']

        message = feedback_services.get_message(reference_dict['thread_id'],
                                                reference_dict['message_id'])
        exploration = exp_fetchers.get_exploration_by_id(
            reference_dict['entity_id'])
        thread = feedback_services.get_thread(reference_dict['thread_id'])

        text = 'changed status from %s to %s' % (old_status, new_status)
        subject = 'Oppia thread status change: "%s"' % thread.subject
        email_manager.send_instant_feedback_message_email(
            user_id, message.author_id, text, subject, exploration.title,
            reference_dict['entity_id'], thread.subject)
    def test_handle_trainable_states(self):
        """Test the handle_trainable_states method."""
        exploration = exp_fetchers.get_exploration_by_id(self.exp_id)
        state_names = ['Home']
        classifier_services.handle_trainable_states(exploration, state_names)

        # There should be two jobs (the first job because of the creation of the
        # exploration) in the data store now.
        all_jobs = classifier_models.ClassifierTrainingJobModel.get_all()
        self.assertEqual(all_jobs.count(), 2)
        for index, job in enumerate(all_jobs):
            if index == 1:
                job_id = job.id

        classifier_training_job = (
            classifier_services.get_classifier_training_job_by_id(job_id))
        self.assertEqual(classifier_training_job.exp_id, self.exp_id)
        self.assertEqual(classifier_training_job.state_name, 'Home')
Esempio n. 6
0
    def put(self, exploration_id):
        """Updates properties of the given exploration."""
        exploration = exp_fetchers.get_exploration_by_id(exploration_id)
        version = self.normalized_payload.get('version')

        if version > exploration.version:
            raise base.BaseHandler.InvalidInputException(
                'Trying to update version %s of exploration from version %s, '
                'which is not possible. Please reload the page and try again.'
                % (exploration.version, version))
        if not exploration.edits_allowed:
            raise base.BaseHandler.InvalidInputException(
                'This exploration cannot be edited. Please contact the admin.')

        commit_message = self.normalized_payload.get('commit_message')
        change_list = self.normalized_payload.get('change_list')

        changes_are_mergeable = exp_services.are_changes_mergeable(
            exploration_id, version, change_list)
        exploration_rights = rights_manager.get_exploration_rights(
            exploration_id)
        can_edit = rights_manager.check_can_edit_activity(
            self.user, exploration_rights)
        can_voiceover = rights_manager.check_can_voiceover_activity(
            self.user, exploration_rights)

        try:
            if can_edit and changes_are_mergeable:
                exp_services.update_exploration(self.user_id, exploration_id,
                                                change_list, commit_message)
            elif can_voiceover and changes_are_mergeable:
                exp_services.update_exploration(self.user_id,
                                                exploration_id,
                                                change_list,
                                                commit_message,
                                                is_by_voice_artist=True)
        except utils.ValidationError as e:
            raise self.InvalidInputException(e)

        exploration_data = exp_services.get_user_exploration_data(
            self.user_id, exploration_id)

        self.values.update(exploration_data)
        self.render_json(self.values)
Esempio n. 7
0
    def get(self, exploration_id):
        """Populates the data on the individual exploration page.

        Args:
            exploration_id: str. The ID of the exploration.
        """
        version = self.normalized_request.get('v')

        exploration = exp_fetchers.get_exploration_by_id(
            exploration_id, strict=False, version=version)
        if exploration is None:
            raise self.PageNotFoundException()

        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
        preferred_language_codes = None

        if user_settings is not None:
            preferred_audio_language_code = (
                user_settings.preferred_audio_language_code)
            preferred_language_codes = (
                user_settings.preferred_language_codes)

        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,
            'preferred_language_codes': preferred_language_codes,
            '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)
Esempio n. 8
0
 def get(self, exploration_id):
     self.render_json({
         'exploration_id': exploration_id,
         'exploration_version': (
             exp_fetchers.get_exploration_by_id(exploration_id).version),
         'is_improvements_tab_enabled': (
             config_domain.IS_IMPROVEMENTS_TAB_ENABLED.value),
         'high_bounce_rate_task_state_bounce_rate_creation_threshold': (
             config_domain
             .HIGH_BOUNCE_RATE_TASK_STATE_BOUNCE_RATE_CREATION_THRESHOLD
             .value),
         'high_bounce_rate_task_state_bounce_rate_obsoletion_threshold': (
             config_domain
             .HIGH_BOUNCE_RATE_TASK_STATE_BOUNCE_RATE_OBSOLETION_THRESHOLD
             .value),
         'high_bounce_rate_task_minimum_exploration_starts': (
             config_domain.HIGH_BOUNCE_RATE_TASK_MINIMUM_EXPLORATION_STARTS
             .value),
     })
Esempio n. 9
0
def update_opportunity_with_updated_exploration(exp_id):
    """Updates the opportunities models with the changes made in the
    exploration.

    Args:
        exp_id: str. The exploration id which is also the id of the opportunity
            model.
    """
    updated_exploration = exp_fetchers.get_exploration_by_id(exp_id)
    content_count = updated_exploration.get_content_count()
    translation_counts = updated_exploration.get_translation_counts()
    complete_translation_language_list = (
        updated_exploration.get_languages_with_complete_translation())
    model = opportunity_models.ExplorationOpportunitySummaryModel.get(exp_id)
    exploration_opportunity_summary = (
        get_exploration_opportunity_summary_from_model(model))
    exploration_opportunity_summary.content_count = content_count
    exploration_opportunity_summary.translation_counts = translation_counts
    exploration_opportunity_summary.complete_translation_languages = (
        complete_translation_language_list)

    new_languages_for_voiceover = set(
        complete_translation_language_list) - set(
            exploration_opportunity_summary.
            assigned_voice_artist_in_language_codes)

    # We only append new languages to need_voice_artist_in_language_codes(
    # instead of adding all of the complete_translation_language_list), as the
    # complete translation languages list will be dynamic based on some
    # content text are changed, where as the voiceover is a long term work and
    # we can allow a voice_artist to work for an exploration which needs a
    # little bit update in text translation.
    need_voice_artist_in_language_codes_set = set(
        exploration_opportunity_summary.need_voice_artist_in_language_codes)
    need_voice_artist_in_language_codes_set |= set(new_languages_for_voiceover)

    exploration_opportunity_summary.need_voice_artist_in_language_codes = list(
        need_voice_artist_in_language_codes_set)

    exploration_opportunity_summary.validate()

    _save_multi_exploration_opportunity_summary(
        [exploration_opportunity_summary])
Esempio n. 10
0
    def test_can_upload_exploration(self):
        with self.swap(constants, 'ALLOW_YAML_FILE_UPLOAD', True):
            self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME])
            self.login(self.CURRICULUM_ADMIN_EMAIL, is_super_admin=True)

            csrf_token = self.get_new_csrf_token()
            explorations_list = self.get_json(
                feconf.CREATOR_DASHBOARD_DATA_URL)['explorations_list']
            self.assertEqual(explorations_list, [])
            exp_a_id = self.post_json(
                '%s?yaml_file=%s' %
                (feconf.UPLOAD_EXPLORATION_URL, self.SAMPLE_YAML_CONTENT), {},
                csrf_token=csrf_token)[creator_dashboard.EXPLORATION_ID_KEY]
            explorations_list = self.get_json(
                feconf.CREATOR_DASHBOARD_DATA_URL)['explorations_list']
            exploration = exp_fetchers.get_exploration_by_id(exp_a_id)
            self.assertEqual(explorations_list[0]['id'], exp_a_id)
            self.assertEqual(exploration.to_yaml(), self.SAMPLE_YAML_CONTENT)
            self.logout()
Esempio n. 11
0
    def test_interactions_demo_exploration(self):
        exp_services.load_demo(self._DEMO_EXPLORATION_ID)
        exploration = exp_fetchers.get_exploration_by_id(
            self._DEMO_EXPLORATION_ID)

        all_interaction_ids = set(
            interaction_registry.Registry.get_all_interaction_ids())
        observed_interaction_ids = set()

        for state in exploration.states.values():
            observed_interaction_ids.add(state.interaction.id)

        missing_interaction_ids = (all_interaction_ids -
                                   observed_interaction_ids)
        self.assertEqual(
            len(missing_interaction_ids),
            0,
            msg=('Missing interaction IDs in demo exploration: %s' %
                 missing_interaction_ids))
Esempio n. 12
0
    def test_stats_events_successfully_updated(self):

        all_models = (stats_models.ExplorationStatsModel.get_all())
        self.assertEqual(all_models.count(), 0)

        exp_id = 'eid1'
        self.save_new_valid_exploration(exp_id, self.OWNER_EMAIL)
        exploration = exp_fetchers.get_exploration_by_id(exp_id)
        event_services.StatsEventsHandler.record(
            exp_id, exploration.version,
            {'state_stats_mapping': {
                'Introduction': {}
            }})

        all_models = stats_models.ExplorationStatsModel.get_all()
        self.assertEqual(all_models.count(), 1)
        model = all_models.get()
        self.assertEqual(model.exp_id, exp_id)
        self.assertEqual(model.exp_version, exploration.version)
Esempio n. 13
0
    def post(self, exploration_id):
        """Handles POST requests.

        Args:
            exploration_id: str. The ID of the exploration.
        """
        old_state_name = self.payload.get('old_state_name')
        # The reader's answer.
        answer = self.payload.get('answer')
        # Parameters associated with the learner.
        params = self.payload.get('params', {})
        # The version of the exploration.
        version = self.payload.get('version')
        if version is None:
            raise self.InvalidInputException(
                'NONE EXP VERSION: Answer Submit')
        session_id = self.payload.get('session_id')
        client_time_spent_in_secs = self.payload.get(
            'client_time_spent_in_secs')
        # The answer group and rule spec indexes, which will be used to get
        # the rule spec string.
        answer_group_index = self.payload.get('answer_group_index')
        rule_spec_index = self.payload.get('rule_spec_index')
        classification_categorization = self.payload.get(
            'classification_categorization')

        exploration = exp_fetchers.get_exploration_by_id(
            exploration_id, version=version)

        old_interaction = exploration.states[old_state_name].interaction

        old_interaction_instance = (
            interaction_registry.Registry.get_interaction_by_id(
                old_interaction.id))

        normalized_answer = old_interaction_instance.normalize_answer(answer)

        event_services.AnswerSubmissionEventHandler.record(
            exploration_id, version, old_state_name,
            exploration.states[old_state_name].interaction.id,
            answer_group_index, rule_spec_index, classification_categorization,
            session_id, client_time_spent_in_secs, params, normalized_answer)
        self.render_json({})
Esempio n. 14
0
    def post(self):
        payload = json.loads(self.request.body)
        user_id = payload['user_id']
        reference_dict = payload['reference_dict']

        message = feedback_services.get_message(
            reference_dict['thread_id'], reference_dict['message_id'])
        exploration = exp_fetchers.get_exploration_by_id(
            reference_dict['entity_id'])
        thread = feedback_services.get_thread(reference_dict['thread_id'])
        model = email_models.GeneralFeedbackEmailReplyToIdModel.get(
            user_id, reference_dict['thread_id'])
        reply_to_id = model.reply_to_id

        subject = 'New Oppia message in "%s"' % thread.subject
        email_manager.send_instant_feedback_message_email(
            user_id, message.author_id, message.text, subject,
            exploration.title, reference_dict['entity_id'],
            thread.subject, reply_to_id=reply_to_id)
Esempio n. 15
0
    def put(self, exploration_id):
        """Updates properties of the given exploration."""
        exploration = exp_fetchers.get_exploration_by_id(exploration_id)
        version = self.payload.get('version')
        _require_valid_version(version, exploration.version)

        commit_message = self.payload.get('commit_message')

        if (commit_message is not None
                and len(commit_message) > feconf.MAX_COMMIT_MESSAGE_LENGTH):
            raise self.InvalidInputException(
                'Commit messages must be at most %s characters long.' %
                feconf.MAX_COMMIT_MESSAGE_LENGTH)

        change_list_dict = self.payload.get('change_list')
        change_list = [
            exp_domain.ExplorationChange(change) for change in change_list_dict
        ]
        try:
            exploration_rights = rights_manager.get_exploration_rights(
                exploration_id)
            can_edit = rights_manager.check_can_edit_activity(
                self.user, exploration_rights)
            can_voiceover = rights_manager.check_can_voiceover_activity(
                self.user, exploration_rights)
            if can_edit:
                exp_services.update_exploration(self.user_id, exploration_id,
                                                change_list, commit_message)
            elif can_voiceover:
                exp_services.update_exploration(self.user_id,
                                                exploration_id,
                                                change_list,
                                                commit_message,
                                                is_by_voice_artist=True)
        except utils.ValidationError as e:
            raise self.InvalidInputException(e)

        exploration_data = exp_services.get_user_exploration_data(
            self.user_id, exploration_id)

        self.values.update(exploration_data)
        self.render_json(self.values)
Esempio n. 16
0
def _construct_exploration_suggestions(suggestions):
    """Returns exploration suggestions with current exploration content.

    Args:
        suggestions: list(BaseSuggestion). A list of suggestions.

    Returns:
        list(dict). List of suggestion dicts with an additional
        exploration_content_html field representing the target
        exploration's current content.
    """
    suggestion_dicts = []
    for suggestion in suggestions:
        exploration = exp_fetchers.get_exploration_by_id(suggestion.target_id)
        content_html = exploration.get_content_html(
            suggestion.change.state_name, suggestion.change.content_id)
        suggestion_dict = suggestion.to_dict()
        suggestion_dict['exploration_content_html'] = content_html
        suggestion_dicts.append(suggestion_dict)
    return suggestion_dicts
Esempio n. 17
0
    def test_interactions_demo_exploration(self):
        exp_services.load_demo(self._DEMO_EXPLORATION_ID)
        exploration = exp_fetchers.get_exploration_by_id(
            self._DEMO_EXPLORATION_ID)

        all_interaction_ids = set(
            interaction_registry.Registry.get_all_interaction_ids())
        observed_interaction_ids = set()

        for state in exploration.states.values():
            observed_interaction_ids.add(state.interaction.id)

        missing_interaction_ids = (
            all_interaction_ids - observed_interaction_ids)
        if list(missing_interaction_ids) != ['RatioExpressionInput']:
            # TODO(#10460): Remove this as soon as the learner's flow is added
            # for RatioExpressionInput.
            self.assertEqual(len(missing_interaction_ids), 0, msg=(
                'Missing interaction IDs in demo exploration: %s' %
                missing_interaction_ids))
    def test_dependencies_loaded_in_exploration_editor(self):
        exp_services.load_demo('0')

        # Register and login as an editor.
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
        self.login(self.EDITOR_EMAIL)

        # Verify that the exploration does not have a Skulpt dependency.
        exploration = exp_fetchers.get_exploration_by_id('0')
        interaction_ids = exploration.get_interaction_ids()
        all_dependency_ids = (interaction_registry.Registry.
                              get_deduplicated_dependency_ids(interaction_ids))

        self.assertNotIn('skulpt', all_dependency_ids)

        # However, Skulpt is loaded in the exploration editor anyway, since
        # all dependencies are loaded in the exploration editor.
        response = self.get_html_response('/create/0')
        response.mustcontain('skulpt')

        self.logout()
Esempio n. 19
0
    def put(self, exploration_id):
        """Updates properties of the given exploration."""
        exploration = exp_fetchers.get_exploration_by_id(exploration_id)
        version = self.payload.get('version')
        _require_valid_version(version, exploration.version)

        commit_message = self.payload.get('commit_message')
        change_list_dict = self.payload.get('change_list')
        change_list = [
            exp_domain.ExplorationChange(change) for change in change_list_dict]
        try:
            exp_services.update_exploration(
                self.user_id, exploration_id, change_list, commit_message)
        except utils.ValidationError as e:
            raise self.InvalidInputException(e)

        exploration_data = exp_services.get_user_exploration_data(
            self.user_id, exploration_id)

        self.values.update(exploration_data)
        self.render_json(self.values)
Esempio n. 20
0
    def map(model):
        if model.draft_change_list is None:
            return

        exploration = exp_fetchers.get_exploration_by_id(
            model.exploration_id, strict=False)

        if exploration is None:
            yield ('DISCARDED - Exploration is missing', model.id)
        elif model.draft_change_list_last_updated.timetuple().tm_year <= 2019:
            yield ('DISCARDED - Draft is old', model.id)
        else:
            return

        # Discard the draft.
        model.draft_change_list = None
        model.draft_change_list_last_updated = None
        model.draft_change_list_exp_version = None
        model.update_timestamps()
        model.put()

        yield ('SUCCESS - Discarded draft', 1)
Esempio n. 21
0
    def test_loading_old_exploration_does_not_break_domain_object_ctor(self):
        """This test attempts to load an exploration that is stored in the data
        store as pre-states schema version 0. The
        exp_fetchers.get_exploration_by_id function should properly load and
        convert the exploration without any issues. Structural changes to the
        states schema will not break the exploration domain class constructor.
        """
        exp_id = 'exp_id3'

        # Create a exploration with states schema version 0 and an old states
        # blob.
        self.save_new_exp_with_states_schema_v0(exp_id, self.albert_id,
                                                'Old Title')

        # Ensure the exploration was converted.
        exploration = exp_fetchers.get_exploration_by_id(exp_id)
        self.assertEqual(exploration.states_schema_version,
                         feconf.CURRENT_STATE_SCHEMA_VERSION)

        # The converted exploration should be up-to-date and properly
        # converted.
        self.assertEqual(exploration.to_yaml(), self.UPGRADED_EXP_YAML)
Esempio n. 22
0
    def test_create_and_accept_suggestion(self):
        with self.swap(feedback_models.GeneralFeedbackThreadModel,
                       'generate_new_thread_id',
                       self.mock_generate_new_thread_id):
            suggestion_services.create_suggestion(
                suggestion_models.SUGGESTION_TYPE_EDIT_STATE_CONTENT,
                suggestion_models.TARGET_TYPE_EXPLORATION, self.EXP_ID,
                self.target_version_at_submission, self.author_id, self.change,
                'test description', None)

        suggestion_id = self.THREAD_ID
        suggestion = suggestion_services.get_suggestion_by_id(suggestion_id)

        suggestion_services.accept_suggestion(suggestion, self.reviewer_id,
                                              self.COMMIT_MESSAGE, None)

        exploration = exp_fetchers.get_exploration_by_id(self.EXP_ID)

        self.assertEqual(exploration.states['State 1'].content.html,
                         '<p>new content</p>')

        self.assertEqual(suggestion.status, suggestion_models.STATUS_ACCEPTED)
Esempio n. 23
0
    def test_interactions_demo_exploration(self):
        exp_services.load_demo(self._DEMO_EXPLORATION_ID)
        exploration = exp_fetchers.get_exploration_by_id(
            self._DEMO_EXPLORATION_ID)

        all_interaction_ids = set(
            interaction_registry.Registry.get_all_interaction_ids())
        observed_interaction_ids = set()

        for state in exploration.states.values():
            observed_interaction_ids.add(state.interaction.id)

        missing_interaction_ids = (
            all_interaction_ids - observed_interaction_ids)
        if list(missing_interaction_ids) != ['MathExpressionInput']:
            # Ignoring the lack of the MathExpressionInput since it is going
            # to be deprecated and explorations that use it will now be using
            # one of AlgebraicExpressionInput, NumericExpressionInput, or
            # MathEquationInput.
            self.assertEqual(len(missing_interaction_ids), 0, msg=(
                'Missing interaction IDs in demo exploration: %s' %
                missing_interaction_ids))
Esempio n. 24
0
    def map(item):
        if item.deleted:
            return

        # Do not upgrade explorations that fail non-strict validation.
        old_exploration = exp_fetchers.get_exploration_by_id(item.id)
        try:
            old_exploration.validate()
        except Exception as e:
            logging.error('Exploration %s failed non-strict validation: %s' %
                          (item.id, e))
            return

        # If the exploration model being stored in the datastore is not the
        # most up-to-date states schema version, then update it.
        if (item.states_schema_version != feconf.CURRENT_STATE_SCHEMA_VERSION):
            # Note: update_exploration does not need to apply a change list in
            # order to perform a migration. See the related comment in
            # exp_services.apply_change_list for more information.
            #
            # Note: from_version and to_version really should be int, but left
            # as str to conform with legacy data.
            commit_cmds = [
                exp_domain.ExplorationChange({
                    'cmd':
                    exp_domain.CMD_MIGRATE_STATES_SCHEMA_TO_LATEST_VERSION,
                    'from_version':
                    python_utils.UNICODE(item.states_schema_version),
                    'to_version':
                    python_utils.UNICODE(feconf.CURRENT_STATE_SCHEMA_VERSION)
                })
            ]
            exp_services.update_exploration(
                feconf.MIGRATION_BOT_USERNAME, item.id, commit_cmds,
                'Update exploration states from schema version %d to %d.' %
                (item.states_schema_version,
                 feconf.CURRENT_STATE_SCHEMA_VERSION))
            yield ('SUCCESS', item.id)
Esempio n. 25
0
    def post(self):
        payload = json.loads(self.request.body)
        user_id = payload['user_id']
        reference_dict = payload['reference_dict']

        message = feedback_services.get_message(
            reference_dict['thread_id'], reference_dict['message_id'])
        exploration = exp_fetchers.get_exploration_by_id(
            reference_dict['entity_id'])
        thread = feedback_services.get_thread(reference_dict['thread_id'])
        feedback_thread_reply_info = (
            email_services.get_feedback_thread_reply_info_by_user_and_thread(
                user_id, reference_dict['thread_id']))
        if feedback_thread_reply_info is None:
            raise self.InvalidInputException(
                'Feedback thread for current user and thread_id does not exist')

        subject = 'New Oppia message in "%s"' % thread.subject
        email_manager.send_instant_feedback_message_email(
            user_id, message.author_id, message.text, subject,
            exploration.title, reference_dict['entity_id'],
            thread.subject, reply_to_id=feedback_thread_reply_info.reply_to_id)
        self.render_json({})
Esempio n. 26
0
def get_text_to_create_voiceover_application(target_type, target_id,
                                             language_code):
    """Returns a text to voiceover for a voiceover application.

    Args:
        target_type: str. The string representing the type of the target entity.
        target_id: str. The ID of the target entity.
        language_code: str. The language code for the content.

    Returns:
        str. The text which can be voiceover for a voiceover application.
    """
    if target_type == feconf.ENTITY_TYPE_EXPLORATION:
        exploration = exp_fetchers.get_exploration_by_id(target_id)
        init_state_name = exploration.init_state_name
        state = exploration.states[init_state_name]
        if exploration.language_code == language_code:
            return state.content.html
        else:
            return state.written_translations.get_translated_content(
                state.content.content_id, language_code)
    else:
        raise Exception('Invalid target type: %s' % target_type)
Esempio n. 27
0
    def post(self):
        payload = json.loads(self.request.body)
        user_id = payload['user_id']
        references = feedback_services.get_feedback_message_references(user_id)
        if not references:
            # Model may not exist if user has already attended to the feedback.
            return

        transaction_services.run_in_transaction(
            feedback_services.update_feedback_email_retries, user_id)

        messages = {}
        for reference in references:
            message = feedback_services.get_message(reference.thread_id,
                                                    reference.message_id)

            exploration = exp_fetchers.get_exploration_by_id(
                reference.entity_id)

            message_text = message.text
            if len(message_text) > 200:
                message_text = message_text[:200] + '...'

            if exploration.id in messages:
                messages[exploration.id]['messages'].append(message_text)
            else:
                messages[exploration.id] = {
                    'title': exploration.title,
                    'messages': [message_text]
                }

        email_manager.send_feedback_message_email(user_id, messages)
        transaction_services.run_in_transaction(
            feedback_services.pop_feedback_message_references, user_id,
            len(references))
        self.render_json({})
Esempio n. 28
0
    def get(self):
        """Handles GET requests."""
        language_code = self.request.get('language_code')
        exp_id = self.request.get('exp_id')

        if not utils.is_supported_audio_language_code(language_code):
            raise self.InvalidInputException('Invalid language_code: %s' % (
                language_code))

        if not opportunity_services.is_exploration_available_for_contribution(
                exp_id):
            raise self.InvalidInputException('Invalid exp_id: %s' % exp_id)

        exp = exp_fetchers.get_exploration_by_id(exp_id)
        state_names_to_content_id_mapping = exp.get_translatable_text(
            language_code)

        self.values = {
            'state_names_to_content_id_mapping': (
                state_names_to_content_id_mapping),
            'version': exp.version
        }

        self.render_json(self.values)
Esempio n. 29
0
def _does_exploration_exist(exploration_id, version, collection_id):
    """Returns if an exploration exists.

    Args:
        exploration_id: str. The ID of the exploration.
        version: int or None. The version of the exploration.
        collection_id: str. ID of the collection.

    Returns:
        bool. True if the exploration exists False otherwise.
    """
    exploration = exp_fetchers.get_exploration_by_id(
        exploration_id, strict=False, version=version)

    if exploration is None:
        return False

    if collection_id:
        collection = collection_services.get_collection_by_id(
            collection_id, strict=False)
        if collection is None:
            return False

    return True
Esempio n. 30
0
    def test_create_and_reject_suggestion(self):
        with self.swap(feedback_models.GeneralFeedbackThreadModel,
                       'generate_new_thread_id',
                       self.mock_generate_new_thread_id):
            suggestion_services.create_suggestion(
                suggestion_models.SUGGESTION_TYPE_EDIT_STATE_CONTENT,
                suggestion_models.TARGET_TYPE_EXPLORATION, self.EXP_ID,
                self.target_version_at_submission, self.author_id, self.change,
                'test description', None)

        suggestion_id = self.THREAD_ID
        suggestion = suggestion_services.get_suggestion_by_id(suggestion_id)

        suggestion_services.reject_suggestion(suggestion, self.reviewer_id,
                                              'Reject message')

        exploration = exp_fetchers.get_exploration_by_id(self.EXP_ID)
        thread_messages = feedback_services.get_messages(self.THREAD_ID)
        last_message = thread_messages[len(thread_messages) - 1]
        self.assertEqual(last_message.text, 'Reject message')
        self.assertEqual(exploration.states['State 1'].content.html,
                         '<p>old content</p>')

        self.assertEqual(suggestion.status, suggestion_models.STATUS_REJECTED)