Some new routes for schedule plugin

This commit is contained in:
Ferdinand Thiessen 2020-09-07 16:13:18 +02:00
parent 0abde3e899
commit 7caaea71a7
5 changed files with 196 additions and 401 deletions

View File

@ -4,8 +4,6 @@
Initialize also a singleton for the AccessTokenController and start the Thread.
"""
from datetime import datetime
import yaml
import logging
import pkg_resources

View File

@ -1,7 +1,7 @@
#############################################
# Plugin: Auth #
# Functionality: Allow management of #
# authentication, login, logout, etc #
# authentication, login, logout, etc #
#############################################
from flask import Blueprint, request, jsonify

View File

@ -6,27 +6,57 @@ from datetime import datetime, timedelta
from flaschengeist.system.controller import eventController
from flaschengeist.system.database import db
from flaschengeist.system.decorator import login_required
from flaschengeist.system.models.event import Event, EventKind
from flaschengeist.system.models.event import EventKind
schedule_bp = Blueprint("schedule", __name__)
schedule_bp = Blueprint("schedule", __name__, url_prefix="/schedule")
def register():
return schedule_bp
@schedule_bp.route("/schedule/events", methods=['GET'])
@schedule_bp.route("/schedule/events/<int:year>", methods=['GET'])
@schedule_bp.route("/schedule/events/<int:year>/<int:month>", methods=['GET'])
@schedule_bp.route("/schedule/events/<int:year>/<int:month>/<int:day>", methods=['GET'])
####################################################################################
# Routes #
# #
# /schedule/events POST: create new #
# GET: get all events this month #
# /schedule/events/<year>/<month> GET: get events by month / date #
# /<year>/<month>/<day> #
# /schedule/events/<id> GET: get event by ID #
# DELETE: delete specified event #
# PUT: modify specified event #
# /schedule/events/<id>/slots GET: get EventSlots of Event #
# POST: add new EventSlot to Event #
# /schedule/events/<id>/slots/<sid> PUT: modify EventSlot #
# GET: get specified EventSlot #
# /schedule/events/<id>/slots/<sid>/jobs POST: add User #
# /schedule/eventKinds
# /schedule/eventKinds/<id>
# PUT: modify user #
# DELETE: remove user #
####################################################################################
@schedule_bp.route("/events/<int:id>", methods=['GET'])
@login_required() # roles=['schedule_read'])
def _get_events(year=datetime.now().year, month=None, day=None, **kwrags):
def __get_event(id, **kwargs):
event = eventController.get_event(id)
if not event:
raise NotFound
return jsonify(event)
@schedule_bp.route("/events", methods=['GET'])
@schedule_bp.route("/events/<int:year>/<int:month>", methods=['GET'])
@schedule_bp.route("/events/<int:year>/<int:month>/<int:day>", methods=['GET'])
@login_required() # roles=['schedule_read'])
def __get_events(year=datetime.now().year, month=datetime.now().month, day=None, **kwrags):
"""Get Event objects for specified date (or month or year),
if nothing set then events for current year are returned
if nothing set then events for current month are returned
Args:
year (int, optional): year to query, defaults to current year
month (int, optional): month to query (if set)
month (int, optional): month to query (if set), defaults to current month
day (int, optional): day to query events for (if set)
**kwrags: contains at least access_token (see flaschengeist.decorator)
Returns:
@ -35,35 +65,40 @@ def _get_events(year=datetime.now().year, month=None, day=None, **kwrags):
BadRequest: If date is invalid
"""
try:
begin = datetime(year=year, month=1, day=1)
end = None
if month:
begin = datetime(year=year, month=month, day=1)
if day:
begin += timedelta(days=day - 1)
end = begin + timedelta(days=1)
else:
end = datetime(year=year, month=month + 1, day=1)
begin = datetime(year=year, month=month, day=1)
if day:
begin += timedelta(days=day - 1)
end = begin + timedelta(days=1)
else:
end = datetime(year=year + 1, month=1, day=1)
end = datetime(year=year, month=month + 1, day=1)
events = Event.query.filter((begin <= Event.begin), (Event.begin < end))
events = eventController.get_events(begin, end)
return jsonify(events)
except ValueError:
raise BadRequest("Invalid date given")
@schedule_bp.route("/schedule/eventKinds", methods=['POST'])
@schedule_bp.route("/eventKinds", methods=['POST'])
@login_required()
def __new_event_kind(**kwargs):
data = request.get_json()
if "name" not in data:
raise BadRequest
event = eventController.create_event_kind(data["name"])
return jsonify({"ok": "ok", "id": event.id})
kind = eventController.create_event_kind(data["name"])
return jsonify({"ok": "ok", "id": kind.id})
@schedule_bp.route("/schedule/events", methods=['POST'])
@schedule_bp.route("/slotKinds", methods=["POST"])
@login_required()
def __new_slot_kind(**kwargs):
data = request.get_json()
if not data or "name" not in data:
raise BadRequest
kind = eventController.create_job_kind(data["name"])
return jsonify({"ok": "ok", "id": kind.id})
@schedule_bp.route("/events", methods=['POST'])
@login_required()
def __new_event(**kwargs):
data = request.get_json()
@ -74,383 +109,85 @@ def __new_event(**kwargs):
return jsonify({"ok": "ok", "id": event.id})
@schedule_bp.route("/schedule/events/<int:id>", methods=["DELETE"])
@schedule_bp.route("/events/<int:id>", methods=["DELETE"])
@login_required()
def __delete_event(id, **kwargs):
if Event.query.filter(Event.id == id).delete() != 1:
if not eventController.delete_event(id):
raise NotFound
db.session.commit()
return jsonify({'ok': 'ok'})
@schedule_bp.route("/eventKinds/<int:id>", methods=["PUT"])
@login_required()
def __edit_event_kind(id, **kwargs):
data = request.get_json()
if not data or "name" not in data:
raise BadRequest
eventController.rename_event_kind(id, data["name"])
return jsonify({"ok": "ok"})
@schedule_bp.route("/events/<int:event_id>/slots", methods=["GET"])
@login_required()
def __get_slots(event_id, **kwargs):
event = eventController.get_event(event_id)
if not event:
raise NotFound
return jsonify({event.slots})
@schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["GET"])
@login_required()
def __get_slot(event_id, slot_id, **kwargs):
slot = eventController.get_event_slot(slot_id, event_id)
if slot:
return jsonify(slot)
raise NotFound
@schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["DELETE"])
@login_required()
def __delete_slot(event_id, slot_id, **kwargs):
if eventController.delete_event_slot(slot_id, event_id):
return jsonify({"ok": "ok"})
raise NotFound
@schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["PUT"])
@login_required()
def __update_slot(event_id, slot_id, **kwargs):
data = request.get_json()
if not data:
raise BadRequest
for job in data['jobs']:
eventController.add_job(job.kind, job.user)
if eventController.delete_event_slot(slot_id, event_id):
return jsonify({"ok": "ok"})
raise NotFound
@schedule_bp.route("/events/<int:event_id>/slots", methods=["POST"])
@login_required()
def __add_slot(event_id, **kwargs):
event = eventController.get_event(event_id)
if not event:
raise NotFound
data = request.get_json()
attr = {"job_slots": []}
try:
if "start" in data:
attr["start"] = parser.isoparse(data["start"])
if "end" in data:
attr["end"] = parser.isoparse(data["end"])
for job in data["jobs"]:
attr["job_slots"].append({"needed_persons": job["needed_persons"], "kind": job["kind"]})
except KeyError:
raise BadRequest("Missing data in request")
eventController.add_slot(event, **attr)
return jsonify({"ok": "ok"})
def __edit_event():
...
# try:
# data = request.get_json()
# from_date = data['from_date']
# to_date = data['to_date']
# from_date = datetime(from_date['year'], from_date['month'], from_date['day'])
# to_date = datetime(to_date['year'], to_date['month'], to_date['day'])
# lockedDays = mainController.getLockedDays(from_date, to_date)
# retVal = []
# for lockedDay in lockedDays:
# day = datetime.combine(lockedDay['daydate'], time(12))
# retDay = {
# "worker": mainController.getWorker(day),
# "day": {
# "date": {
# "year": day.year,
# "month": day.month,
# "day": day.day
# },
# "locked": lockedDay['locked']
# },
# "jobkinddate": mainController.getJobKindDates(day.date())
# }
# retVal.append(retDay)
#
# logger.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# logger.warn("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
# @schedule.route("/user/jobsOnDates", methods=['POST'])
# @login_required(groups=[USER])
# def _getJobsOnDates(**kwargs):
# debug.info("/user/jobsOnDates")
# try:
# data = request.get_json()
# lockedDays = mainController.getLockedDaysFromList(data)
# retVal = []
# for lockedDay in lockedDays:
# day = datetime.combine(lockedDay['daydate'], time(12))
# retDay = {
# "worker": mainController.getWorker(day),
# "day": {
# "date": {
# "year": day.year,
# "month": day.month,
# "day": day.day
# },
# "locked": lockedDay['locked']
# },
# "jobkinddate": mainController.getJobKindDates(day.date())
# }
# retVal.append(retDay)
#
# debug.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
# @schedule.route("/user/job", methods=['POST'])
# @login_required(groups=[USER])
# def _getUser(**kwargs):
# debug.info("/user/job")
# try:
# data = request.get_json()
# day = data['day']
# month = data['month']
# year = data['year']
# date = datetime(year, month, day, 12)
# lockedDay = mainController.getLockedDay(date)
# if not lockedDay:
# lockedDay = {
# 'date': {
# 'year': year,
# 'month': month,
# 'day': day
# },
# 'locked': False
# }
# else:
# lockedDay = {
# 'date': {
# 'year': year,
# 'month': month,
# 'day': day
# },
# 'locked': lockedDay['locked']
# }
# retVal = {
# 'worker': mainController.getWorker(date),
# 'day': lockedDay
# }
# debug.debug("retrun {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
#
# @schedule.route("/user/addJob", methods=['POST'])
# @login_required(groups=[USER])
# def _addUser(**kwargs):
# debug.info("/user/addJob")
# try:
# if 'accToken' in kwargs:
# accToken = kwargs['accToken']
# user = accToken.user
# data = request.get_json()
# day = data['day']
# month = data['month']
# year = data['year']
# date = datetime(year, month, day, 12)
# job_kind = None
# if 'job_kind' in data:
# job_kind = data['job_kind']
# mainController.addWorker(user.uid, date, job_kind=job_kind, userExc=True)
# retVal = mainController.getWorker(date)
# debug.debug("return {{ {} }}".format(retVal))
# jobL.info("Mitglied {} {} schreib sich am {} zum Dienst ein.".format(
# user.firstname, user.lastname, date.date()))
# return jsonify(retVal)
# except DayLocked as err:
# debug.debug("exception", exc_info=True)
# return jsonify({'error': str(err)}), 403
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({'error': str(err)}), 409
#
#
# @schedule.route("/user/deleteJob", methods=['POST'])
# @login_required(groups=[USER])
# def _deletJob(**kwargs):
# debug.info("/user/deleteJob")
# try:
# if 'accToken' in kwargs:
# accToken = kwargs['accToken']
# user = accToken.user
# data = request.get_json()
# day = data['day']
# month = data['month']
# year = data['year']
# date = datetime(year, month, day, 12)
# mainController.deleteWorker(user.uid, date, True)
# retVal = mainController.getWorker(date)
# debug.debug("return ok")
# jobL.info("Mitglied {} {} entfernt sich am {} aus dem Dienst".format(
# user.firstname, user.lastname, date.date()))
# return jsonify(retVal)
# except DayLocked as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 403
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 409
#
# @schedule.route("/user/getJobInvites", methods=['POST'])
# @login_required(groups=[USER])
# def _getJobInvites(**kwargs):
# try:
# debug.info("/user/getJobInvites")
# from_user = None
# to_user = None
# on_date = None
#
# data = request.get_json()
#
# if 'from_user' in data:
# from_user = data['from_user']
# if 'to_user' in data:
# to_user = data['to_user']
# on_date = date(data['date']['year'], data['date']['month'], data['date']['day'])
# retVal = mainController.getJobInvites(from_user, to_user, on_date)
# debug.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
# @schedule.route("/user/JobInvites", methods=['PUT', 'POST'])
# @login_required(groups=[USER])
# def _JobInvites(**kwargs):
# try:
# debug.info("/user/JobInvites")
# data = request.get_json()
# if request.method == 'PUT':
# mainController.setJobInvites(data)
# retVal = mainController.getJobInvites(kwargs['accToken'].user.toJSON(), None, datetime.now().date())
# debug.debug("return {{ {} }}".format(retVal))
# if request.method == 'POST':
# retVal = mainController.updateJobInvites(data)
#
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
# @schedule.route("/user/deleteJobInvite", methods=['POST'])
# @login_required(groups=[USER])
# def _deleteJobInvite(**kwargs):
# try:
# debug.info("/user/deleteJobInvite")
# data = request.get_json()
# mainController.deleteJobInvite(data)
# retVal = mainController.getJobInvites(data['from_user'], None, datetime.now().date())
# debug.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
#
# @schedule.route("/user/getJobRequests", methods=['POST'])
# @login_required(groups=[USER])
# def _getJobRequests(**kwargs):
# try:
# debug.info("/user/getJobRequests")
# from_user = None
# to_user = None
# on_date = None
#
# data = request.get_json()
#
# if 'from_user' in data:
# from_user = data['from_user']
# if 'to_user' in data:
# to_user = data['to_user']
# on_date = date(data['date']['year'], data['date']['month'], data['date']['day'])
# retVal = mainController.getJobRequests(from_user, to_user, on_date)
# debug.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
# @schedule.route("/user/JobRequests", methods=['PUT', 'POST'])
# @login_required(groups=[USER])
# def _JobRequests(**kwargs):
# try:
# debug.info("/user/JobRequests")
# data = request.get_json()
# if request.method == 'PUT':
# mainController.setJobRequests(data)
# retVal = mainController.getJobRequests(kwargs['accToken'].user.toJSON(), None, datetime.now().date())
# debug.debug("return {{ {} }}".format(retVal))
# if request.method == 'POST':
# data['on_date'] = date(data['on_date']['year'], data['on_date']['month'], data['on_date']['day'])
# retVal = mainController.updateJobRequests(data)
#
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
#
# @schedule.route("/user/deleteJobRequest", methods=['POST'])
# @login_required(groups=[USER])
# def _deleteJobRequest(**kwargs):
# try:
# debug.info("/user/deleteJobRequest")
# data = request.get_json()
# mainController.deleteJobRequest(data)
# retVal = mainController.getJobRequests(data['from_user'], None, datetime.now().date())
# debug.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500
# CREDIT == Gerücht? CreditList?
# creditL = getCreditLogger()
# @schedule.route("/user/main")
# @login_required(groups=[USER])
# def _main(**kwargs):
# debug.info("/user/main")
# try:
# if 'accToken' in kwargs:
# accToken = kwargs['accToken']
# accToken.user = mainController.getUser(accToken.user.uid)
# retVal = accToken.user.toJSON()
# retVal['creditList'] = {credit.year: credit.toJSON()
# for credit in accToken.user.geruechte}
# debug.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception:
# debug.debug("exception", exc_info=True)
# return jsonify("error", "something went wrong"), 500
# @schedule.route("/user/addAmount", methods=['POST'])
# @login_required(groups=[USER])
# def _addAmount(**kwargs):
# debug.info("/user/addAmount")
# try:
# if 'accToken' in kwargs:
# accToken = kwargs['accToken']
# data = request.get_json()
# amount = int(data['amount'])
# date = datetime.now()
# mainController.addAmount(
# accToken.user.uid, amount, year=date.year, month=date.month)
# accToken.user = mainController.getUser(accToken.user.uid)
# retVal = accToken.user.toJSON()
# retVal['creditList'] = {credit.year: credit.toJSON()
# for credit in accToken.user.geruechte}
# debug.debug("return {{ {} }}".format(retVal))
# creditL.info("{} {} {} fügt sich selbst {} € Schulden hinzu".format(
# date, accToken.user.firstname, accToken.user.lastname, amount/100))
# return jsonify(retVal)
# except Exception:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": "something went wrong"}), 500
# @schedule.route("/user/saveConfig", methods=['POST'])
# @login_required(groups=[USER])
# def _saveConfig(**kwargs):
# debug.info("/user/saveConfig")
# try:
# if 'accToken' in kwargs:
# accToken = kwargs['accToken']
# data = request.get_json()
# password = data['acceptedPassword']
# data.pop('acceptedPassword')
# accToken.user = mainController.modifyUser(
# accToken.user, data, password)
# retVal = accToken.user.toJSON()
# retVal['creditList'] = {credit.year: credit.toJSON()
# for credit in accToken.user.geruechte}
# debug.debug("return {{ {} }}".format(retVal))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 409
#
# @schedule.route("/user/storno", methods=['POST'])
# @login_required(groups=[USER])
# def _storno(**kwargs):
# """ Function for Baruser to storno amount
#
# This function added to the user with the posted userID the posted amount.
#
# Returns:
# JSON-File with userID and the amount
# or ERROR 401 Permission Denied
# """
#
# debug.info("/user/storno")
# try:
# if 'accToken' in kwargs:
# accToken = kwargs['accToken']
# user = accToken.user
# data = request.get_json()
# amount = int(data['amount'])
#
# date = datetime.now()
# mainController.addCredit(
# user.uid, amount, year=date.year, month=date.month)
# accToken.user = mainController.getUser(accToken.user.uid)
# retVal = accToken.user.toJSON()
# retVal['creditList'] = {credit.year: credit.toJSON()
# for credit in accToken.user.geruechte}
# debug.debug("return {{ {} }}".format(retVal))
# creditL.info("{} {} {} storniert {} €".format(
# date, user.firstname, user.lastname, amount/100))
# return jsonify(retVal)
# except Exception as err:
# debug.debug("exception", exc_info=True)
# return jsonify({"error": str(err)}), 500

View File

@ -1,12 +1,37 @@
from werkzeug.exceptions import BadRequest
from werkzeug.exceptions import BadRequest, NotFound
from flaschengeist.system.models.event import EventKind, Event
from flaschengeist.system.models.event import EventKind, Event, EventSlot, JobSlot, JobKind
from sqlalchemy.exc import IntegrityError
from flaschengeist import logger
from flaschengeist.system.database import db
def get_event(id):
return Event.query.get(id)
def get_events(begin, end):
"""Query events which start from begin until end
Args:
begin (datetime): Earliest start
end (datetime): Latest start
Returns: collection of Event objects
"""
return Event.query.filter((begin <= Event.begin), (Event.begin < end))
def delete_event(id):
"""Delete event with given ID
Args:
id: id of Event to delete
Returns: True if successful, False if Event is not found
"""
return Event.query.filter(Event.id == id).delete() == 1
def create_event(begin, kind, end=None, description=None):
try:
event = Event(begin=begin,
@ -21,6 +46,17 @@ def create_event(begin, kind, end=None, description=None):
raise BadRequest
def create_job_kind(name):
try:
kind = JobKind(name=name)
db.session.add(kind)
db.session.commit()
return kind
except IntegrityError:
logger.debug("IntegrityError: Looks like there is a name collision", exc_info=True)
raise BadRequest("Name already exists")
def create_event_kind(name):
try:
event = EventKind(name=name)
@ -30,3 +66,24 @@ def create_event_kind(name):
except IntegrityError:
logger.debug("IntegrityError: Looks like there is a name collision", exc_info=True)
raise BadRequest("Name already exists")
def rename_event_kind(id, name):
ek = EventKind.query.get(id)
if not ek:
raise NotFound
ek.name = name
try:
db.session.commit()
except IntegrityError:
raise BadRequest("Name already exists")
def add_slot(event, job_slots, needed_persons, start=None, end=None):
event_slot = EventSlot(start=start, end=end)
for slot in job_slots:
kind = JobKind.query.get(slot.id)
job_slot = JobSlot(kind=kind, needed_persons=slot.needed_persons)
event_slot.add_slot(job_slot)
event.add_slot(event_slot)
db.session.commit()

View File

@ -27,7 +27,10 @@ def modify_user(user, password, new_password=None):
Args:
user: User object to sync with backend
password: Current password (most backends are needing this)
password: Cu db.session.commit()
# TODO: is this needed?
def user_has_rorrent password (most backends are needing this)
new_password (optional): New password, if password should be changed
Raises: