Exemple #1
0
def _get_exploration_player_data(
        exploration_id, version, collection_id, can_edit):
    try:
        exploration = exp_services.get_exploration_by_id(
            exploration_id, version=version)
    except Exception:
        raise Exception

    collection_title = None
    if collection_id:
        try:
            collection = collection_services.get_collection_by_id(
                collection_id)
            collection_title = collection.title
        except Exception:
            raise Exception

    version = exploration.version

    # TODO(sll): Cache these computations.
    gadget_types = exploration.get_gadget_types()
    interaction_ids = exploration.get_interaction_ids()
    dependency_ids = (
        interaction_registry.Registry.get_deduplicated_dependency_ids(
            interaction_ids))
    dependencies_html, additional_angular_modules = (
        dependency_registry.Registry.get_deps_html_and_angular_modules(
            dependency_ids))

    gadget_templates = (
        gadget_registry.Registry.get_gadget_html(gadget_types))
    interaction_templates = (
        rte_component_registry.Registry.get_html_for_all_components() +
        interaction_registry.Registry.get_interaction_html(
            interaction_ids))

    return {
        'GADGET_SPECS': gadget_registry.Registry.get_all_specs(),
        'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
        'DEFAULT_TWITTER_SHARE_MESSAGE_PLAYER': (
            DEFAULT_TWITTER_SHARE_MESSAGE_PLAYER.value),
        'additional_angular_modules': additional_angular_modules,
        'can_edit': can_edit,
        'dependencies_html': jinja2.utils.Markup(
            dependencies_html),
        'exploration_title': exploration.title,
        'exploration_version': version,
        'collection_id': collection_id,
        'collection_title': collection_title,
        'gadget_templates': jinja2.utils.Markup(gadget_templates),
        'interaction_templates': jinja2.utils.Markup(
            interaction_templates),
        'is_private': rights_manager.is_exploration_private(
            exploration_id),
        # Note that this overwrites the value in base.py.
        'meta_name': exploration.title,
        # Note that this overwrites the value in base.py.
        'meta_description': utils.capitalize_string(exploration.objective),
        'nav_mode': feconf.NAV_MODE_EXPLORE,
    }
Exemple #2
0
def _get_exploration_player_data(
        exploration_id, version, collection_id, can_edit):
    try:
        exploration = exp_services.get_exploration_by_id(
            exploration_id, version=version)
    except Exception:
        raise Exception

    collection_title = None
    if collection_id:
        try:
            collection = collection_services.get_collection_by_id(
                collection_id)
            collection_title = collection.title
        except Exception:
            raise Exception

    version = exploration.version

    # TODO(sll): Cache these computations.
    gadget_types = exploration.get_gadget_types()
    interaction_ids = exploration.get_interaction_ids()
    dependency_ids = (
        interaction_registry.Registry.get_deduplicated_dependency_ids(
            interaction_ids))
    dependencies_html, additional_angular_modules = (
        dependency_registry.Registry.get_deps_html_and_angular_modules(
            dependency_ids))

    gadget_templates = (
        gadget_registry.Registry.get_gadget_html(gadget_types))
    interaction_templates = (
        rte_component_registry.Registry.get_html_for_all_components() +
        interaction_registry.Registry.get_interaction_html(
            interaction_ids))

    return {
        'GADGET_SPECS': gadget_registry.Registry.get_all_specs(),
        'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
        'DEFAULT_TWITTER_SHARE_MESSAGE_PLAYER': (
            DEFAULT_TWITTER_SHARE_MESSAGE_PLAYER.value),
        'additional_angular_modules': additional_angular_modules,
        'can_edit': can_edit,
        'dependencies_html': jinja2.utils.Markup(
            dependencies_html),
        'exploration_title': exploration.title,
        'exploration_version': version,
        'collection_id': collection_id,
        'collection_title': collection_title,
        'gadget_templates': jinja2.utils.Markup(gadget_templates),
        'interaction_templates': jinja2.utils.Markup(
            interaction_templates),
        'is_private': rights_manager.is_exploration_private(
            exploration_id),
        # Note that this overwrites the value in base.py.
        'meta_name': exploration.title,
        # Note that this overwrites the value in base.py.
        'meta_description': utils.capitalize_string(exploration.objective),
        'nav_mode': feconf.NAV_MODE_EXPLORE,
    }
Exemple #3
0
    def get(self, exploration_id):
        """Handles GET requests."""
        version = self.request.get('v')
        if not version:
            # The default value for a missing parameter seems to be ''.
            version = None
        else:
            version = int(version)

        try:
            exploration = exp_services.get_exploration_by_id(exploration_id,
                                                             version=version)
        except Exception as e:
            raise self.PageNotFoundException(e)

        if not rights_manager.Actor(self.user_id).can_view(exploration_id):
            raise self.PageNotFoundException

        is_iframed = (self.request.get('iframed') == 'true')

        # TODO(sll): Cache these computations.
        interactive_widget_ids = exploration.get_interactive_widget_ids()
        widget_dependency_ids = (
            widget_registry.Registry.get_deduplicated_dependency_ids(
                interactive_widget_ids))
        widget_dependencies_html, additional_angular_modules = (
            dependency_registry.Registry.get_deps_html_and_angular_modules(
                widget_dependency_ids))

        widget_js_directives = (
            widget_registry.Registry.get_noninteractive_widget_js() +
            widget_registry.Registry.get_interactive_widget_js(
                interactive_widget_ids))

        self.values.update({
            'additional_angular_modules':
            additional_angular_modules,
            'exploration_version':
            version,
            'iframed':
            is_iframed,
            'is_private':
            rights_manager.is_exploration_private(exploration_id),
            'nav_mode':
            feconf.NAV_MODE_EXPLORE,
            'skin_html':
            skins_services.Registry.get_skin_html(exploration.default_skin),
            'widget_dependencies_html':
            jinja2.utils.Markup(widget_dependencies_html),
            'widget_js_directives':
            jinja2.utils.Markup(widget_js_directives),
        })

        if is_iframed:
            self.render_template('player/exploration_player.html',
                                 iframe_restriction=None)
        else:
            self.render_template('player/exploration_player.html')
    def _get_domain_object_validation_type(cls, item):
        exp_rights = rights_manager.get_exploration_rights(item.id,
                                                           strict=False)

        if exp_rights is None:
            return base_model_validators.VALIDATION_MODE_NEUTRAL

        if rights_manager.is_exploration_private(item.id):
            return base_model_validators.VALIDATION_MODE_NON_STRICT

        return base_model_validators.VALIDATION_MODE_STRICT
Exemple #5
0
def _get_exploration_player_data(
        exploration_id, version, collection_id, can_edit):
    """Returns a dict of exploration player data.

    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.
        can_edit: bool. Whether the given user can edit this activity.

    Returns:
        dict. A dict of exploration player data.
        The keys and values of the dict are as follows:
        - 'can_edit': bool. Whether the given user can edit this activity.
        - 'exploration_title': str. Title of exploration.
        - 'exploration_version': int. The version of the exploration.
        - 'collection_id': str. ID of the collection.
        - 'collection_title': str. Title of collection.
            required by the given exploration ID.
        - 'is_private': bool. Whether the exploration is private or not.
        - 'meta_name': str. Title of exploration.
        - 'meta_description': str. Objective of exploration.
    """
    try:
        exploration = exp_fetchers.get_exploration_by_id(
            exploration_id, version=version)
    except Exception:
        raise Exception

    collection_title = None
    if collection_id:
        try:
            collection = collection_services.get_collection_by_id(
                collection_id)
            collection_title = collection.title
        except Exception:
            raise Exception

    version = exploration.version

    return {
        'can_edit': can_edit,
        'exploration_title': exploration.title,
        'exploration_version': version,
        'collection_id': collection_id,
        'collection_title': collection_title,
        'is_private': rights_manager.is_exploration_private(
            exploration_id),
        # Note that this overwrites the value in base.py.
        'meta_name': exploration.title,
        # Note that this overwrites the value in base.py.
        'meta_description': utils.capitalize_string(exploration.objective),
    }
Exemple #6
0
    def get(self, exploration_id):
        """Handles GET requests."""
        version = self.request.get('v')
        if not version:
            # The default value for a missing parameter seems to be ''.
            version = None
        else:
            version = int(version)

        try:
            exploration = exp_services.get_exploration_by_id(
                exploration_id, version=version)
        except Exception as e:
            raise self.PageNotFoundException(e)

        if not rights_manager.Actor(self.user_id).can_view(exploration_id):
            raise self.PageNotFoundException

        is_iframed = (self.request.get('iframed') == 'true')

        # TODO(sll): Cache these computations.
        interactive_widget_ids = exploration.get_interactive_widget_ids()
        widget_dependency_ids = (
            widget_registry.Registry.get_deduplicated_dependency_ids(
                interactive_widget_ids))
        widget_dependencies_html, additional_angular_modules = (
            dependency_registry.Registry.get_deps_html_and_angular_modules(
                widget_dependency_ids))

        widget_js_directives = (
            widget_registry.Registry.get_noninteractive_widget_js() +
            widget_registry.Registry.get_interactive_widget_js(
                interactive_widget_ids))

        self.values.update({
            'additional_angular_modules': additional_angular_modules,
            'exploration_version': version,
            'iframed': is_iframed,
            'is_private': rights_manager.is_exploration_private(
                exploration_id),
            'nav_mode': feconf.NAV_MODE_EXPLORE,
            'skin_html': skins_services.Registry.get_skin_html(
                exploration.default_skin),
            'widget_dependencies_html': jinja2.utils.Markup(
                widget_dependencies_html),
            'widget_js_directives': jinja2.utils.Markup(widget_js_directives),
        })

        if is_iframed:
            self.render_template(
                'player/exploration_player.html', iframe_restriction=None)
        else:
            self.render_template('player/exploration_player.html')
Exemple #7
0
    def _validate_explorations_are_public(
            cls, item, field_name_to_external_model_references):
        """Validates that explorations for model are public.

        Args:
            item: ndb.Model. BaseUserModel to validate.
            field_name_to_external_model_references:
                dict(str, (list(ExternalModelReference))).
                A dict keyed by field name. The field name represents
                a unique identifier provided by the storage
                model to which the external model is associated. Each value
                contains a list of ExternalModelReference objects corresponding
                to the field_name. For examples, all the external Exploration
                Models corresponding to a storage model can be associated
                with the field name 'exp_ids'. This dict is used for
                validation of External Model properties linked to the
                storage model.
        """
        if 'exploration_ids' not in field_name_to_external_model_references:
            return

        exp_ids = []
        exploration_model_references = (
            field_name_to_external_model_references['exploration_ids'])

        for exploration_model_reference in exploration_model_references:
            exploration_model = exploration_model_reference.model_instance

            if exploration_model is None or exploration_model.deleted:
                model_class = exploration_model_reference.model_class
                model_id = exploration_model_reference.model_id
                cls._add_error(
                    'exploration_ids %s' % ERROR_CATEGORY_FIELD_CHECK,
                    'Entity id %s: based on field exploration_ids having'
                    ' value %s, expected model %s with id %s but it doesn\'t'
                    ' exist' %
                    (item.id, model_id, model_class.__name__, model_id))
                continue
            exp_ids.append(exploration_model.id)

        private_exp_ids = [
            exp_id for exp_id in exp_ids
            if (rights_manager.is_exploration_private(exp_id))
        ]
        if private_exp_ids:
            cls._add_error(
                'public exploration check',
                'Entity id %s: Explorations with ids %s are private' %
                (item.id, private_exp_ids))
Exemple #8
0
def validate_exps_in_collection_are_public(collection):
    """Validates that explorations in a given collection are public.

    Args:
        collection: Collection. Collection to be validated.

    Raises:
        ValidationError: The collection contains at least one private
            exploration.
    """
    for exploration_id in collection.exploration_ids:
        if rights_manager.is_exploration_private(exploration_id):
            raise utils.ValidationError(
                'Cannot reference a private exploration within a public '
                'collection, exploration ID: %s' % exploration_id)
Exemple #9
0
    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))
Exemple #10
0
    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)
            )
Exemple #11
0
def get_learner_collection_dict_by_id(collection_id,
                                      user_id,
                                      strict=True,
                                      allow_invalid_explorations=False,
                                      version=None):
    """Creates and returns a dictionary representation of a collection given by
    the provided collection ID. This dictionary contains extra information
    along with the dict returned by collection_domain.Collection.to_dict()
    which includes useful data for the collection learner view. The information
    includes progress in the collection, information about explorations
    referenced within the collection, and a slightly nicer data structure for
    frontend work.
    This raises a ValidationError if the collection retrieved using the given
    ID references non-existent explorations.
    which includes useful data for the collection learner view.
    """
    collection = collection_services.get_collection_by_id(collection_id,
                                                          strict=strict,
                                                          version=version)

    exp_ids = collection.exploration_ids
    exp_summary_dicts = get_displayable_exp_summary_dicts_matching_ids(
        exp_ids, editor_user_id=user_id)
    exp_summaries_dict_map = {
        exp_summary_dict['id']: exp_summary_dict
        for exp_summary_dict in exp_summary_dicts
    }

    # TODO(bhenning): Users should not be recommended explorations they have
    # completed outside the context of a collection (see #1461).
    next_exploration_ids = None
    completed_exp_ids = None
    if user_id:
        completed_exp_ids = (
            collection_services.get_valid_completed_exploration_ids(
                user_id, collection_id, collection))
        next_exploration_ids = collection.get_next_exploration_ids(
            completed_exp_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_exp_ids = []

    collection_dict = collection.to_dict()
    collection_dict['skills'] = collection.skills
    collection_dict['playthrough_dict'] = {
        'next_exploration_ids': next_exploration_ids,
        'completed_exploration_ids': completed_exp_ids
    }
    collection_dict['version'] = collection.version
    collection_is_public = rights_manager.is_collection_public(collection_id)

    # 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']:
        exploration_id = collection_node['exploration_id']
        summary_dict = exp_summaries_dict_map.get(exploration_id)
        if not allow_invalid_explorations:
            if not summary_dict:
                raise utils.ValidationError(
                    'Expected collection to only reference valid '
                    'explorations, but found an exploration with ID: %s (was '
                    'the exploration deleted or is it a private exploration '
                    'that you do not have edit access to?)' % exploration_id)
            if collection_is_public and rights_manager.is_exploration_private(
                    exploration_id):
                raise utils.ValidationError(
                    'Cannot reference a private exploration within a public '
                    'collection, exploration ID: %s' % exploration_id)

        if summary_dict:
            collection_node['exploration_summary'] = summary_dict
        else:
            collection_node['exploration_summary'] = None

    return collection_dict
Exemple #12
0
    def get(self, exploration_id):
        """Handles GET requests."""
        version = self.request.get('v')
        if not version:
            # The default value for a missing parameter seems to be ''.
            version = None
        else:
            version = int(version)

        try:
            exploration = exp_services.get_exploration_by_id(
                exploration_id, version=version)
        except Exception as e:
            raise self.PageNotFoundException(e)

        version = exploration.version

        if not rights_manager.Actor(self.user_id).can_view(exploration_id):
            raise self.PageNotFoundException

        is_iframed = (self.request.get('iframed') == 'true')

        # TODO(sll): Cache these computations.
        interaction_ids = exploration.get_interaction_ids()
        dependency_ids = (
            interaction_registry.Registry.get_deduplicated_dependency_ids(
                interaction_ids))
        dependencies_html, additional_angular_modules = (
            dependency_registry.Registry.get_deps_html_and_angular_modules(
                dependency_ids))

        interaction_templates = (
            rte_component_registry.Registry.get_html_for_all_components() +
            interaction_registry.Registry.get_interaction_html(
                interaction_ids))

        self.values.update({
            'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
            'additional_angular_modules': additional_angular_modules,
            'can_edit': (
                bool(self.username) and
                self.username not in config_domain.BANNED_USERNAMES.value and
                rights_manager.Actor(self.user_id).can_edit(exploration_id)
            ),
            'dependencies_html': jinja2.utils.Markup(
                dependencies_html),
            'exploration_title': exploration.title,
            'exploration_version': version,
            'iframed': is_iframed,
            'interaction_templates': jinja2.utils.Markup(
                interaction_templates),
            'is_private': rights_manager.is_exploration_private(
                exploration_id),
            'nav_mode': feconf.NAV_MODE_EXPLORE,
            'skin_templates': jinja2.utils.Markup(
                skins_services.Registry.get_skin_templates(
                    [exploration.default_skin])),
            'skin_js_url': skins_services.Registry.get_skin_js_url(
                exploration.default_skin),
            'skin_tag': jinja2.utils.Markup(
                skins_services.Registry.get_skin_tag(exploration.default_skin)
            ),
            'title': exploration.title,
        })

        if is_iframed:
            self.render_template(
                'player/exploration_player.html', iframe_restriction=None)
        else:
            self.render_template('player/exploration_player.html')
Exemple #13
0
def get_learner_collection_dict_by_id(collection_id,
                                      user,
                                      strict=True,
                                      allow_invalid_explorations=False,
                                      version=None):
    """Gets a dictionary representation of a collection given by the provided
    collection ID. This dict includes user-specific playthrough information.

    Args:
        collection_id: str. The id of the collection.
        user: UserActionsInfo. Object having user_id, role and actions for
            given user.
        strict: bool. Whether to fail noisily if no collection with the given
            id exists in the datastore.
        allow_invalid_explorations: bool. Whether to also return explorations
            that are invalid, such as deleted/private explorations.
        version: str or None. The version number of the collection to be
            retrieved. If it is None, the latest version will be retrieved.

    Returns:
        dict. A dictionary that contains extra information along with the dict
        returned by collection_domain.Collection.to_dict() which includes useful
        data for the collection learner view. The information includes progress
        in the collection, information about explorations referenced within the
        collection, and a slightly nicer data structure for frontend work.

    Raises:
        ValidationError. If the collection retrieved using the given
            ID references non-existent explorations.
    """
    collection = collection_services.get_collection_by_id(collection_id,
                                                          strict=strict,
                                                          version=version)

    exp_ids = collection.exploration_ids
    exp_summary_dicts = get_displayable_exp_summary_dicts_matching_ids(
        exp_ids, user=user)
    exp_summaries_dict_map = {
        exp_summary_dict['id']: exp_summary_dict
        for exp_summary_dict in exp_summary_dicts
    }

    # TODO(bhenning): Users should not be recommended explorations they have
    # completed outside the context of a collection (see #1461).
    next_exploration_id = None
    completed_exp_ids = None
    if user.user_id:
        completed_exp_ids = (
            collection_services.get_valid_completed_exploration_ids(
                user.user_id, collection))
        next_exploration_id = collection.get_next_exploration_id(
            completed_exp_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 exploration.
        next_exploration_id = collection.first_exploration_id
        completed_exp_ids = []

    collection_dict = collection.to_dict()
    collection_dict['nodes'] = [node.to_dict() for node in collection.nodes]

    collection_dict['playthrough_dict'] = {
        'next_exploration_id': next_exploration_id,
        'completed_exploration_ids': completed_exp_ids
    }
    collection_dict['version'] = collection.version
    collection_is_public = rights_manager.is_collection_public(collection_id)

    # 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']:
        exploration_id = collection_node['exploration_id']
        summary_dict = exp_summaries_dict_map.get(exploration_id)
        if not allow_invalid_explorations:
            if not summary_dict:
                raise utils.ValidationError(
                    'Expected collection to only reference valid '
                    'explorations, but found an exploration with ID: %s (was '
                    'the exploration deleted or is it a private exploration '
                    'that you do not have edit access to?)' % exploration_id)
            if collection_is_public and rights_manager.is_exploration_private(
                    exploration_id):
                raise utils.ValidationError(
                    'Cannot reference a private exploration within a public '
                    'collection, exploration ID: %s' % exploration_id)

        if summary_dict:
            collection_node['exploration_summary'] = summary_dict
        else:
            collection_node['exploration_summary'] = None

    return collection_dict
def validate_exps_in_collection_are_public(collection):
    for exploration_id in collection.exploration_ids:
        if rights_manager.is_exploration_private(exploration_id):
            raise utils.ValidationError(
                'Cannot reference a private exploration within a public '
                'collection, exploration ID: %s' % exploration_id)
Exemple #15
0
    def get(self, exploration_id):
        """Handles GET requests."""
        version_str = self.request.get('v')
        version = int(version_str) if version_str else None

        # Note: this is an optional argument and will be None when the
        # exploration is being played outside the context of a collection.
        collection_id = self.request.get('collection_id')

        try:
            exploration = exp_services.get_exploration_by_id(exploration_id,
                                                             version=version)
        except Exception as e:
            raise self.PageNotFoundException(e)

        collection_title = None
        if collection_id:
            try:
                collection = collection_services.get_collection_by_id(
                    collection_id)
                collection_title = collection.title
            except Exception as e:
                raise self.PageNotFoundException(e)

        version = exploration.version

        if not rights_manager.Actor(self.user_id).can_view(
                feconf.ACTIVITY_TYPE_EXPLORATION, exploration_id):
            raise self.PageNotFoundException

        is_iframed = (self.request.get('iframed') == 'true')

        # TODO(sll): Cache these computations.
        gadget_types = exploration.get_gadget_types()
        interaction_ids = exploration.get_interaction_ids()
        dependency_ids = (interaction_registry.Registry.
                          get_deduplicated_dependency_ids(interaction_ids))
        dependencies_html, additional_angular_modules = (
            dependency_registry.Registry.get_deps_html_and_angular_modules(
                dependency_ids))

        gadget_templates = (
            gadget_registry.Registry.get_gadget_html(gadget_types))

        interaction_templates = (
            rte_component_registry.Registry.get_html_for_all_components() +
            interaction_registry.Registry.get_interaction_html(interaction_ids)
        )

        self.values.update({
            'GADGET_SPECS':
            gadget_registry.Registry.get_all_specs(),
            'INTERACTION_SPECS':
            interaction_registry.Registry.get_all_specs(),
            'DEFAULT_TWITTER_SHARE_MESSAGE_PLAYER':
            (DEFAULT_TWITTER_SHARE_MESSAGE_PLAYER.value),
            'additional_angular_modules':
            additional_angular_modules,
            'can_edit':
            (bool(self.username)
             and self.username not in config_domain.BANNED_USERNAMES.value
             and rights_manager.Actor(self.user_id).can_edit(
                 feconf.ACTIVITY_TYPE_EXPLORATION, exploration_id)),
            'dependencies_html':
            jinja2.utils.Markup(dependencies_html),
            'exploration_title':
            exploration.title,
            'exploration_version':
            version,
            'collection_id':
            collection_id,
            'collection_title':
            collection_title,
            'gadget_templates':
            jinja2.utils.Markup(gadget_templates),
            'iframed':
            is_iframed,
            'interaction_templates':
            jinja2.utils.Markup(interaction_templates),
            'is_private':
            rights_manager.is_exploration_private(exploration_id),
            # Note that this overwrites the value in base.py.
            'meta_name':
            exploration.title,
            # Note that this overwrites the value in base.py.
            'meta_description':
            utils.capitalize_string(exploration.objective),
            'nav_mode':
            feconf.NAV_MODE_EXPLORE,
        })

        if is_iframed:
            self.render_template('player/exploration_player.html',
                                 iframe_restriction=None)
        else:
            self.render_template('player/exploration_player.html')
Exemple #16
0
def validate_exps_in_collection_are_public(collection):
    for exploration_id in collection.exploration_ids:
        if rights_manager.is_exploration_private(exploration_id):
            raise utils.ValidationError(
                'Cannot reference a private exploration within a public '
                'collection, exploration ID: %s' % exploration_id)
Exemple #17
0
def get_learner_collection_dict_by_id(
        collection_id, user_id, strict=True, allow_invalid_explorations=False,
        version=None):
    """Creates and returns a dictionary representation of a collection given by
    the provided collection ID. This dictionary contains extra information
    along with the dict returned by collection_domain.Collection.to_dict()
    which includes useful data for the collection learner view. The information
    includes progress in the collection, information about explorations
    referenced within the collection, and a slightly nicer data structure for
    frontend work.
    This raises a ValidationError if the collection retrieved using the given
    ID references non-existent explorations.
    which includes useful data for the collection learner view.
    """
    collection = collection_services.get_collection_by_id(
        collection_id, strict=strict, version=version)

    exp_ids = collection.exploration_ids
    exp_summary_dicts = get_displayable_exp_summary_dicts_matching_ids(
        exp_ids, editor_user_id=user_id)
    exp_summaries_dict_map = {
        exp_summary_dict['id']: exp_summary_dict
        for exp_summary_dict in exp_summary_dicts
    }

    # TODO(bhenning): Users should not be recommended explorations they have
    # completed outside the context of a collection (see #1461).
    next_exploration_ids = None
    completed_exp_ids = None
    if user_id:
        completed_exp_ids = (
            collection_services.get_valid_completed_exploration_ids(
                user_id, collection_id, collection))
        next_exploration_ids = collection.get_next_exploration_ids(
            completed_exp_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_exp_ids = []

    collection_dict = collection.to_dict()
    collection_dict['skills'] = collection.skills
    collection_dict['playthrough_dict'] = {
        'next_exploration_ids': next_exploration_ids,
        'completed_exploration_ids': completed_exp_ids
    }
    collection_dict['version'] = collection.version
    collection_is_public = rights_manager.is_collection_public(collection_id)

    # 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']:
        exploration_id = collection_node['exploration_id']
        summary_dict = exp_summaries_dict_map.get(exploration_id)
        if not allow_invalid_explorations:
            if not summary_dict:
                raise utils.ValidationError(
                    'Expected collection to only reference valid '
                    'explorations, but found an exploration with ID: %s (was '
                    'the exploration deleted or is it a private exploration '
                    'that you do not have edit access to?)'
                    % exploration_id)
            if collection_is_public and rights_manager.is_exploration_private(
                    exploration_id):
                raise utils.ValidationError(
                    'Cannot reference a private exploration within a public '
                    'collection, exploration ID: %s' % exploration_id)

        if summary_dict:
            collection_node['exploration_summary'] = summary_dict
        else:
            collection_node['exploration_summary'] = None

    return collection_dict
Exemple #18
0
    def get(self, exploration_id):
        """Handles GET requests."""
        version_str = self.request.get('v')
        version = int(version_str) if version_str else None

        # Note: this is an optional argument and will be None when the
        # exploration is being played outside the context of a collection.
        collection_id = self.request.get('collection_id')

        try:
            exploration = exp_services.get_exploration_by_id(
                exploration_id, version=version)
        except Exception as e:
            raise self.PageNotFoundException(e)

        collection_title = None
        if collection_id:
            try:
                collection = collection_services.get_collection_by_id(
                    collection_id)
                collection_title = collection.title
            except Exception as e:
                raise self.PageNotFoundException(e)

        version = exploration.version

        if not rights_manager.Actor(self.user_id).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id):
            raise self.PageNotFoundException

        is_iframed = (self.request.get('iframed') == 'true')

        # TODO(sll): Cache these computations.
        gadget_types = exploration.get_gadget_types()
        interaction_ids = exploration.get_interaction_ids()
        dependency_ids = (
            interaction_registry.Registry.get_deduplicated_dependency_ids(
                interaction_ids))
        dependencies_html, additional_angular_modules = (
            dependency_registry.Registry.get_deps_html_and_angular_modules(
                dependency_ids))

        gadget_templates = (
            gadget_registry.Registry.get_gadget_html(gadget_types))

        interaction_templates = (
            rte_component_registry.Registry.get_html_for_all_components() +
            interaction_registry.Registry.get_interaction_html(
                interaction_ids))

        self.values.update({
            'GADGET_SPECS': gadget_registry.Registry.get_all_specs(),
            'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
            'SHARING_OPTIONS': SHARING_OPTIONS.value,
            'SHARING_OPTIONS_TWITTER_TEXT': SHARING_OPTIONS_TWITTER_TEXT.value,
            'additional_angular_modules': additional_angular_modules,
            'can_edit': (
                bool(self.username) and
                self.username not in config_domain.BANNED_USERNAMES.value and
                rights_manager.Actor(self.user_id).can_edit(
                    rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id)
            ),
            'dependencies_html': jinja2.utils.Markup(
                dependencies_html),
            'exploration_title': exploration.title,
            'exploration_version': version,
            'collection_id': collection_id,
            'collection_title': collection_title,
            'gadget_templates': jinja2.utils.Markup(gadget_templates),
            'iframed': is_iframed,
            'interaction_templates': jinja2.utils.Markup(
                interaction_templates),
            'is_private': rights_manager.is_exploration_private(
                exploration_id),
            # Note that this overwrites the value in base.py.
            'meta_name': exploration.title,
            # Note that this overwrites the value in base.py.
            'meta_description': utils.capitalize_string(exploration.objective),
            'nav_mode': feconf.NAV_MODE_EXPLORE,
        })

        if is_iframed:
            self.render_template(
                'player/exploration_player.html', iframe_restriction=None)
        else:
            self.render_template('player/exploration_player.html')
Exemple #19
0
    def get(self, exploration_id):
        """Handles GET requests."""
        version = self.request.get('v')
        if not version:
            # The default value for a missing parameter seems to be ''.
            version = None
        else:
            version = int(version)

        try:
            exploration = exp_services.get_exploration_by_id(
                exploration_id, version=version)
        except Exception as e:
            raise self.PageNotFoundException(e)

        version = exploration.version

        if not rights_manager.Actor(self.user_id).can_view(exploration_id):
            raise self.PageNotFoundException

        is_iframed = (self.request.get('iframed') == 'true')

        # TODO(sll): Cache these computations.
        gadget_ids = exploration.get_gadget_ids()
        interaction_ids = exploration.get_interaction_ids()
        dependency_ids = (
            interaction_registry.Registry.get_deduplicated_dependency_ids(
                interaction_ids))
        dependencies_html, additional_angular_modules = (
            dependency_registry.Registry.get_deps_html_and_angular_modules(
                dependency_ids))

        gadget_templates = (
            gadget_registry.Registry.get_gadget_html(gadget_ids))

        interaction_templates = (
            rte_component_registry.Registry.get_html_for_all_components() +
            interaction_registry.Registry.get_interaction_html(
                interaction_ids))

        self.values.update({
            'GADGET_SPECS': gadget_registry.Registry.get_all_specs(),
            'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
            'SHARING_OPTIONS': SHARING_OPTIONS.value,
            'SHARING_OPTIONS_TWITTER_TEXT': SHARING_OPTIONS_TWITTER_TEXT.value,
            'additional_angular_modules': additional_angular_modules,
            'can_edit': (
                bool(self.username) and
                self.username not in config_domain.BANNED_USERNAMES.value and
                rights_manager.Actor(self.user_id).can_edit(exploration_id)
            ),
            'dependencies_html': jinja2.utils.Markup(
                dependencies_html),
            'exploration_title': exploration.title,
            'exploration_version': version,
            'gadget_templates': jinja2.utils.Markup(gadget_templates),
            'iframed': is_iframed,
            'interaction_templates': jinja2.utils.Markup(
                interaction_templates),
            'is_private': rights_manager.is_exploration_private(
                exploration_id),
            # Note that this overwrites the value in base.py.
            'meta_name': exploration.title,
            # Note that this overwrites the value in base.py.
            'meta_description': self._make_first_letter_uppercase(
                exploration.objective),
            'nav_mode': feconf.NAV_MODE_EXPLORE,
            'skin_templates': jinja2.utils.Markup(
                skins_services.Registry.get_skin_templates(
                    [exploration.default_skin])),
            'skin_js_url': skins_services.Registry.get_skin_js_url(
                exploration.default_skin),
            'skin_tag': jinja2.utils.Markup(
                skins_services.Registry.get_skin_tag(exploration.default_skin)
            ),
        })

        if is_iframed:
            self.render_template(
                'player/exploration_player.html', iframe_restriction=None)
        else:
            self.render_template('player/exploration_player.html')
Exemple #20
0
def _get_exploration_player_data(
        exploration_id, version, collection_id, can_edit):
    """Returns a dict of exploration player data.

    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.
        can_edit: bool. Whether the given user can edit this activity.

    Returns:
        dict. A dict of exploration player data.
        The keys and values of the dict are as follows:
        - 'INTERACTION_SPECS': dict. A dict containing the full specs of each
            interaction. Contains interaction ID and a list of instances of
            all interactions.
        - 'additional_angular_modules': list. A de-duplicated list of strings,
            each representing an additional angular module that should be
            loaded.
        - 'can_edit': bool. Whether the given user can edit this activity.
        - 'dependencies_html': str. The additional HTML to insert on the page.
        - 'exploration_title': str. Title of exploration.
        - 'exploration_version': int. The version of the exploration.
        - 'collection_id': str. ID of the collection.
        - 'collection_title': str. Title of collection.
        - 'interaction_templates': str. The HTML bodies of the interactions
            required by the given exploration ID.
        - 'is_private': bool. Whether the exploration is private or not.
        - 'meta_name': str. Title of exploration.
        - 'meta_description': str. Objective of exploration.
    """
    try:
        exploration = exp_fetchers.get_exploration_by_id(
            exploration_id, version=version)
    except Exception:
        raise Exception

    collection_title = None
    if collection_id:
        try:
            collection = collection_services.get_collection_by_id(
                collection_id)
            collection_title = collection.title
        except Exception:
            raise Exception

    version = exploration.version

    # TODO(sll): Cache these computations.
    interaction_ids = exploration.get_interaction_ids()
    for interaction_id in feconf.ALLOWED_QUESTION_INTERACTION_IDS:
        if interaction_id not in interaction_ids:
            interaction_ids.append(interaction_id)

    dependency_ids = (
        interaction_registry.Registry.get_deduplicated_dependency_ids(
            interaction_ids))
    dependencies_html, additional_angular_modules = (
        dependency_registry.Registry.get_deps_html_and_angular_modules(
            dependency_ids))

    interaction_templates = (
        interaction_registry.Registry.get_interaction_html(
            interaction_ids))

    return {
        'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
        'additional_angular_modules': additional_angular_modules,
        'can_edit': can_edit,
        'dependencies_html': jinja2.utils.Markup(
            dependencies_html),
        'exploration_title': exploration.title,
        'exploration_version': version,
        'collection_id': collection_id,
        'collection_title': collection_title,
        'interaction_templates': jinja2.utils.Markup(
            interaction_templates),
        'is_private': rights_manager.is_exploration_private(
            exploration_id),
        # Note that this overwrites the value in base.py.
        'meta_name': exploration.title,
        # Note that this overwrites the value in base.py.
        'meta_description': utils.capitalize_string(exploration.objective),
    }
Exemple #21
0
    def get(self, exploration_id):
        """Handles GET requests."""
        version = self.request.get('v')
        if not version:
            # The default value for a missing parameter seems to be ''.
            version = None
        else:
            version = int(version)

        try:
            exploration = exp_services.get_exploration_by_id(
                exploration_id, version=version)
        except Exception as e:
            raise self.PageNotFoundException(e)

        version = exploration.version

        if not rights_manager.Actor(self.user_id).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id):
            raise self.PageNotFoundException

        is_iframed = (self.request.get('iframed') == 'true')

        # TODO(sll): Cache these computations.
        gadget_types = exploration.get_gadget_types()
        interaction_ids = exploration.get_interaction_ids()
        dependency_ids = (
            interaction_registry.Registry.get_deduplicated_dependency_ids(
                interaction_ids))
        dependencies_html, additional_angular_modules = (
            dependency_registry.Registry.get_deps_html_and_angular_modules(
                dependency_ids))

        gadget_templates = (
            gadget_registry.Registry.get_gadget_html(gadget_types))

        interaction_templates = (
            rte_component_registry.Registry.get_html_for_all_components() +
            interaction_registry.Registry.get_interaction_html(
                interaction_ids))

        self.values.update({
            'GADGET_SPECS': gadget_registry.Registry.get_all_specs(),
            'INTERACTION_SPECS': interaction_registry.Registry.get_all_specs(),
            'SHARING_OPTIONS': SHARING_OPTIONS.value,
            'SHARING_OPTIONS_TWITTER_TEXT': SHARING_OPTIONS_TWITTER_TEXT.value,
            'additional_angular_modules': additional_angular_modules,
            'can_edit': (
                bool(self.username) and
                self.username not in config_domain.BANNED_USERNAMES.value and
                rights_manager.Actor(self.user_id).can_edit(
                    rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id)
            ),
            'dependencies_html': jinja2.utils.Markup(
                dependencies_html),
            'exploration_title': exploration.title,
            'exploration_version': version,
            'gadget_templates': jinja2.utils.Markup(gadget_templates),
            'iframed': is_iframed,
            'interaction_templates': jinja2.utils.Markup(
                interaction_templates),
            'is_private': rights_manager.is_exploration_private(
                exploration_id),
            # Note that this overwrites the value in base.py.
            'meta_name': exploration.title,
            # Note that this overwrites the value in base.py.
            'meta_description': self._make_first_letter_uppercase(
                exploration.objective),
            'nav_mode': feconf.NAV_MODE_EXPLORE,
            'skin_templates': jinja2.utils.Markup(
                skins_services.Registry.get_skin_templates(
                    [feconf.DEFAULT_SKIN_ID])),
            'skin_js_url': skins_services.Registry.get_skin_js_url(
                feconf.DEFAULT_SKIN_ID),
            'skin_tag': jinja2.utils.Markup(
                skins_services.Registry.get_skin_tag(feconf.DEFAULT_SKIN_ID)),
        })

        if is_iframed:
            self.render_template(
                'player/exploration_player.html', iframe_restriction=None)
        else:
            self.render_template('player/exploration_player.html')