[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/<int:identifier>", methods=["GET"])
@login_required()
@ -185,6 +191,19 @@ def get_event(event_id, current_session):
@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>/<int:day>", methods=["GET"])
@login_required()
@ -221,21 +240,20 @@ def get_events(current_session, year=datetime.now().year, month=datetime.now().m
def _add_job(event, data):
end = None
try:
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):
raise BadRequest("Missing POST parameter")
if "end" in data:
end = from_iso_format(data["end"])
raise BadRequest("Missing or invalid POST parameter")
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)
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"])
@ -268,15 +286,13 @@ def create_event(current_session):
except (NotFound, ValueError):
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(
start=start,
end=end,
name=data.get("name", None),
is_template=data.get("is_template", None),
event_type=event_type,
description=data.get("description", None),
recurrence_rule=recurrence_rule,
)
if "jobs" in data:
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
Returns:
JSON encoded Event object or HTTP-error
JSON encoded Job object or HTTP-error
"""
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"])
event_controller.update()
return jsonify(job.event_)
return jsonify(job)
# 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 sqlalchemy.exc import IntegrityError
from flaschengeist import logger
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
@ -105,7 +109,11 @@ def get_event(event_id) -> 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
Args:
start (datetime): Earliest start
@ -113,7 +121,12 @@ def get_events(start, end):
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):
@ -129,15 +142,13 @@ def delete_event(event_id):
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:
logger.debug(event_type)
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)
if recurrence_rule is not None:
event = Event(start=start, end=end, description=description, type=event_type, jobs=jobs, template_=event)
db.session.commit()
return event
except IntegrityError:
@ -185,18 +196,3 @@ def assign_to_job(job: Job, user, value):
service = Service(user_=user, value=value, job_=job)
db.session.add(service)
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_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 #
##########
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):
"""Model for an Event"""
@ -100,19 +80,14 @@ class Event(db.Model, ModelSerializeMixin):
id: int = db.Column(db.Integer, primary_key=True)
start: datetime = db.Column(UtcDateTime, nullable=False)
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")
is_template: bool = db.Column(db.Boolean, default=False)
jobs: list[Job] = db.relationship(
"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
_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.Integer, db.ForeignKey(f"{_table_prefix_}event_type.id", ondelete="CASCADE"), nullable=False
)