[events] Improved event plugin

This commit is contained in:
Ferdinand Thiessen 2021-03-21 00:55:50 +01:00
parent 4cd353cf4e
commit b60c405f76
3 changed files with 54 additions and 67 deletions

View File

@ -30,6 +30,12 @@ class EventPlugin(Plugin):
) )
@schedule_bp.route("/templates", methods=["GET"])
@login_required()
def get_templates(current_session):
return jsonify(event_controller.get_templates())
@schedule_bp.route("/event-types", methods=["GET"]) @schedule_bp.route("/event-types", methods=["GET"])
@schedule_bp.route("/event-types/<int:identifier>", methods=["GET"]) @schedule_bp.route("/event-types/<int:identifier>", methods=["GET"])
@login_required() @login_required()
@ -185,6 +191,19 @@ def get_event(event_id, current_session):
@schedule_bp.route("/events", methods=["GET"]) @schedule_bp.route("/events", methods=["GET"])
@login_required()
def get_filtered_events(current_session):
begin = request.args.get('from')
if begin is not None:
begin = from_iso_format(begin)
end = request.args.get('to')
if end is not None:
end = from_iso_format(end)
if begin is None and end is None:
begin = datetime.now()
return jsonify(event_controller.get_events(begin, end))
@schedule_bp.route("/events/<int:year>/<int:month>", methods=["GET"]) @schedule_bp.route("/events/<int:year>/<int:month>", methods=["GET"])
@schedule_bp.route("/events/<int:year>/<int:month>/<int:day>", methods=["GET"]) @schedule_bp.route("/events/<int:year>/<int:month>/<int:day>", methods=["GET"])
@login_required() @login_required()
@ -221,21 +240,20 @@ def get_events(current_session, year=datetime.now().year, month=datetime.now().m
def _add_job(event, data): def _add_job(event, data):
end = None
try: try:
start = from_iso_format(data["start"]) start = from_iso_format(data["start"])
end = None
if "end" in data:
end = from_iso_format(data["end"])
required_services = data["required_services"]
job_type = data["type"]
if isinstance(job_type, dict):
job_type = data["type"]["id"]
except (KeyError, ValueError): except (KeyError, ValueError):
raise BadRequest("Missing POST parameter") raise BadRequest("Missing or invalid POST parameter")
if "end" in data:
end = from_iso_format(data["end"])
if "required_services" not in data:
raise BadRequest
job_type = data["type"]
if isinstance(job_type, dict):
job_type = data["type"]["id"]
job_type = event_controller.get_job_type(job_type) job_type = event_controller.get_job_type(job_type)
event_controller.add_job(event, job_type, data["required_services"], start, end, comment=data.get("comment")) event_controller.add_job(event, job_type, required_services, start, end, comment=data.get("comment", None))
@schedule_bp.route("/events", methods=["POST"]) @schedule_bp.route("/events", methods=["POST"])
@ -268,15 +286,13 @@ def create_event(current_session):
except (NotFound, ValueError): except (NotFound, ValueError):
raise BadRequest("Invalid parameter") raise BadRequest("Invalid parameter")
recurrence_rule = None
if "recurrence_rule" in data:
recurrence_rule = event_controller.create_recurrence(data=data["recurrence_rule"])
event = event_controller.create_event( event = event_controller.create_event(
start=start, start=start,
end=end, end=end,
name=data.get("name", None),
is_template=data.get("is_template", None),
event_type=event_type, event_type=event_type,
description=data.get("description", None), description=data.get("description", None),
recurrence_rule=recurrence_rule,
) )
if "jobs" in data: if "jobs" in data:
for job in data["jobs"]: for job in data["jobs"]:
@ -390,7 +406,7 @@ def update_job(event_id, job_id, current_session: Session):
current_session: Session sent with Authorization Header current_session: Session sent with Authorization Header
Returns: Returns:
JSON encoded Event object or HTTP-error JSON encoded Job object or HTTP-error
""" """
job = event_controller.get_job(job_id, event_id) job = event_controller.get_job(job_id, event_id)
@ -419,7 +435,7 @@ def update_job(event_id, job_id, current_session: Session):
job.type = event_controller.get_job_type(data["type"]) job.type = event_controller.get_job_type(data["type"])
event_controller.update() event_controller.update()
return jsonify(job.event_) return jsonify(job)
# TODO: JobTransfer # TODO: JobTransfer

View File

@ -1,9 +1,13 @@
from datetime import datetime
from typing import Optional
from sqlalchemy import or_, and_
from werkzeug.exceptions import BadRequest, NotFound from werkzeug.exceptions import BadRequest, NotFound
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from flaschengeist import logger from flaschengeist import logger
from flaschengeist.database import db from flaschengeist.database import db
from flaschengeist.plugins.events.models import EventType, Event, Job, JobType, Service, RecurrenceRule from flaschengeist.plugins.events.models import EventType, Event, Job, JobType, Service
from flaschengeist.utils.datetime import from_iso_format from flaschengeist.utils.datetime import from_iso_format
@ -105,7 +109,11 @@ def get_event(event_id) -> Event:
return event return event
def get_events(start, end): def get_templates():
return Event.query.filter(Event.is_template == True).all()
def get_events(start: Optional[datetime] = None, end=None):
"""Query events which start from begin until end """Query events which start from begin until end
Args: Args:
start (datetime): Earliest start start (datetime): Earliest start
@ -113,7 +121,12 @@ def get_events(start, end):
Returns: collection of Event objects Returns: collection of Event objects
""" """
return Event.query.filter((start <= Event.start), (Event.start < end)).all() query = Event.query.filter(Event.is_template.__eq__(False))
if start is not None:
query = query.filter(start <= Event.start)
if end is not None:
query = query.filter(Event.start < end)
return query.all()
def delete_event(event_id): def delete_event(event_id):
@ -129,15 +142,13 @@ def delete_event(event_id):
db.session.commit() db.session.commit()
def create_event(event_type, start, end=None, jobs=[], description=None, recurrence_rule=None): def create_event(event_type, start, end=None, jobs=[], is_template=None, name=None, description=None):
try: try:
logger.debug(event_type) logger.debug(event_type)
event = Event( event = Event(
start=start, end=end, description=description, type=event_type, jobs=jobs, recurrence_rule=recurrence_rule start=start, end=end, name=name, description=description, type=event_type, is_template=is_template, jobs=jobs
) )
db.session.add(event) db.session.add(event)
if recurrence_rule is not None:
event = Event(start=start, end=end, description=description, type=event_type, jobs=jobs, template_=event)
db.session.commit() db.session.commit()
return event return event
except IntegrityError: except IntegrityError:
@ -185,18 +196,3 @@ def assign_to_job(job: Job, user, value):
service = Service(user_=user, value=value, job_=job) service = Service(user_=user, value=value, job_=job)
db.session.add(service) db.session.add(service)
db.session.commit() db.session.commit()
def create_recurrence(data=None, count=None, end_date=None, frequency=None, interval=None):
if data is not None:
if "frequency" not in data:
raise BadRequest("Missing POST parameter")
frequency = data["frequency"]
if "end_date" in data:
end_date = from_iso_format(data["end_date"])
if "count" in data:
count = data["count"]
if "interval" in data:
interval = data["interval"]
recurrence = RecurrenceRule(frequency=frequency, end_date=end_date, count=count, interval=interval)
db.session.add(recurrence)

View File

@ -67,32 +67,12 @@ class Job(db.Model, ModelSerializeMixin):
event_ = db.relationship("Event", back_populates="jobs") event_ = db.relationship("Event", back_populates="jobs")
event_id_ = db.Column("event_id", db.Integer, db.ForeignKey(f"{_table_prefix_}event.id"), nullable=False) event_id_ = db.Column("event_id", db.Integer, db.ForeignKey(f"{_table_prefix_}event.id"), nullable=False)
__table_args__ = (UniqueConstraint("type_id", "start", name="_type_start_uc"),) __table_args__ = (UniqueConstraint("type_id", "start", "event_id", name="_type_start_uc"),)
########## ##########
# Events # # Events #
########## ##########
class _Frequency(enum.Enum):
daily = 1
weekly = 2
monthly = 3
yearly = 4
class RecurrenceRule(db.Model, ModelSerializeMixin):
__tablename__ = _table_prefix_ + "recurrence_rule"
frequency: str = db.Column(db.Enum(_Frequency))
until: Optional[datetime] = db.Column(UtcDateTime)
count: Optional[int] = db.Column(db.Integer)
interval: int = db.Column(db.Integer, nullable=False, default=1)
id_: int = db.Column("id", db.Integer, primary_key=True)
class Event(db.Model, ModelSerializeMixin): class Event(db.Model, ModelSerializeMixin):
"""Model for an Event""" """Model for an Event"""
@ -100,19 +80,14 @@ class Event(db.Model, ModelSerializeMixin):
id: int = db.Column(db.Integer, primary_key=True) id: int = db.Column(db.Integer, primary_key=True)
start: datetime = db.Column(UtcDateTime, nullable=False) start: datetime = db.Column(UtcDateTime, nullable=False)
end: Optional[datetime] = db.Column(UtcDateTime) end: Optional[datetime] = db.Column(UtcDateTime)
description: Optional[str] = db.Column(db.String(255)) name: Optional[str] = db.Column(db.String(255))
description: Optional[str] = db.Column(db.String(512))
type: Union[EventType, int] = db.relationship("EventType") type: Union[EventType, int] = db.relationship("EventType")
is_template: bool = db.Column(db.Boolean, default=False)
jobs: list[Job] = db.relationship( jobs: list[Job] = db.relationship(
"Job", back_populates="event_", cascade="all,delete,delete-orphan", order_by="[Job.start, Job.end]" "Job", back_populates="event_", cascade="all,delete,delete-orphan", order_by="[Job.start, Job.end]"
) )
recurrence_rule: Optional[RecurrenceRule] = db.relationship("RecurrenceRule")
template_id: Optional[int] = db.Column("template_id", db.Integer, db.ForeignKey(f"{_table_prefix_}event.id"))
# Not exported properties for backend use
template_ = db.relationship("Event")
# Protected for internal use # Protected for internal use
_recurrence_rule_id = db.Column(
"recurrence_rule_id", db.Integer, db.ForeignKey(f"{_table_prefix_}recurrence_rule.id")
)
_type_id = db.Column( _type_id = db.Column(
"type_id", db.Integer, db.ForeignKey(f"{_table_prefix_}event_type.id", ondelete="CASCADE"), nullable=False "type_id", db.Integer, db.ForeignKey(f"{_table_prefix_}event_type.id", ondelete="CASCADE"), nullable=False
) )