mirror of
https://github.com/pds-nest/nest.git
synced 2024-11-25 06:24:19 +00:00
⤴ Merge, resolving conflicts
This commit is contained in:
commit
7a4e99c4f1
10 changed files with 318 additions and 2 deletions
|
@ -36,6 +36,10 @@ class IntegerParameterSchema(Schema):
|
|||
rid = fields.Integer(description="The target numeric id.")
|
||||
|
||||
|
||||
class AlertParameterSchema(Schema):
|
||||
rid = fields.Integer(description="The target numeric id.")
|
||||
|
||||
|
||||
class CreateUser(Schema):
|
||||
email = fields.String(description="The new user's email.")
|
||||
username = fields.String(description="The new user's username.")
|
||||
|
@ -75,5 +79,38 @@ class CreateCondition(Schema):
|
|||
content = fields.String(description="The condition content. Meaning may change according to type.")
|
||||
|
||||
|
||||
class CreateAlert(Schema):
|
||||
name = fields.String(description="The name of the alert.")
|
||||
limit = fields.Integer(description="The number of tweets in a time window.")
|
||||
window_size = fields.Integer(description="The size of the time window.")
|
||||
|
||||
|
||||
class Operations(Schema):
|
||||
id = fields.Integer(description="The operation id.")
|
||||
operation = fields.Integer(description="The type of the operation.")
|
||||
is_root = fields.Boolean(description="If true, the operation is the root of the operation tree.")
|
||||
node_1 = fields.Nested('self')
|
||||
node_2 = fields.Nested('self')
|
||||
condition = fields.Nested(ConditionSchema)
|
||||
alert_id = fields.Integer(description="The id of the related alert.")
|
||||
|
||||
|
||||
class Notification(Schema):
|
||||
id = fields.Integer(description="The notification id.")
|
||||
ora = fields.DateTime(description="Muda muda muda.")
|
||||
repository_id = fields.Integer(description="The id of the related repository.")
|
||||
|
||||
|
||||
class Alert(Schema):
|
||||
id = fields.Integer(description="The alert id.")
|
||||
name = fields.String(description="The name of the alert.")
|
||||
limit = fields.Integer(description="The number of tweets in a time window.")
|
||||
window_size = fields.Integer(description="The size of the time window.")
|
||||
repository_id = fields.Integer(description="The id of the related repository.")
|
||||
operations = fields.Nested(Operations, many=True)
|
||||
root_operation = fields.Nested(Operations, many=False)
|
||||
notifications = fields.Nested(Notification, many=True)
|
||||
|
||||
|
||||
class ConditionParameterSchema(Schema):
|
||||
cid = fields.Integer(description="The condition id.")
|
||||
|
|
|
@ -29,6 +29,9 @@ spec.components.schema("RepositoryUpdate", schema=RepositoryUpdate)
|
|||
spec.components.schema("CreateRepository", schema=CreateRepository)
|
||||
spec.components.schema("CreateCondition", schema=CreateCondition)
|
||||
spec.components.schema("ConditionParameter", schema=ConditionParameterSchema)
|
||||
spec.components.schema("AlertParameter", schema=AlertParameterSchema)
|
||||
spec.components.schema("Alert", schema=Alert)
|
||||
spec.components.schema("CreateAlert", schema=CreateAlert)
|
||||
spec.components.security_scheme("jwt", {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"})
|
||||
|
||||
# add swagger tags that are used for endpoint annotation
|
||||
|
@ -42,6 +45,9 @@ tags = [
|
|||
{'name': 'condition-related',
|
||||
'description': 'Condition related calls of the API.'
|
||||
},
|
||||
{'name': 'alert-related',
|
||||
'description': 'Alert related calls of the API.'
|
||||
},
|
||||
{'name': 'admin-only',
|
||||
'description': 'Admin only calls of the API.'
|
||||
},
|
||||
|
|
|
@ -62,6 +62,11 @@ app.add_url_rule(
|
|||
view_func=routes.page_repository_conditions,
|
||||
methods=["GET", "POST"],
|
||||
)
|
||||
app.add_url_rule(
|
||||
"/api/v1/repositories/<int:rid>/alerts",
|
||||
view_func=routes.page_repository_alerts,
|
||||
methods=["GET", "POST"]
|
||||
)
|
||||
app.add_url_rule(
|
||||
"/api/v1/conditions/<int:cid>",
|
||||
view_func=routes.page_condition,
|
||||
|
|
|
@ -17,3 +17,16 @@ class Alert(ext.Model):
|
|||
repository = ext.relationship("Repository", back_populates="alerts")
|
||||
notifications = ext.relationship("Notification", back_populates="alert", cascade="all, delete")
|
||||
operations = ext.relationship("BoolOperation", back_populates="alert", cascade="all, delete")
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'window_size': self.window_size,
|
||||
'limit': self.limit,
|
||||
'repository_id': self.repository_id,
|
||||
'notifications': [notification.to_json() for notification in self.notifications],
|
||||
'operations': [operation.to_json() for operation in self.operations],
|
||||
'root_operation': [operation.to_json() for operation in self.operations if operation.is_root == True][
|
||||
0] if self.operations else None
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ from sqlalchemy.orm import backref
|
|||
|
||||
class BoolOperation(ext.Model):
|
||||
__tablename__ = "bool_operation"
|
||||
|
||||
id = ext.Column(ext.Integer, primary_key=True)
|
||||
operation = ext.Column(ext.Enum(OperationType), nullable=False)
|
||||
isRoot = ext.Column(ext.Boolean, default=False, nullable=False)
|
||||
|
@ -24,3 +25,13 @@ class BoolOperation(ext.Model):
|
|||
node_2 = ext.relationship("BoolOperation", primaryjoin=("bool_operation.c.node_2_id==bool_operation.c.id"),
|
||||
remote_side="BoolOperation.id", backref=backref("father_2", uselist=False))
|
||||
alert = ext.relationship("Alert", back_populates="operations")
|
||||
|
||||
def to_json(self):
|
||||
return {"id": self.id,
|
||||
"operation": self.operation,
|
||||
"is_root": self.is_root,
|
||||
"alert_id": self.alert_id,
|
||||
"condition": self.condition.to_json() if self.condition else None,
|
||||
"node_1": self.node_1.to_json() if self.node_1 else None,
|
||||
"node_2": self.node_2.to_json() if self.node_2 else None
|
||||
}
|
||||
|
|
|
@ -13,3 +13,10 @@ class Notification(ext.Model):
|
|||
alert_id = ext.Column(ext.Integer, ext.ForeignKey("alert.id"), nullable=False)
|
||||
# Relationships
|
||||
alert = ext.relationship("Alert", back_populates="notifications")
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"ora": self.ora.isoformat(),
|
||||
"alert_id": self.alert_id
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@ from .conditions import page_repository_conditions
|
|||
from .repository import page_repository
|
||||
from .repositories import page_repositories
|
||||
from .conditions import *
|
||||
from .alerts import *
|
|
@ -0,0 +1,2 @@
|
|||
from .repository_alerts import page_repository_alerts
|
||||
from .alert import page_alert
|
142
code/backend/nest_backend/routes/repository/alerts/alert.py
Normal file
142
code/backend/nest_backend/routes/repository/alerts/alert.py
Normal file
|
@ -0,0 +1,142 @@
|
|||
from flask import render_template, abort, jsonify, request
|
||||
from nest_backend.database import *
|
||||
from flask_jwt_extended import jwt_required
|
||||
from nest_backend.gestione import *
|
||||
from flask_cors import cross_origin
|
||||
import datetime
|
||||
|
||||
|
||||
@cross_origin()
|
||||
@jwt_required()
|
||||
@repository_auth
|
||||
def page_alert(aid):
|
||||
"""
|
||||
---
|
||||
get:
|
||||
summary: Get details about an alert.
|
||||
parameters:
|
||||
- in: path
|
||||
schema: AlertParameterSchema
|
||||
security:
|
||||
- jwt: []
|
||||
responses:
|
||||
'200':
|
||||
description: The details about the requested alert. The schema is incapsulated in Success.
|
||||
content:
|
||||
application/json:
|
||||
schema: Alert
|
||||
'404':
|
||||
description: Could not find the requested repository.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'403':
|
||||
description: The user is not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'401':
|
||||
description: The user is not logged in.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
tags:
|
||||
- alert-related
|
||||
delete:
|
||||
summary: Deletes an alert.
|
||||
parameters:
|
||||
- in: path
|
||||
schema: AlertParameterSchema
|
||||
security:
|
||||
- jwt: []
|
||||
responses:
|
||||
'200':
|
||||
description: The repository has been deleted successfully.
|
||||
'404':
|
||||
description: Could not find the requested repository.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'403':
|
||||
description: The user is not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'401':
|
||||
description: The user is not logged in.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'500':
|
||||
description: Could not delete the repository.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
tags:
|
||||
- alert-related
|
||||
patch:
|
||||
summary: Updates an alert.
|
||||
security:
|
||||
- jwt: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: CreateAlert
|
||||
parameters:
|
||||
- in: path
|
||||
schema: AlertParameterSchema
|
||||
|
||||
responses:
|
||||
'200':
|
||||
description: The repository has been updated successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema: Alert
|
||||
'404':
|
||||
description: Could not find the requested repository.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'403':
|
||||
description: The user is not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'401':
|
||||
description: The user is not logged in.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
tags:
|
||||
- alert-related
|
||||
"""
|
||||
user = find_user(get_jwt_identity())
|
||||
alert = Alert.query.filter_by(id=aid).first()
|
||||
if not alert:
|
||||
return json_error("Could not find alert."), 404
|
||||
if alert.repository not in [a.repository for a in user.authorizations] + user.owner_of:
|
||||
json_error("You are not authorized to proceed."), 403
|
||||
if request.method == "GET":
|
||||
return json_success(alert.to_json()), 200
|
||||
if alert.repository not in user.owner_of:
|
||||
json_error("You are not authorized to proceed."), 403
|
||||
if request.method == "PATCH":
|
||||
if 'name' in request.json:
|
||||
alert.name = request.json['name']
|
||||
if 'limit' in request.json:
|
||||
alert.limit = request.json['limit']
|
||||
if 'window_size' in request.json:
|
||||
alert.window_size = request.json['window_size']
|
||||
ext.session.commit()
|
||||
return json_success(alert.to_json()), 200
|
||||
elif request.method == "DELETE":
|
||||
try:
|
||||
ext.session.delete(alert)
|
||||
ext.session.commit()
|
||||
except Exception:
|
||||
return json_error("Something went wrong while deleting alert."), 500
|
||||
return json_success("Deletion completed."), 200
|
||||
elif request.method == "PUT":
|
||||
pass
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
from flask import render_template, abort, jsonify, request
|
||||
from nest_backend.database import *
|
||||
from flask_jwt_extended import jwt_required
|
||||
from nest_backend.gestione import *
|
||||
from flask_cors import cross_origin
|
||||
|
||||
|
||||
@cross_origin()
|
||||
@jwt_required()
|
||||
@repository_auth
|
||||
def page_repository_alerts(rid):
|
||||
"""
|
||||
---
|
||||
get:
|
||||
summary: Get a list of a repository alerts.
|
||||
parameters:
|
||||
- in: path
|
||||
schema: IntegerParameterSchema
|
||||
security:
|
||||
- jwt: []
|
||||
responses:
|
||||
'200':
|
||||
description: List of Alert schemas, incapsulated in Success.
|
||||
'401':
|
||||
description: The user is not logged in.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'403':
|
||||
description: The user is not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'404':
|
||||
description: The repository could not be found.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
tags:
|
||||
- repository-related
|
||||
post:
|
||||
summary: Creates an alert and attaches it to the repository.
|
||||
security:
|
||||
- jwt: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: CreateAlert
|
||||
responses:
|
||||
'200':
|
||||
description: The alert has been created successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema: Alert
|
||||
'403':
|
||||
description: The user is not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
'401':
|
||||
description: The user is not logged in.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
tags:
|
||||
- alert-related
|
||||
"""
|
||||
|
||||
repository = Repository.query.filter_by(id=rid).first()
|
||||
if not repository:
|
||||
return json_error("Could not find repository"), 404
|
||||
user = find_user(get_jwt_identity())
|
||||
if user.email != repository.owner_id:
|
||||
return json_error("You are not authorized."), 403
|
||||
|
||||
if request.method == "GET":
|
||||
return json_success([alert.to_json() for alert in repository.alerts])
|
||||
|
||||
if request.method == "POST":
|
||||
if 'name' not in request.json:
|
||||
json_error("Missing name."), 400
|
||||
if 'limit' not in request.json:
|
||||
json_error('Missing limit'), 400
|
||||
if 'window_size' not in request.json:
|
||||
json_error('Missing window size'), 400
|
||||
alert = Alert(name=request.json['name'], limit=request.json['limit'], window_size=request.json['window_size'],
|
||||
repository_id=rid)
|
||||
ext.session.add(alert)
|
||||
ext.session.commit()
|
||||
|
||||
return json_success(alert.to_json()), 200
|
Loading…
Reference in a new issue