Example #1
0
    def add_sketch_attribute(self, name, values, ontology='text'):
        """Add an attribute to the sketch.

        Args:
            name (str): The name of the attribute
            values (list): A list of strings, which contains the values of the
                attribute.
            ontology (str): Ontology of the attribute, matches with
                data/ontology.yaml.
        """
        # Check first whether the attribute already exists.
        attribute = Attribute.query.filter_by(name=name).first()

        if not attribute:
            attribute = Attribute(user=None,
                                  sketch=self.sql_sketch,
                                  name=name,
                                  ontology=ontology)
            db_session.add(attribute)
            db_session.commit()

        for value in values:
            attribute_value = AttributeValue(user=None,
                                             attribute=attribute,
                                             value=value)

            attribute.values.append(attribute_value)
            db_session.add(attribute_value)
            db_session.commit()

        db_session.add(attribute)
        db_session.commit()
Example #2
0
    def post(self, sketch_id):
        """Handles POST request to the resource.

        Returns:
            A string with the response from running the analyzer.
        """
        sketch = Sketch.query.get_with_acl(sketch_id)
        if not sketch:
            abort(HTTP_STATUS_CODE_NOT_FOUND, 'No sketch found with this ID.')

        if not sketch.has_permission(current_user, 'write'):
            return abort(HTTP_STATUS_CODE_FORBIDDEN,
                         'User does not have write permission on the sketch.')

        form = request.json
        if not form:
            form = request.data

        if not form:
            return abort(
                HTTP_STATUS_CODE_FORBIDDEN,
                'Unable to add or remove an attribute from a '
                'sketch without any data submitted.')

        for check in ['name', 'ontology']:
            error_message = self._validate_form_entry(form, check)
            if error_message:
                return abort(HTTP_STATUS_CODE_BAD_REQUEST, error_message)

        action = form.get('action', '')
        if action not in ('post', 'delete'):
            return abort(HTTP_STATUS_CODE_BAD_REQUEST,
                         'Action needs to be either "post" or "delete"')

        name = form.get('name')
        ontology = form.get('ontology', 'text')

        if action == 'post':
            values = form.get('values')
            if not values:
                return abort(HTTP_STATUS_CODE_BAD_REQUEST,
                             'Missing values from the request.')

            if not isinstance(values, (list, tuple)):
                return abort(HTTP_STATUS_CODE_BAD_REQUEST,
                             'Values needs to be a list.')

            if any([not isinstance(x, str) for x in values]):
                return abort(HTTP_STATUS_CODE_BAD_REQUEST,
                             'All values needs to be stored as strings.')

            for attribute in sketch.attributes:
                if attribute.name == name:
                    return abort(
                        HTTP_STATUS_CODE_BAD_REQUEST,
                        'Unable to add the attribute, it already exists.')

            attribute = Attribute(user=current_user,
                                  sketch=sketch,
                                  name=name,
                                  ontology=ontology)
            db_session.add(attribute)
            db_session.commit()

            for value in values:
                attribute_value = AttributeValue(user=current_user,
                                                 attribute=attribute,
                                                 value=value)
                attribute.values.append(attribute_value)
                db_session.add(attribute_value)
                db_session.commit()

            db_session.add(attribute)
            db_session.commit()

            return HTTP_STATUS_CODE_OK

        if action != 'delete':
            return abort(HTTP_STATUS_CODE_BAD_REQUEST, 'Unable to proceed.')

        for attribute in sketch.attributes:
            if attribute.name != name:
                continue
            for value in attribute.values:
                attribute.values.remove(value)
            sketch.attributes.remove(attribute)
            db_session.commit()

            return HTTP_STATUS_CODE_OK

        return abort(HTTP_STATUS_CODE_BAD_REQUEST,
                     'Unable to delete the attribute, couldn\'t find it.')
Example #3
0
    def post(self, sketch_id):
        """Handles POST request to the resource.

        Returns:
            A HTTP 200 if the attribute is successfully added or modified.
        """
        sketch = Sketch.query.get_with_acl(sketch_id)
        if not sketch:
            abort(HTTP_STATUS_CODE_NOT_FOUND, "No sketch found with this ID.")

        if not sketch.has_permission(current_user, "write"):
            return abort(
                HTTP_STATUS_CODE_FORBIDDEN,
                "User does not have write permission on the sketch.",
            )

        form = request.json
        if not form:
            form = request.data

        if not form:
            return abort(
                HTTP_STATUS_CODE_FORBIDDEN,
                "Unable to add or modify an attribute from a "
                "sketch without any data submitted.",
            )

        for check in ["name", "ontology"]:
            error_message = self._validate_form_entry(form, check)
            if error_message:
                return abort(HTTP_STATUS_CODE_BAD_REQUEST, error_message)

        name = form.get("name")
        ontology = form.get("ontology", "text")

        ontology_def = ontology_lib.ONTOLOGY
        ontology_dict = ontology_def.get(ontology, {})
        cast_as_string = ontology_dict.get("cast_as", "str")

        values = form.get("values")
        if not values:
            return abort(HTTP_STATUS_CODE_BAD_REQUEST,
                         "Missing values from the request.")

        if not isinstance(values, (list, tuple)):
            return abort(HTTP_STATUS_CODE_BAD_REQUEST,
                         "Values needs to be a list.")

        value_strings = [
            ontology_lib.OntologyManager.encode_value(x, cast_as_string)
            for x in values
        ]

        if any([not isinstance(x, str) for x in value_strings]):
            return abort(
                HTTP_STATUS_CODE_BAD_REQUEST,
                "All values needs to be stored as strings.",
            )

        attribute = None
        message = ""
        update_attribute = False
        for attribute in sketch.attributes:
            if (attribute.name == name) and (attribute.ontology == ontology):
                message = "Attribute Updated"
                update_attribute = True
                break

        if update_attribute:
            _ = AttributeValue.query.filter_by(attribute=attribute).delete()
        else:
            attribute = Attribute(user=current_user,
                                  sketch=sketch,
                                  name=name,
                                  ontology=ontology)

            db_session.add(attribute)
            db_session.commit()

        for value in value_strings:
            attribute_value = AttributeValue(user=current_user,
                                             attribute=attribute,
                                             value=value)
            attribute.values.append(attribute_value)
            db_session.add(attribute_value)
            db_session.commit()

        db_session.add(attribute)
        db_session.commit()

        return_data = {
            "name": name,
            "ontology": ontology,
            "cast_as": cast_as_string,
        }
        response = None
        if message:
            return_data["action"] = "update"
            response = jsonify(return_data)
            response.status_code = HTTP_STATUS_CODE_OK
        else:
            return_data["action"] = "create"
            response = jsonify(return_data)
            response.status_code = HTTP_STATUS_CODE_CREATED

        return response