Beispiel #1
0
def update_topic_and_subtopic_pages(committer_id, topic_id, change_list,
                                    commit_message):
    """Updates a topic and its subtopic pages. Commits changes.

    Args:
        committer_id: str. The id of the user who is performing the update
            action.
        topic_id: str. The topic id.
        change_list: list(TopicChange and SubtopicPageChange). These changes are
            applied in sequence to produce the resulting topic.
        commit_message: str or None. A description of changes made to the
            topic.

    Raises:
        ValueError. Current user does not have enough rights to edit a topic.
    """
    topic_rights = topic_fetchers.get_topic_rights(topic_id, strict=False)
    if topic_rights.topic_is_published and not commit_message:
        raise ValueError('Expected a commit message, received none.')

    old_topic = topic_fetchers.get_topic_by_id(topic_id)
    (updated_topic, updated_subtopic_pages_dict, deleted_subtopic_ids,
     newly_created_subtopic_ids,
     updated_subtopic_pages_change_cmds_dict) = apply_change_list(
         topic_id, change_list)

    if (old_topic.url_fragment != updated_topic.url_fragment and
            does_topic_with_url_fragment_exist(updated_topic.url_fragment)):
        raise utils.ValidationError(
            'Topic with URL Fragment \'%s\' already exists' %
            updated_topic.url_fragment)
    if (old_topic.name != updated_topic.name
            and does_topic_with_name_exist(updated_topic.name)):
        raise utils.ValidationError('Topic with name \'%s\' already exists' %
                                    updated_topic.name)

    _save_topic(committer_id, updated_topic, commit_message, change_list)
    # The following loop deletes those subtopic pages that are already in the
    # datastore, which are supposed to be deleted in the current changelist.
    for subtopic_id in deleted_subtopic_ids:
        if subtopic_id not in newly_created_subtopic_ids:
            subtopic_page_services.delete_subtopic_page(
                committer_id, topic_id, subtopic_id)

    for subtopic_page_id, subtopic_page in updated_subtopic_pages_dict.items():
        subtopic_page_change_list = updated_subtopic_pages_change_cmds_dict[
            subtopic_page_id]
        subtopic_id = subtopic_page.get_subtopic_id_from_subtopic_page_id()
        # The following condition prevents the creation of subtopic pages that
        # were deleted above.
        if subtopic_id not in deleted_subtopic_ids:
            subtopic_page_services.save_subtopic_page(
                committer_id, subtopic_page, commit_message,
                subtopic_page_change_list)
    generate_topic_summary(topic_id)

    if old_topic.name != updated_topic.name:
        opportunity_services.update_opportunities_with_new_topic_name(
            updated_topic.id, updated_topic.name)
Beispiel #2
0
    def validate(self):
        """Validates various properties of the UserQuery.

        Raises:
            ValidationError. Expected ID to be a string.
            ValidationError. Expected params to be of type UserQueryParams.
            ValidationError. Expected objective to be a string.
            ValidationError. Expected submitter ID to be a valid user ID.
            ValidationError. Expected status to be a string.
            ValidationError. Invalid status.
            ValidationError. Expected user_ids to be a list.
            ValidationError. Expected each user ID in user_ids to be a string.
            ValidationError. Expected user ID in user_ids to be a valid user ID.
            ValidationError. Expected sent_email_model_id to be a string.
        """
        if not isinstance(self.id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected ID to be a string, received %s' % self.id)

        if not isinstance(self.params, tuple):
            raise utils.ValidationError(
                'Expected params to be of type tuple, received %s' %
                type(self.params))

        if not isinstance(self.submitter_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected submitter ID to be a string, received %s' %
                self.submitter_id)
        if not utils.is_user_id_valid(self.submitter_id):
            raise utils.ValidationError(
                'Expected submitter ID to be a valid user ID, received %s' %
                self.submitter_id)

        if not isinstance(self.status, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected status to be a string, received %s' % self.status)
        if self.status not in feconf.ALLOWED_USER_QUERY_STATUSES:
            raise utils.ValidationError('Invalid status: %s' % self.status)

        if not isinstance(self.user_ids, list):
            raise utils.ValidationError(
                'Expected user_ids to be a list, received %s' %
                type(self.user_ids))
        for user_id in self.user_ids:
            if not isinstance(user_id, python_utils.BASESTRING):
                raise utils.ValidationError(
                    'Expected each user ID in user_ids to be a string, '
                    'received %s' % user_id)

            if not utils.is_user_id_valid(user_id):
                raise utils.ValidationError(
                    'Expected user ID in user_ids to be a valid user ID, '
                    'received %s' % user_id)

        if self.sent_email_model_id and not isinstance(
                self.sent_email_model_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected sent_email_model_id to be a string, received %s' %
                self.sent_email_model_id)
Beispiel #3
0
    def validate(self) -> None:
        """Validates an ActivityRights object.

        Raises:
            utils.ValidationError. If any of the owners, editors, voice artists
                and viewers lists overlap, or if a community-owned exploration
                has owners, editors, voice artists or viewers specified.
        """
        if self.community_owned:
            if (self.owner_ids or self.editor_ids or self.voice_artist_ids
                    or self.viewer_ids):
                raise utils.ValidationError(
                    'Community-owned explorations should have no owners, '
                    'editors, voice artists or viewers specified.')

        if self.community_owned and self.status == ACTIVITY_STATUS_PRIVATE:
            raise utils.ValidationError(
                'Community-owned explorations cannot be private.')

        if self.status != ACTIVITY_STATUS_PRIVATE and self.viewer_ids:
            raise utils.ValidationError(
                'Public explorations should have no viewers specified.')

        owner_editor = set(self.owner_ids) & set(self.editor_ids)
        owner_voice_artist = set(self.owner_ids) & set(self.voice_artist_ids)
        owner_viewer = set(self.owner_ids) & set(self.viewer_ids)
        editor_voice_artist = set(self.editor_ids) & set(self.voice_artist_ids)
        editor_viewer = set(self.editor_ids) & set(self.viewer_ids)
        voice_artist_viewer = set(self.voice_artist_ids) & set(self.viewer_ids)
        if owner_editor:
            raise utils.ValidationError(
                'A user cannot be both an owner and an editor: %s' %
                owner_editor)
        if owner_voice_artist:
            raise utils.ValidationError(
                'A user cannot be both an owner and a voice artist: %s' %
                owner_voice_artist)
        if owner_viewer:
            raise utils.ValidationError(
                'A user cannot be both an owner and a viewer: %s' %
                owner_viewer)
        if editor_voice_artist:
            raise utils.ValidationError(
                'A user cannot be both an editor and a voice artist: %s' %
                editor_voice_artist)
        if editor_viewer:
            raise utils.ValidationError(
                'A user cannot be both an editor and a viewer: %s' %
                editor_viewer)
        if voice_artist_viewer:
            raise utils.ValidationError(
                'A user cannot be both a voice artist and a viewer: %s' %
                voice_artist_viewer)

        if not self.community_owned and len(self.owner_ids) == 0:
            raise utils.ValidationError(
                'Activity should have atleast one owner.')
Beispiel #4
0
    def validate_dict(
        self, change_dict: Mapping[str, AcceptableChangeDictTypes]
    ) -> None:
        """Checks that the command in change dict is valid for the domain
        object.

        Args:
            change_dict: dict. A dict of changes with keys as a cmd and the
                attributes of a command.

        Raises:
            ValidationError. The change dict does not contain the cmd key,
                or the cmd name is not allowed for the Change domain object
                or the command attributes are missing or extra.
            DeprecatedCommandError. The change dict contains a deprecated
                command or the value for the command attribute is deprecated.
        """
        if 'cmd' not in change_dict:
            raise utils.ValidationError('Missing cmd key in change dict')

        cmd_name = change_dict['cmd']
        # Ruling out the possibility of different types for mypy type checking.
        assert isinstance(cmd_name, str)

        valid_cmd_attribute_specs = None

        all_allowed_commands = (
            self.ALLOWED_COMMANDS + self.COMMON_ALLOWED_COMMANDS)
        for cmd in all_allowed_commands:
            if cmd['name'] == cmd_name:
                valid_cmd_attribute_specs = copy.deepcopy(cmd)
                break

        if cmd_name in self.DEPRECATED_COMMANDS:
            raise utils.DeprecatedCommandError(
                'Command %s is deprecated' % cmd_name)

        if not valid_cmd_attribute_specs:
            raise utils.ValidationError('Command %s is not allowed' % cmd_name)

        # Here we are deleting the 'name' key which cause MyPy to throw error,
        # because MyPy does not allow key deletion from TypedDict. So to silent
        # the error, we added an ignore here.
        valid_cmd_attribute_specs.pop('name', None)  # type: ignore[misc]

        actual_cmd_attributes = copy.deepcopy(change_dict)
        # Here, `actual_cmd_attributes` is of type Mapping and Mapping does not
        # contain extra methods (e.g: .pop()). But here we are accessing `pop()`
        # method, which causes MyPy to throw error. Thus to avoid the error,
        # we used ignore here.
        actual_cmd_attributes.pop('cmd', None)  # type: ignore[attr-defined]

        validate_cmd(
            cmd_name, valid_cmd_attribute_specs, actual_cmd_attributes)
Beispiel #5
0
    def require_valid_blog_post_id(cls, blog_id):
        """Checks whether the blog id is a valid one.

        Args:
            blog_id: str. The blog post id to validate.
        """
        if not isinstance(blog_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Blog Post ID should be a string, received: %s' % blog_id)

        if len(blog_id) != BLOG_POST_ID_LENGTH:
            raise utils.ValidationError('Blog ID %s is invalid' % blog_id)
Beispiel #6
0
def _create_topic(committer_id, topic, commit_message, commit_cmds):
    """Creates a new topic, and ensures that rights for a new topic
    are saved first.

    Args:
        committer_id: str. ID of the committer.
        topic: Topic. Topic domain object.
        commit_message: str. A description of changes made to the topic.
        commit_cmds: list(TopicChange). A list of TopicChange objects that
            represent change commands made to the given topic.
    """
    topic.validate()
    if does_topic_with_name_exist(topic.name):
        raise utils.ValidationError('Topic with name \'%s\' already exists' %
                                    topic.name)
    if does_topic_with_url_fragment_exist(topic.url_fragment):
        raise utils.ValidationError(
            'Topic with URL Fragment \'%s\' already exists' %
            topic.url_fragment)
    create_new_topic_rights(topic.id, committer_id)
    model = topic_models.TopicModel(
        id=topic.id,
        name=topic.name,
        abbreviated_name=topic.abbreviated_name,
        url_fragment=topic.url_fragment,
        thumbnail_bg_color=topic.thumbnail_bg_color,
        thumbnail_filename=topic.thumbnail_filename,
        thumbnail_size_in_bytes=topic.thumbnail_size_in_bytes,
        canonical_name=topic.canonical_name,
        description=topic.description,
        language_code=topic.language_code,
        canonical_story_references=[
            reference.to_dict()
            for reference in topic.canonical_story_references
        ],
        additional_story_references=[
            reference.to_dict()
            for reference in topic.additional_story_references
        ],
        uncategorized_skill_ids=topic.uncategorized_skill_ids,
        subtopic_schema_version=topic.subtopic_schema_version,
        story_reference_schema_version=topic.story_reference_schema_version,
        next_subtopic_id=topic.next_subtopic_id,
        subtopics=[subtopic.to_dict() for subtopic in topic.subtopics],
        meta_tag_content=topic.meta_tag_content,
        practice_tab_is_displayed=topic.practice_tab_is_displayed,
        page_title_fragment_for_web=topic.page_title_fragment_for_web)
    commit_cmd_dicts = [commit_cmd.to_dict() for commit_cmd in commit_cmds]
    model.commit(committer_id, commit_message, commit_cmd_dicts)
    topic.version += 1
    generate_topic_summary(topic.id)
Beispiel #7
0
def update_blog_post(
    blog_post_id: str, change_dict: BlogPostChangeDict
) -> None:
    """Updates the blog post and its summary model in the datastore.

    Args:
        blog_post_id: str. The ID of the blog post which is to be updated.
        change_dict: dict. A dict containing all the changes keyed by
            corresponding field name (title, content, thumbnail_filename,
            tags).
    """
    updated_blog_post = apply_change_dict(blog_post_id, change_dict)
    if 'title' in change_dict:
        blog_post_models: Sequence[blog_models.BlogPostModel] = (
            blog_models.BlogPostModel.query().filter(
                blog_models.BlogPostModel.title == updated_blog_post.title
            ).filter(
                blog_models.BlogPostModel.deleted == False  # pylint: disable=singleton-comparison
            ).fetch()
        )
        if len(blog_post_models) > 0:
            if (len(blog_post_models) > 1 or (
                    blog_post_models[0].id != blog_post_id)):
                raise utils.ValidationError(
                    'Blog Post with given title already exists: %s'
                    % updated_blog_post.title)

    _save_blog_post(updated_blog_post)
    updated_blog_post_summary = compute_summary_of_blog_post(updated_blog_post)
    _save_blog_post_summary(updated_blog_post_summary)
Beispiel #8
0
    def populate_from_modifiable_user_data(self, modifiable_user_data):
        """Populate the UserSettings domain object using the user data in
            modifiable_user_data.

        Args:
            modifiable_user_data: ModifiableUserData. The modifiable user
                data object with the information to be updated.

        Raises:
            ValidationError. None or empty value is provided for display alias
                attribute.
        """
        if (not modifiable_user_data.display_alias
                or not isinstance(modifiable_user_data.display_alias, str)):
            raise utils.ValidationError(
                'Expected display_alias to be a string, received %s.' %
                modifiable_user_data.display_alias)
        self.display_alias = modifiable_user_data.display_alias
        self.preferred_language_codes = (
            modifiable_user_data.preferred_language_codes)
        self.preferred_site_language_code = (
            modifiable_user_data.preferred_site_language_code)
        self.preferred_audio_language_code = (
            modifiable_user_data.preferred_audio_language_code)
        self.pin = modifiable_user_data.pin
Beispiel #9
0
 def validate(cls, value_dict):
     """Validates Image component."""
     super(Image, cls).validate(value_dict)
     filename_re = r'^[A-Za-z0-9+/_-]*\.((png)|(jpeg)|(gif)|(jpg))$'
     filepath = value_dict['filepath-with-value']
     if not re.match(filename_re, filepath):
         raise utils.ValidationError('Invalid filepath')
Beispiel #10
0
    def validate(cls, value_dict):
        """Validates customization args for a rich text component.

        Raises:
            TypeError. If any customization arg is invalid.
        """
        arg_names_to_obj_classes = {}
        customization_arg_specs = cls.rich_text_component_specs[
            cls.__name__]['customization_arg_specs']
        for customization_arg_spec in customization_arg_specs:
            arg_name = '%s-with-value' % customization_arg_spec['name']
            schema = customization_arg_spec['schema']
            if schema['type'] != 'custom':
                obj_type = schema['type']
            else:
                obj_type = schema['obj_type']
            obj_class = cls.obj_types_to_obj_classes[obj_type]
            arg_names_to_obj_classes[arg_name] = obj_class

        required_attr_names = list(arg_names_to_obj_classes.keys())
        attr_names = list(value_dict.keys())

        if set(attr_names) != set(required_attr_names):
            missing_attr_names = list(
                set(required_attr_names) - set(attr_names))
            extra_attr_names = list(set(attr_names) - set(required_attr_names))
            raise utils.ValidationError(
                'Missing attributes: %s, Extra attributes: %s' %
                (', '.join(missing_attr_names), ', '.join(extra_attr_names)))

        for arg_name in required_attr_names:
            arg_obj_class = arg_names_to_obj_classes[arg_name]
            arg_obj_class.normalize(value_dict[arg_name])
Beispiel #11
0
def is_story_published_and_present_in_topic(story):
    """Returns whether a story is published. Raises an exception if the story
    is not present in the corresponding topic's story references.

    Args:
        story: Story. The story domain object.

    Returns:
        bool. Whether the supplied story is published.
    """
    topic = topic_fetchers.get_topic_by_id(story.corresponding_topic_id,
                                           strict=False)
    if topic is None:
        raise utils.ValidationError(
            'Expected story to only belong to a valid topic, but found no '
            'topic with ID: %s' % story.corresponding_topic_id)

    story_is_published = False
    story_is_present_in_topic = False
    for story_reference in topic.get_all_story_references():
        if story_reference.story_id == story.id:
            story_is_present_in_topic = True
            story_is_published = story_reference.story_is_published

    if not story_is_present_in_topic:
        raise Exception(
            'Expected story to belong to the topic %s, but it is '
            'neither a part of the canonical stories or the additional '
            'stories of the topic.' % story.corresponding_topic_id)

    return story_is_published
Beispiel #12
0
    def require_valid_blog_post_id(cls, blog_id: str) -> None:
        """Checks whether the blog id is a valid one.

        Args:
            blog_id: str. The blog post id to validate.
        """
        if len(blog_id) != BLOG_POST_ID_LENGTH:
            raise utils.ValidationError('Blog ID %s is invalid' % blog_id)
Beispiel #13
0
    def validate(self) -> None:
        """Validate the existence of the object class."""

        # Ensure the obj_type is among the supported ParamSpec types.
        if self.obj_type not in feconf.SUPPORTED_OBJ_TYPES:
            raise utils.ValidationError(
                '%s is not among the supported object types for parameters:'
                ' {%s}.' %
                (self.obj_type, ', '.join(sorted(feconf.SUPPORTED_OBJ_TYPES))))
Beispiel #14
0
 def validate(cls, value_dict):
     """Validates Math component."""
     super(Math, cls).validate(value_dict)
     filename_pattern_regex = constants.constants.MATH_SVG_FILENAME_REGEX
     filename = value_dict['math_content-with-value']['svg_filename']
     if not re.match(filename_pattern_regex, filename):
         raise utils.ValidationError(
             'Invalid svg_filename attribute in math component: %s' %
             (filename))
Beispiel #15
0
    def validate(self) -> None:
        """Validates various properties of the object.

        Raises:
            ValidationError. One or more attributes of the object are invalid.
        """

        if self.content_count < 0:
            raise utils.ValidationError(
                'Expected content_count to be a non-negative integer, '
                'received %s' % self.content_count)

        allowed_language_codes = [
            language['id']
            for language in (constants.SUPPORTED_AUDIO_LANGUAGES)
        ]

        if not set(self.language_codes_with_assigned_voice_artists).isdisjoint(
                self.language_codes_needing_voice_artists):
            raise utils.ValidationError(
                'Expected voice_artist "needed" and "assigned" list of '
                'languages to be disjoint, received: %s, %s' %
                (self.language_codes_needing_voice_artists,
                 self.language_codes_with_assigned_voice_artists))

        self._validate_translation_counts(self.translation_counts)
        self._validate_translation_counts(self.translation_in_review_counts)

        expected_set_of_all_languages = set(
            self.incomplete_translation_language_codes +
            self.language_codes_needing_voice_artists +
            self.language_codes_with_assigned_voice_artists)

        for language_code in expected_set_of_all_languages:
            if language_code not in allowed_language_codes:
                raise utils.ValidationError('Invalid language_code: %s' %
                                            language_code)

        if expected_set_of_all_languages != set(allowed_language_codes):
            raise utils.ValidationError(
                'Expected set of all languages available in '
                'incomplete_translation, needs_voiceover and assigned_voiceover'
                ' to be the same as the supported audio languages, '
                'received %s' % list(sorted(expected_set_of_all_languages)))
Beispiel #16
0
    def validate(self):
        """Validates various properties of the object.

        Raises:
            ValidationError. One or more attributes of the object are invalid.
        """
        if not isinstance(self.skill_description, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected skill_description to be a string, received %s' %
                self.skill_description)
        if not isinstance(self.question_count, int):
            raise utils.ValidationError(
                'Expected question_count to be an integer, received %s' %
                self.question_count)

        if self.question_count < 0:
            raise utils.ValidationError(
                'Expected question_count to be a non-negative integer, '
                'received %s' % self.question_count)
Beispiel #17
0
    def validate_dict(self, change_dict):
        """Checks that the command in change dict is valid for the domain
        object.

        Args:
            change_dict: dict. A dict of changes with keys as a cmd and the
                attributes of a command.

        Raises:
            ValidationError. The change dict does not contain the cmd key,
                or the cmd name is not allowed for the Change domain object
                or the command attributes are missing or extra.
            DeprecatedCommandError. The change dict contains a deprecated
                command or the value for the command attribute is deprecated.
        """
        if 'cmd' not in change_dict:
            raise utils.ValidationError('Missing cmd key in change dict')

        cmd_name = change_dict['cmd']

        valid_cmd_attribute_specs = None

        all_allowed_commands = (self.ALLOWED_COMMANDS +
                                self.COMMON_ALLOWED_COMMANDS)
        for cmd in all_allowed_commands:
            if cmd['name'] == cmd_name:
                valid_cmd_attribute_specs = copy.deepcopy(cmd)
                break

        if cmd_name in self.DEPRECATED_COMMANDS:
            raise utils.DeprecatedCommandError('Command %s is deprecated' %
                                               cmd_name)

        if not valid_cmd_attribute_specs:
            raise utils.ValidationError('Command %s is not allowed' % cmd_name)

        valid_cmd_attribute_specs.pop('name', None)

        actual_cmd_attributes = copy.deepcopy(change_dict)
        actual_cmd_attributes.pop('cmd', None)

        validate_cmd(cmd_name, valid_cmd_attribute_specs,
                     actual_cmd_attributes)
Beispiel #18
0
 def validate(cls, value_dict):
     """Validates Collapsible component."""
     super(Collapsible, cls).validate(value_dict)
     content = value_dict['content-with-value']
     inner_soup = bs4.BeautifulSoup(content, 'html.parser')
     collapsible = inner_soup.findAll(
         name='oppia-noninteractive-collapsible')
     tabs = inner_soup.findAll(name='oppia-noninteractive-tabs')
     if len(collapsible) or len(tabs):
         raise utils.ValidationError('Nested tabs and collapsible')
Beispiel #19
0
    def validate(self):
        """Checks whether user_id, gae_id, firebase_auth_id, and parent_user_id
        are valid.

        Raises:
            ValidationError. The user_id is not specified.
            ValidationError. The user_id is not a string.
            ValidationError. The user_id has the wrong format.
            ValidationError. The gae_id is not a string.
            ValidationError. The firebase_auth_id is not a string.
            ValidationError. The parent_user_id has the wrong format.
            ValidationError. The parent_user_id is set for a full user.
            ValidationError. The parent_user_id is not set for a profile user.
        """
        if not self.user_id:
            raise utils.ValidationError('No user_id specified')

        if not isinstance(self.user_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'user_id must be a string, but got %r' % self.user_id)

        if not utils.is_user_id_valid(self.user_id):
            raise utils.ValidationError(
                'user_id=%r has the wrong format' % self.user_id)

        if (self.gae_id is not None and
                not isinstance(self.gae_id, python_utils.BASESTRING)):
            raise utils.ValidationError(
                'gae_id must be a string, but got %r' % self.gae_id)

        if (self.firebase_auth_id is not None and
                not isinstance(self.firebase_auth_id, python_utils.BASESTRING)):
            raise utils.ValidationError(
                'firebase_auth_id must be a string, but got %r' %
                self.firebase_auth_id)

        if (self.parent_user_id is not None and
                not utils.is_user_id_valid(self.parent_user_id)):
            raise utils.ValidationError(
                'parent_user_id=%r has the wrong format' % self.parent_user_id)

        if self.is_full_user() and self.parent_user_id is not None:
            raise utils.ValidationError(
                'parent_user_id must not be set for a full user, but got '
                'gae_id=%r, firebase_auth_id=%r, parent_user_id=%r' % (
                    self.gae_id, self.firebase_auth_id, self.parent_user_id))

        if not self.is_full_user() and self.parent_user_id is None:
            raise utils.ValidationError(
                'parent_user_id must be set for a profile user, but got '
                'gae_id=%r, firebase_auth_id=%r, parent_user_id=%r' % (
                    self.gae_id, self.firebase_auth_id, self.parent_user_id))
Beispiel #20
0
    def validate(self):
        """Validates various properties of the collection node.

        Raises:
            ValidationError. One or more attributes of the collection node are
                invalid.
        """
        if not isinstance(self.exploration_id, str):
            raise utils.ValidationError(
                'Expected exploration ID to be a string, received %s' %
                self.exploration_id)
Beispiel #21
0
    def validate(self):
        """Checks that the domain object is valid.

        Raises:
            ValidationError. The field pseudonymizable_entity_mappings
                contains wrong key.
        """
        for key in self.pseudonymizable_entity_mappings.keys():
            if key not in [name.value for name in models.NAMES]:
                raise utils.ValidationError(
                    'pseudonymizable_entity_mappings contain wrong key')
Beispiel #22
0
    def validate(self) -> None:
        """Validates various properties of the object.

        Raises:
            ValidationError. One or more attributes of the object are invalid.
        """

        if self.question_count < 0:
            raise utils.ValidationError(
                'Expected question_count to be a non-negative integer, '
                'received %s' % self.question_count)
Beispiel #23
0
    def _validate_entity_parameters(self, entity_name, entity_id):
        """Checks whether the entity_id and entity_name passed in are valid.

        Args:
            entity_name: str. The name of the entity
                (eg: exploration, topic etc).
            entity_id: str. The ID of the corresponding entity.

        Raises:
            ValidationError. When parameters passed in are invalid.
        """
        if entity_name not in ALLOWED_ENTITY_NAMES and (
                entity_name not in ALLOWED_SUGGESTION_IMAGE_CONTEXTS):
            raise utils.ValidationError('Invalid entity_name received: %s.' %
                                        entity_name)
        if not isinstance(entity_id, python_utils.BASESTRING):
            raise utils.ValidationError('Invalid entity_id received: %s' %
                                        entity_id)
        if entity_id == '':
            raise utils.ValidationError('Entity id cannot be empty')
Beispiel #24
0
 def validate(cls, value_dict):
     """Validates Tab component."""
     super(Tabs, cls).validate(value_dict)
     tab_contents = value_dict['tab_contents-with-value']
     for tab_content in tab_contents:
         inner_soup = (bs4.BeautifulSoup(tab_content['content'],
                                         'html.parser'))
         collapsible = inner_soup.findAll(
             name='oppia-noninteractive-collapsible')
         tabs = inner_soup.findAll(name='oppia-noninteractive-tabs')
         if len(collapsible) or len(tabs):
             raise utils.ValidationError('Nested tabs and collapsible')
Beispiel #25
0
    def validate(self) -> None:
        """Validates various properties of the UserQuery.

        Raises:
            ValidationError. Expected submitter ID to be a valid user ID.
            ValidationError. Invalid status.
            ValidationError. Expected user ID in user_ids to be a valid user ID.
        """
        if not utils.is_user_id_valid(self.submitter_id):
            raise utils.ValidationError(
                'Expected submitter ID to be a valid user ID, received %s' %
                self.submitter_id)

        if self.status not in feconf.ALLOWED_USER_QUERY_STATUSES:
            raise utils.ValidationError('Invalid status: %s' % self.status)

        for user_id in self.user_ids:
            if not utils.is_user_id_valid(user_id):
                raise utils.ValidationError(
                    'Expected user ID in user_ids to be a valid user ID, '
                    'received %s' % user_id)
Beispiel #26
0
    def validate(self):
        """Validate the existence of the object class."""

        # Ensure that this object class exists.
        object_registry.Registry.get_object_class_by_type(self.obj_type)

        # Ensure the obj_type is among the supported ParamSpec types.
        if self.obj_type not in self.SUPPORTED_OBJ_TYPES:
            raise utils.ValidationError(
                '%s is not among the supported object types for parameters:'
                ' {%s}.' %
                (self.obj_type, ', '.join(sorted(self.SUPPORTED_OBJ_TYPES))))
    def validate(self):
        """Validates the mapping before it is saved to storage."""

        if not isinstance(self.exp_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected exp_id to be a string, received %s' % self.exp_id)

        if not isinstance(self.exp_version, int):
            raise utils.ValidationError(
                'Expected exp_version to be an int, received %s' %
                (self.exp_version))

        if not isinstance(self.state_name, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected state_name to be a string, received %s' %
                (self.state_name))

        if not isinstance(self.algorithm_ids_to_job_ids, dict):
            raise utils.ValidationError(
                'Expected algorithm_ids_to_job_ids to be a dict, '
                'received %s' % (self.algorithm_ids_to_job_ids))

        for algorithm_id in self.algorithm_ids_to_job_ids:
            if not isinstance(algorithm_id, python_utils.BASESTRING):
                raise utils.ValidationError(
                    'Expected algorithm_id to be str, received %s' %
                    (algorithm_id))

            if not isinstance(self.algorithm_ids_to_job_ids[algorithm_id],
                              python_utils.BASESTRING):
                raise utils.ValidationError(
                    'Expected job_id to be str, received %s' %
                    (self.algorithm_ids_to_job_ids[algorithm_id]))
Beispiel #28
0
    def validate(self) -> None:
        """Validates the training job before it is saved to storage."""

        algorithm_ids = []
        utils.require_valid_name(self.state_name, 'the state name')
        if self.status not in feconf.ALLOWED_TRAINING_JOB_STATUSES:
            raise utils.ValidationError(
                'Expected status to be in %s, received %s' %
                (feconf.ALLOWED_TRAINING_JOB_STATUSES, self.status))

        if self.interaction_id not in feconf.INTERACTION_CLASSIFIER_MAPPING:
            raise utils.ValidationError('Invalid interaction id: %s' %
                                        self.interaction_id)

        algorithm_ids = [
            classifier_details['algorithm_id'] for classifier_details in
            feconf.INTERACTION_CLASSIFIER_MAPPING.values()
        ]
        if self.algorithm_id not in algorithm_ids:
            raise utils.ValidationError('Invalid algorithm id: %s' %
                                        self.algorithm_id)

        if not isinstance(self.training_data, list):
            raise utils.ValidationError(
                'Expected training_data to be a list, received %s' %
                (self.training_data))

        for grouped_answers in self.training_data:
            if 'answer_group_index' not in grouped_answers:
                raise utils.ValidationError(
                    'Expected answer_group_index to be a key in training_data'
                    'list item')
            if 'answers' not in grouped_answers:
                raise utils.ValidationError(
                    'Expected answers to be a key in training_data list item')
Beispiel #29
0
    def require_valid_title(cls, title, strict):
        """Checks whether the blog post title is a valid one.

        Args:
            title: str. The title to validate.
            strict: bool. Enable strict checks on the blog post summary when the
                blog post is published or is going to be published.

        Raises:
            ValidationErrors. Title provided is invalid.
        """
        if not isinstance(title, python_utils.BASESTRING):
            raise utils.ValidationError('Title should be a string.')

        if len(title) > constants.MAX_CHARS_IN_BLOG_POST_TITLE:
            raise utils.ValidationError(
                'blog post title should at most have %d chars, received: %s' %
                (constants.MAX_CHARS_IN_BLOG_POST_TITLE, title))

        if strict:
            if not title:
                raise utils.ValidationError('Title should not be empty')
Beispiel #30
0
    def validate(self, strict=False):
        """Validates various properties of the blog post summary object.

        Args:
            strict: bool. Enable strict checks on the blog post summary when the
                blog post is published or is going to be published.

        Raises:
            ValidationError. One or more attributes of blog post are invalid.
        """
        self.require_valid_title(self.title, strict)
        self.require_valid_tags(self.tags, strict)
        self.require_valid_thumbnail_filename(self.thumbnail_filename,
                                              strict=strict)

        if not isinstance(self.summary, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected summary to be a string, received: %s' % self.summary)

        if strict:
            self.require_valid_url_fragment(self.url_fragment)
            if not self.summary:
                raise utils.ValidationError('Summary can not be empty')