예제 #1
0
    def delete(self, user, equipment, component):
        '''
        DELETE-method definition.
        Deletes an equipment resource in the API.

        Returns flask Response object.
        '''

        # Find user by name in database. If not found, respond with error 404
        if User.query.filter_by(uri=user).first() is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Find equipment by name in database.
        # If not found, respond with error 404
        if Equipment.query.filter_by(uri=equipment).first() is None:
            return create_error_response(
                404, "Not found",
                "No equipment was found with URI {}".format(equipment))
        # Find component by category in database.
        # If not found, respond with error 404
        db_comp = Component.query.filter_by(uri=component).first()
        if db_comp is None:
            return create_error_response(
                404, "Not found", "No component was found with "
                "URI {}".format(component))
        # Delete equipment
        db.session.delete(db_comp)
        db.session.commit()
        return Response(status=204)
예제 #2
0
    def get(self, user, equipment, component):
        '''
        GET-method definition.
        Builds the response body and adds controls as defined in API design

        Returns flask Response object.
        '''

        # Find user by name in database. If not found, respond with error 404
        if User.query.filter_by(uri=user).first() is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Find equipment by name in database.
        # If not found, respond with error 404
        db_equip = Equipment.query.filter_by(uri=equipment).first()
        if db_equip is None:
            return create_error_response(
                404, "Not found",
                "No equipment was found with URI {}".format(equipment))
        # Find component by category in database.
        # If not found, respond with error 404
        db_comp = Component.query.filter_by(uri=component).first()
        if db_comp is None:
            return create_error_response(
                404, "Not found", "No component was found with "
                "URI {}".format(component))
        # Instantiate response message body and include component data
        body = ComponentBuilder(name=db_comp.name,
                                category=db_comp.category,
                                brand=db_comp.brand,
                                model=db_comp.model,
                                date_added=db_comp.date_added,
                                date_retired=db_comp.date_retired,
                                equipment=db_equip.name)
        # Add controls to message body
        body.add_namespace("cyequ", LINK_RELATIONS_URL)
        body.add_control("self",
                         url_for("api.componentitem",
                                 user=user,
                                 equipment=equipment,
                                 component=component),
                         title="Get this component's information.")
        body.add_control("profile",
                         COMPONENT_PROFILE,
                         title="Get profile of component resource.")
        body.add_control("up",
                         url_for("api.equipmentitem",
                                 user=user,
                                 equipment=equipment),
                         title="Get associated equipment's information.")
        body.add_control_all_users()
        body.add_control_edit_component(user, equipment, component)
        body.add_control_delete_component(user, equipment, component)
        return Response(json.dumps(body), 200, mimetype=MASON)
예제 #3
0
파일: user.py 프로젝트: vesamaki/PWP_2020
    def get(self, user):
        '''
        GET-method definition.
        Builds the response body and adds controls as defined in API design

        Returns flask Response object.
        '''

        # Find user by name in database. If not found, respond with error 404
        db_user = User.query.filter_by(uri=user).first()
        if db_user is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Instantiate response message body
        body = UserBuilder(name=db_user.name)
        # Add controls to message body
        body.add_namespace("cyequ", LINK_RELATIONS_URL)
        body.add_control("self",
                         url_for("api.useritem", user=user),
                         title="Get this user's information.")
        body.add_control("profile",
                         USER_PROFILE,
                         title="Get profile of user resource.")
        body.add_control("collection",
                         url_for("api.usercollection"),
                         title="Get a list of all users know to the API.")
        body.add_control_edit_user(user)
        body.add_control_all_equipment(user)
        return Response(json.dumps(body), 200, mimetype=MASON)
예제 #4
0
파일: user.py 프로젝트: vesamaki/PWP_2020
    def post(self):
        '''
        POST-method definition.
        Checks for appropriate request body and creates a new user resource
        in the API.

        Exceptions.
        jsonschema.ValidationError. If request is not
            a valid JSON document.
        sqlalchemy.exc.IntegrityError. Violation of SQLite database
            integrity.

        Returns flask Response object.
        '''

        # Check for json.
        if request.json is None:
            return create_error_response(415, "Unsupported media type",
                                         "Requests must be JSON")
        # Validate request against the schema. If fails, respond with error 400
        try:
            validate(request.json, user_schema())
        except ValidationError as err:
            return create_error_response(400, "Invalid JSON "
                                         "document", str(err))
        # Add user to db
        user = User(name=request.json["name"])
        try:
            db.session.add(user)
            db.session.commit()
        except IntegrityError:
            # In case of database error
            db.session.rollback()
            return create_error_response(
                409, "Already exists", "User with name '{}' already"
                " exists.".format(request.json["name"]))
        # Find user by name in database.
        db_user = User.query.filter_by(name=request.json["name"]).first()
        # Create URI for user
        db_user.uri = db_user.name + str(db_user.id)
        db.session.commit()
        # Respond with location of new resource
        return Response(
            status=201,
            headers={"Location": url_for("api.useritem", user=db_user.uri)})
예제 #5
0
파일: user.py 프로젝트: vesamaki/PWP_2020
    def put(self, user):
        '''
        PUT-method definition.
        Checks for appropriate request body and modifies a resource in the
        API.

        Exceptions.
        jsonschema.ValidationError. If request is not
            a valid JSON document.
        sqlalchemy.exc.IntegrityError. Violation of SQLite database
            integrity.

        Returns flask Response object.
        '''

        # Check for json. If fails, respond with error 415
        if request.json is None:
            return create_error_response(415, "Unsupported media type",
                                         "Requests must be JSON")
        # Validate request against the schema. If fails, respond with error 400
        try:
            validate(request.json, user_schema())
        except ValidationError as err:
            return create_error_response(400, "Invalid JSON "
                                         "document", str(err))
        # Find user by name in database. If not found, respond with error 404
        db_user = User.query.filter_by(uri=user).first()
        if db_user is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Update user data
        db_user.name = request.json["name"]
        try:
            db.session.commit()
        except IntegrityError:
            # In case of database error
            db.session.rollback()
            return create_error_response(
                409, "Already exists", "User with name '{}' already "
                "exists.".format(request.json["name"]))
        return Response(status=204)
예제 #6
0
    def get(self, user):
        '''
        GET-method definition.
        Builds the response body and adds controls as defined in API design

        Returns flask Response object.
        '''

        # Find user by name in database. If not found, respond with error 404
        db_user = User.query.filter_by(uri=user).first()
        if db_user is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Instantiate message body
        body = EquipmentBuilder(items=[])
        # Add general controls to message body
        body.add_namespace("cyequ", LINK_RELATIONS_URL)
        body.add_control("self",
                         url_for("api.equipmentbyuser", user=user),
                         title="Get a list of all equipment owned by "
                         "the given user.")
        body.add_control("cyequ:owner",
                         url_for("api.useritem", user=user),
                         title="Get associated user's information.")
        body.add_control_add_equipment(user)
        # Loop through all equipment items owned by user
        for equipment in db_user.hasEquip:
            equip = EquipmentBuilder(name=equipment.name,
                                     category=equipment.category,
                                     date_added=equipment.date_added,
                                     date_retired=equipment.date_retired)
            # Add controls to each item
            equip.add_control("self",
                              url_for("api.equipmentitem",
                                      user=user,
                                      equipment=equipment.uri),
                              title="Get this equipment's information.")
            equip.add_control("profile",
                              EQUIPMENT_PROFILE,
                              title="Get the profile of equipment resource.")
            # Append each item to items-list of response body
            body["items"].append(equip)
        return Response(json.dumps(body), 200, mimetype=MASON)
예제 #7
0
    def post(self, user):
        '''
        POST-method definition.
        Checks for appropriate request body and creates a new equipment
        resource in the API.

        Exceptions.
        jsonschema.ValidationError. If request is not
            a valid JSON document.
        sqlalchemy.exc.IntegrityError. Violation of SQLite database
            integrity.

        Returns flask Response object.
        '''

        # Check for json. If fails, respond with error 415
        if request.json is None:
            return create_error_response(415, "Unsupported media type",
                                         "Requests must be JSON")
        # Validate request against the schema. If fails, respond with error 400
        try:
            validate(request.json, component_schema())
        except ValidationError as err:
            return create_error_response(400, "Invalid JSON"
                                         "document", str(err))
        # Find user by name in database. If not found, respond with error 404
        db_user = User.query.filter_by(uri=user).first()
        if db_user is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Convert %Y-%m-%d %H:%M:%S dates to Python datetime format
        p_date_added = convert_req_date(request.json.get("date_added"))
        p_date_retired = convert_req_date(request.json.get("date_retired"))
        # Check if date_retired given
        if p_date_retired is not None:
            # Check if date_retired is later than date_added
            if p_date_added >= p_date_retired:
                return create_error_response(
                    409, "Inconsistent dates", "Retire date {} must be in the "
                    "future with respect to"
                    " added date {}".format(p_date_retired, p_date_added))
        # Add equipment to db
        new_equip = Equipment(name=request.json["name"],
                              category=request.json["category"],
                              brand=request.json["brand"],
                              model=request.json["model"],
                              date_added=p_date_added,
                              date_retired=p_date_retired,
                              owner=db_user.id)
        try:
            db.session.add(new_equip)
            db.session.commit()
        except IntegrityError:
            # In case of database error
            db.session.rollback()
            return create_error_response(
                409, "Already exists", "Equipment with name '{}' already"
                " exists for this user.".format(request.json["name"]))
        # Find new equipment by name in database.
        db_equip = Equipment.query.filter_by(name=request.json["name"]).first()
        # Create URI for user
        db_equip.uri = db_equip.name + str(db_equip.id)
        db.session.commit()
        # Respond with location of new resource
        return Response(status=201,
                        headers={
                            "Location":
                            url_for("api.equipmentitem",
                                    user=user,
                                    equipment=db_equip.uri)
                        })
예제 #8
0
    def put(self, user, equipment):
        '''
        PUT-method definition.
        Checks for appropriate request body and modifies an equipment resource
        in the API.

        Exceptions.
        jsonschema.ValidationError. If request is not
            a valid JSON document.
        sqlalchemy.exc.IntegrityError. Violation of SQLite database
            integrity.

        Returns flask Response object.
        '''

        # Check for json. If fails, respond with error 415
        if request.json is None:
            return create_error_response(415, "Unsupported media type",
                                         "Requests must be JSON")
        # Validate request against the schema. If fails, respond with error 400
        try:
            validate(request.json, equipment_schema())
        except ValidationError as err:
            return create_error_response(400, "Invalid JSON "
                                         "document", str(err))
        # Find user by name in database. If not found, respond with error 404
        if User.query.filter_by(uri=user).first() is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Find equipment by name in database.
        # If not found, respond with error 404
        db_equip = Equipment.query.filter_by(uri=equipment).first()
        if db_equip is None:
            return create_error_response(
                404, "Not found",
                "No equipment was found with URI {}".format(equipment))
        # Convert %Y-%m-%d %H:%M:%S dates to Python datetime format
        p_date_added = convert_req_date(request.json.get("date_added"))
        p_date_retired = convert_req_date(request.json.get("date_retired"))
        # Update equipment data
        db_equip.name = request.json["name"]
        db_equip.category = request.json["category"]
        db_equip.brand = request.json["brand"]
        db_equip.model = request.json["model"]
        # Make sure equipment date_added cannot be moved forward in time if
        # equipment has associated components
        if db_equip.date_added >= p_date_added:
            db_equip.date_added = p_date_added
        elif not Component.query.filter_by(equipment_id=db_equip.id).first():
            db_equip.date_added = p_date_added
        else:
            return create_error_response(
                409, "Inconsistent dates",
                "New added date {} must not be in the"
                "future of current added date {} if "
                "equipment has components associated"
                " with it".format(p_date_added, db_equip.date_added))
        # When retiring equipment, also retire associated components
        # Check if date_retired given for equipment
        if request.json.get("date_retired") is not None:
            # Check if date_retired is later than date_added
            if p_date_added >= p_date_retired:
                return create_error_response(
                    409, "Inconsistent dates", "Retire date {} must be in the "
                    "future with respect to"
                    " added date {}".format(p_date_retired, p_date_added))
            # Update equipment date_retired
            db_equip.date_retired = p_date_retired
            # Loop all associated components for equipment
            for component in Component.query.filter_by(
                    equipment_id=db_equip.id).all():  # noqa: 501
                # Update component date_retired
                component.date_retired = p_date_retired
        try:
            db.session.commit()
        except IntegrityError:
            # In case of database error
            db.session.rollback()
            return create_error_response(
                409, "Already exists", "Equipment with name '{}' already "
                "exists for user.".format(request.json["name"]))
        return Response(status=204)
예제 #9
0
    def post(self, user, equipment):
        '''
        POST-method definition.
        Checks for appropriate request body and creates a new component
        resource in the API.

        Exceptions.
        jsonschema.ValidationError. If request is not
            a valid JSON document.
        sqlalchemy.exc.IntegrityError. Violation of SQLite database
            integrity.

        Returns flask Response object.
        '''

        # Check for json. If fails, respond with error 415
        if request.json is None:
            return create_error_response(415, "Unsupported media type",
                                         "Requests must be JSON")
        # Validate request against the schema. If fails, respond with error 400
        try:
            validate(request.json, equipment_schema())
        except ValidationError as err:
            return create_error_response(400, "Invalid JSON "
                                         "document", str(err))
        # Find user by name in database. If not found, respond with error 404
        if User.query.filter_by(uri=user).first() is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Find equipment by name in database.
        # If not found, respond with error 404
        db_equip = Equipment.query.filter_by(uri=equipment).first()
        if db_equip is None:
            return create_error_response(
                404, "Not found",
                "No equipment was found with URI {}".format(equipment))
        # Check if equipment is already retired
        if db_equip.date_retired is not None:
            return create_error_response(
                409, "Already retired", "Equipment of URI '{}' is retired."
                " Cannot add component {}.".format(db_equip.uri,
                                                   request.json["category"]))
        # Date checks
        # Convert %Y-%m-%d %H:%M:%S dates to Python datetime format
        p_date_added = convert_req_date(request.json.get("date_added"))
        # Check that component date added is not before
        # associated equipment's date added
        if p_date_added < db_equip.date_added:
            return create_error_response(
                409, "Inconsistent dates", "Components's date added {} must be"
                " after associated equipment's "
                "date added {}".format(db_equip.date_added, p_date_added))
        # Check if date_retired given and convert
        p_date_retired = convert_req_date(request.json.get("date_retired"))
        if p_date_retired is not None:
            if p_date_added >= p_date_retired:
                return create_error_response(
                    409, "Inconsistent dates", "Retire date {} must be in the "
                    "future with respect to"
                    " added date {}".format(p_date_retired, p_date_added))
        else:
            # If not given, set to faaar in the future.
            # Meaning component is currently installed to equipment
            p_date_retired = convert_req_date("9999-12-31 23:59:59")
        # Add a new component to db for equipment
        new_comp = Component(name=request.json["name"],
                             category=request.json["category"],
                             brand=request.json["brand"],
                             model=request.json["model"],
                             date_added=p_date_added,
                             date_retired=p_date_retired,
                             equipment_id=db_equip.id)
        try:
            db.session.add(new_comp)
            db.session.commit()
        except IntegrityError:
            # In case of database error
            db.session.rollback()
            # Currently doesn't work.
            # No functioning constraint for unique "active component".
            return create_error_response(
                409, "Already in service", "Unretired component of category"
                " '{}' already exists.".format(request.json["category"]))
        # Find new component by category & date_retired in database.
        db_comp = Component.query.filter_by(
            category=request.json["category"],
            date_retired=p_date_retired).first()
        # Create URI for user
        db_comp.uri = db_comp.name + str(db_comp.id)
        db.session.commit()
        # Respond with location of new resource
        return Response(status=201,
                        headers={
                            "Location":
                            url_for("api.componentitem",
                                    user=user,
                                    equipment=equipment,
                                    component=db_comp.uri)
                        })
예제 #10
0
    def get(self, user, equipment):
        '''
        GET-method definition.
        Builds the response body and adds controls as defined in API design

        Returns flask Response object.
        '''

        # Find user by name in database. If not found, respond with error 404
        db_user = User.query.filter_by(uri=user).first()
        if db_user is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Find equipment by name in database.
        # If not found, respond with error 404
        db_equip = Equipment.query.filter_by(uri=equipment).first()
        if db_equip is None:
            return create_error_response(
                404, "Not found",
                "No equipment was found with URI {}".format(equipment))
        # Instantiate response message body
        body = EquipmentBuilder(name=db_equip.name,
                                category=db_equip.category,
                                brand=db_equip.brand,
                                model=db_equip.model,
                                date_added=db_equip.date_added,
                                date_retired=db_equip.date_retired,
                                user=db_user.name,
                                items=[])
        # Loop through all users in database and build each item with data and
        # controls.
        for component in db_equip.hasCompos:
            # If component is in active service, don't attach retired_date
            if component.date_retired == datetime(9999, 12, 31, 23, 59, 59):
                comp = ComponentBuilder(name=component.name,
                                        category=component.category,
                                        brand=component.brand,
                                        model=component.brand,
                                        date_added=component.date_added)
            else:
                comp = ComponentBuilder(name=component.name,
                                        category=component.category,
                                        brand=component.brand,
                                        model=component.brand,
                                        date_added=component.date_added,
                                        date_retired=component.date_retired)
            # Add controls to each item
            comp.add_control("self",
                             url_for("api.componentitem",
                                     user=user,
                                     equipment=equipment,
                                     component=component.uri),
                             title="Get this component's information.")
            comp.add_control("profile",
                             COMPONENT_PROFILE,
                             title="Get profile of component resource.")
            # Append each item to items-list of response body
            body["items"].append(comp)
        # Add controls response message body
        body.add_namespace("cyequ", LINK_RELATIONS_URL)
        body.add_control("self",
                         url_for("api.equipmentitem",
                                 user=user,
                                 equipment=equipment),
                         title="Get this equipment's information.")
        body.add_control("profile",
                         EQUIPMENT_PROFILE,
                         title="Get profile of equipment resource.")
        body.add_control("cyequ:owner",
                         url_for("api.equipmentbyuser", user=user),
                         title="Get associated user's information.")
        body.add_control_all_users()
        body.add_control_all_equipment(user)
        body.add_control_edit_equipment(user, equipment)
        body.add_control_delete_equipment(user, equipment)
        body.add_control_add_component(user, equipment)
        return Response(json.dumps(body), 200, mimetype=MASON)
예제 #11
0
    def put(self, user, equipment, component):
        '''
        PUT-method definition.
        Checks for appropriate request body and modifies an equipment resource
        in the API.

        Exceptions.
        jsonschema.ValidationError. If request is not
            a valid JSON document.
        sqlalchemy.exc.IntegrityError. Violation of SQLite database
            integrity.

        Returns flask Response object.
        '''

        # Check for json. If fails, respond with error 415
        if request.json is None:
            return create_error_response(415, "Unsupported media type",
                                         "Requests must be JSON")
        # Validate request against the schema. If fails, respond with error 400
        try:
            validate(request.json, component_schema())
        except ValidationError as err:
            return create_error_response(400, "Invalid JSON "
                                         "document", str(err))
        # Find user by name in database. If not found, respond with error 404
        if User.query.filter_by(uri=user).first() is None:
            return create_error_response(
                404, "Not found", "No user was found with URI {}".format(user))
        # Find equipment by name in database.
        # If not found, respond with error 404
        db_equip = Equipment.query.filter_by(uri=equipment).first()
        if db_equip is None:
            return create_error_response(
                404, "Not found",
                "No equipment was found with URI {}".format(equipment))
        # Find component by category in database.
        # If not found, respond with error 404
        db_comp = Component.query.filter_by(uri=component).first()
        if db_comp is None:
            return create_error_response(
                404, "Not found", "No component was found with "
                "URI {}".format(component))
        # Convert %Y-%m-%d %H:%M:%S dates to Python datetime format
        p_date_added = convert_req_date(request.json.get("date_added"))
        p_date_retired = convert_req_date(request.json.get("date_retired"))
        # Update equipment data
        db_comp.name = request.json["name"]
        db_comp.category = request.json["category"]
        db_comp.brand = request.json["brand"]
        db_comp.model = request.json["model"]
        # Make sure component date_added cannot be moved backward in time
        # past associated equipment's date_added
        if db_equip.date_added <= p_date_added:
            db_comp.date_added = p_date_added
        else:
            return create_error_response(
                409, "Inconsistent dates",
                "New added date {} must be at or in "
                "the future of associated equipment's"
                " current added date {}".format(p_date_added,
                                                db_equip.date_added))
        # Check if date_retired given
        if p_date_retired is not None:
            # Check if date_retired is later than date_added
            if p_date_added >= p_date_retired:
                return create_error_response(
                    409, "Inconsistent dates", "Retire date {} must be in the "
                    "future with respect to"
                    " added date {}".format(p_date_retired, p_date_added))
            # Check if equipment is already retired
            # Components are retired, when equipment is retired
            # Cannot re- or unretire components of retired equipment
            elif db_equip.date_retired is not None:
                return create_error_response(
                    409, "Not allowed", "Cannot reretire components of a"
                    " retired equipment {}".format(db_equip.uri))
            else:
                db_comp.date_retired = p_date_retired
        try:
            db.session.commit()
        except IntegrityError:
            # In case of database error
            db.session.rollback()
            return create_error_response(
                409, "Already exists", "Unretired component of category"
                " {} already exists.".format(request.json["category"]))
        return Response(status=204)