Fixed Hooks, use own implementation. Fixed routes.
This commit is contained in:
		
							parent
							
								
									287cc91947
								
							
						
					
					
						commit
						ec05cde746
					
				| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
from pyhooks import precall_register
 | 
			
		||||
from flaschengeist.system.hook import HookCall
 | 
			
		||||
 | 
			
		||||
send_message_hook = precall_register("send_message")
 | 
			
		||||
send_message_hook = HookCall("send_message")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Plugin:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ from werkzeug.local import LocalProxy
 | 
			
		|||
from flaschengeist import logger
 | 
			
		||||
from flaschengeist.modules import Plugin
 | 
			
		||||
from flaschengeist.system.decorator import login_required
 | 
			
		||||
from flaschengeist.system.controller import accessTokenController, userController
 | 
			
		||||
from flaschengeist.system.controller import accessTokenController, userController, messageController
 | 
			
		||||
 | 
			
		||||
access_controller = LocalProxy(lambda: accessTokenController.AccessTokenController())
 | 
			
		||||
auth_bp = Blueprint("auth", __name__)
 | 
			
		||||
| 
						 | 
				
			
			@ -21,89 +21,96 @@ class AuthRoutePlugin(Plugin):
 | 
			
		|||
    def __init__(self, conf):
 | 
			
		||||
        super().__init__(blueprint=auth_bp)
 | 
			
		||||
 | 
			
		||||
    #################################################
 | 
			
		||||
    #                     Routes                    #
 | 
			
		||||
    #                                               #
 | 
			
		||||
    # /auth           POST: login (new token)       #
 | 
			
		||||
    #                  GET: get all tokens for user #
 | 
			
		||||
    # /auth/<token>    GET: get lifetime of token   #
 | 
			
		||||
    #                  PUT: set new lifetime        #
 | 
			
		||||
    #               DELETE: logout / delete token   #
 | 
			
		||||
    #################################################
 | 
			
		||||
#################################################
 | 
			
		||||
#                     Routes                    #
 | 
			
		||||
#                                               #
 | 
			
		||||
# /auth           POST: login (new token)       #
 | 
			
		||||
#                  GET: get all tokens for user #
 | 
			
		||||
# /auth/<token>    GET: get lifetime of token   #
 | 
			
		||||
#                  PUT: set new lifetime        #
 | 
			
		||||
#               DELETE: logout / delete token   #
 | 
			
		||||
#################################################
 | 
			
		||||
 | 
			
		||||
    @auth_bp.route("/auth", methods=["POST"])
 | 
			
		||||
    def _create_token():
 | 
			
		||||
        """Login User
 | 
			
		||||
 | 
			
		||||
        Login in User and create an AccessToken for the User.
 | 
			
		||||
        Requires POST data {'userid': string, 'password': string}
 | 
			
		||||
        Returns:
 | 
			
		||||
            A JSON-File with user information and created token or errors
 | 
			
		||||
        """
 | 
			
		||||
        logger.debug("Start log in.")
 | 
			
		||||
        data = request.get_json()
 | 
			
		||||
        try:
 | 
			
		||||
            userid = data["userid"]
 | 
			
		||||
            password = data["password"]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            raise BadRequest("Missing parameter(s)")
 | 
			
		||||
@auth_bp.route("/auth", methods=["POST"])
 | 
			
		||||
def _create_token():
 | 
			
		||||
    """Login User
 | 
			
		||||
 | 
			
		||||
        logger.debug("search user {{ {} }} in database".format(userid))
 | 
			
		||||
        user = userController.login_user(userid, password)
 | 
			
		||||
        if not user:
 | 
			
		||||
            raise Unauthorized
 | 
			
		||||
        logger.debug("user is {{ {} }}".format(user))
 | 
			
		||||
        token = access_controller.create(user, user_agent=request.user_agent)
 | 
			
		||||
        logger.debug("access token is {{ {} }}".format(token))
 | 
			
		||||
        logger.info("User {{ {} }} success login.".format(userid))
 | 
			
		||||
    Login in User and create an AccessToken for the User.
 | 
			
		||||
    Requires POST data {'userid': string, 'password': string}
 | 
			
		||||
    Returns:
 | 
			
		||||
        A JSON-File with user information and created token or errors
 | 
			
		||||
    """
 | 
			
		||||
    logger.debug("Start log in.")
 | 
			
		||||
    data = request.get_json()
 | 
			
		||||
    try:
 | 
			
		||||
        userid = data["userid"]
 | 
			
		||||
        password = data["password"]
 | 
			
		||||
    except KeyError:
 | 
			
		||||
        raise BadRequest("Missing parameter(s)")
 | 
			
		||||
 | 
			
		||||
        # Lets cleanup the DB
 | 
			
		||||
        access_controller.clear_expired()
 | 
			
		||||
        return jsonify({"user": user, "token": token, "permissions": user.get_permissions()})
 | 
			
		||||
    logger.debug("search user {{ {} }} in database".format(userid))
 | 
			
		||||
    user = userController.login_user(userid, password)
 | 
			
		||||
    if not user:
 | 
			
		||||
        raise Unauthorized
 | 
			
		||||
    logger.debug("user is {{ {} }}".format(user))
 | 
			
		||||
    token = access_controller.create(user, user_agent=request.user_agent)
 | 
			
		||||
    logger.debug("access token is {{ {} }}".format(token))
 | 
			
		||||
    logger.info("User {{ {} }} success login.".format(userid))
 | 
			
		||||
 | 
			
		||||
    @auth_bp.route("/auth", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def _get_tokens(access_token, **kwargs):
 | 
			
		||||
        tokens = access_controller.get_users_tokens(access_token.user)
 | 
			
		||||
        return jsonify(tokens)
 | 
			
		||||
    # Lets cleanup the DB
 | 
			
		||||
    access_controller.clear_expired()
 | 
			
		||||
    return jsonify({"user": user, "token": token, "permissions": user.get_permissions()})
 | 
			
		||||
 | 
			
		||||
    @auth_bp.route("/auth/<token>", methods=["DELETE"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def _delete_token(token, access_token, **kwargs):
 | 
			
		||||
        logger.debug("Try to delete access token {{ {} }}".format(token))
 | 
			
		||||
        token = access_controller.get_token(token, access_token.user)
 | 
			
		||||
        if not token:
 | 
			
		||||
            logger.debug("Token not found in database!")
 | 
			
		||||
            # Return 403 error, so that users can not bruteforce tokens
 | 
			
		||||
            # Valid tokens from other users and invalid tokens now are looking the same
 | 
			
		||||
            raise Forbidden
 | 
			
		||||
        access_controller.delete_token(token)
 | 
			
		||||
        access_controller.clear_expired()
 | 
			
		||||
 | 
			
		||||
@auth_bp.route("/auth", methods=["GET"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def _get_tokens(access_token, **kwargs):
 | 
			
		||||
    tokens = access_controller.get_users_tokens(access_token.user)
 | 
			
		||||
    a = messageController.Message(access_token.user, "Go", "Bar")
 | 
			
		||||
    messageController.send_message(a)
 | 
			
		||||
    return jsonify(tokens)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@login_required()
 | 
			
		||||
@auth_bp.route("/auth/<token>", methods=["DELETE"])
 | 
			
		||||
def _delete_token(token, access_token, **kwargs):
 | 
			
		||||
    logger.debug("Try to delete access token {{ {} }}".format(token))
 | 
			
		||||
    token = access_controller.get_token(token, access_token.user)
 | 
			
		||||
    if not token:
 | 
			
		||||
        logger.debug("Token not found in database!")
 | 
			
		||||
        # Return 403 error, so that users can not bruteforce tokens
 | 
			
		||||
        # Valid tokens from other users and invalid tokens now are looking the same
 | 
			
		||||
        raise Forbidden
 | 
			
		||||
    access_controller.delete_token(token)
 | 
			
		||||
    access_controller.clear_expired()
 | 
			
		||||
    return jsonify({"ok": "ok"})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@login_required()
 | 
			
		||||
@auth_bp.route("/auth/<token>", methods=["GET"])
 | 
			
		||||
def _get_token(token, access_token, **kwargs):
 | 
			
		||||
    logger.debug("get token {{ {} }}".format(token))
 | 
			
		||||
    token = access_controller.get_token(token, access_token.user)
 | 
			
		||||
    if not token:
 | 
			
		||||
        # Return 403 error, so that users can not bruteforce tokens
 | 
			
		||||
        # Valid tokens from other users and invalid tokens now are looking the same
 | 
			
		||||
        raise Forbidden
 | 
			
		||||
    return jsonify(token)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@login_required()
 | 
			
		||||
@auth_bp.route("/auth/<token>", methods=["PUT"])
 | 
			
		||||
def _set_lifetime(token, access_token, **kwargs):
 | 
			
		||||
    token = access_controller.get_token(token, access_token.user)
 | 
			
		||||
    if not token:
 | 
			
		||||
        # Return 403 error, so that users can not bruteforce tokens
 | 
			
		||||
        # Valid tokens from other users and invalid tokens now are looking the same
 | 
			
		||||
        raise Forbidden
 | 
			
		||||
    try:
 | 
			
		||||
        lifetime = request.get_json()["value"]
 | 
			
		||||
        logger.debug("set lifetime {{ {} }} to access token {{ {} }}".format(lifetime, token))
 | 
			
		||||
        access_controller.set_lifetime(token, lifetime)
 | 
			
		||||
        return jsonify({"ok": "ok"})
 | 
			
		||||
 | 
			
		||||
    @auth_bp.route("/auth/<token>", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def _get_token(token, access_token, **kwargs):
 | 
			
		||||
        logger.debug("get token {{ {} }}".format(token))
 | 
			
		||||
        token = access_controller.get_token(token, access_token.user)
 | 
			
		||||
        if not token:
 | 
			
		||||
            # Return 403 error, so that users can not bruteforce tokens
 | 
			
		||||
            # Valid tokens from other users and invalid tokens now are looking the same
 | 
			
		||||
            raise Forbidden
 | 
			
		||||
        return jsonify(token)
 | 
			
		||||
 | 
			
		||||
    @auth_bp.route("/auth/<token>", methods=["PUT"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def _set_lifetime(token, access_token, **kwargs):
 | 
			
		||||
        token = access_controller.get_token(token, access_token.user)
 | 
			
		||||
        if not token:
 | 
			
		||||
            # Return 403 error, so that users can not bruteforce tokens
 | 
			
		||||
            # Valid tokens from other users and invalid tokens now are looking the same
 | 
			
		||||
            raise Forbidden
 | 
			
		||||
        try:
 | 
			
		||||
            lifetime = request.get_json()["value"]
 | 
			
		||||
            logger.debug("set lifetime {{ {} }} to access token {{ {} }}".format(lifetime, token))
 | 
			
		||||
            access_controller.set_lifetime(token, lifetime)
 | 
			
		||||
            return jsonify({"ok": "ok"})
 | 
			
		||||
        except (KeyError, TypeError):
 | 
			
		||||
            raise BadRequest
 | 
			
		||||
    except (KeyError, TypeError):
 | 
			
		||||
        raise BadRequest
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
import smtplib
 | 
			
		||||
from email.mime.multipart import MIMEMultipart
 | 
			
		||||
from email.mime.text import MIMEText
 | 
			
		||||
 | 
			
		||||
from flaschengeist import logger
 | 
			
		||||
from flaschengeist.system.models.user import User
 | 
			
		||||
from flaschengeist.system.controller import userController
 | 
			
		||||
from flaschengeist.system.controller.messageController import Message
 | 
			
		||||
| 
						 | 
				
			
			@ -18,9 +20,15 @@ class MailMessagePlugin(Plugin):
 | 
			
		|||
        self.crypt = config["CRYPT"]
 | 
			
		||||
        self.mail = config["MAIL"]
 | 
			
		||||
 | 
			
		||||
    @send_message_hook
 | 
			
		||||
        @send_message_hook
 | 
			
		||||
        def dummy_send(msg):
 | 
			
		||||
            self.send_mail(msg)
 | 
			
		||||
 | 
			
		||||
    def send_mail(self, msg: Message):
 | 
			
		||||
        if isinstance(msg.receiver, User):
 | 
			
		||||
            if not msg.receiver.mail:
 | 
			
		||||
                logger.warn("Could not send Mail, mail missing: {}".format(msg.receiver))
 | 
			
		||||
                return
 | 
			
		||||
            recipients = [msg.receiver.mail]
 | 
			
		||||
        else:
 | 
			
		||||
            recipients = userController.get_user_by_role(msg.receiver)
 | 
			
		||||
| 
						 | 
				
			
			@ -29,15 +37,17 @@ class MailMessagePlugin(Plugin):
 | 
			
		|||
        mail["From"] = self.mail
 | 
			
		||||
        mail["To"] = ", ".join(recipients)
 | 
			
		||||
        mail["Subject"] = msg.subject
 | 
			
		||||
        msg.attach(msg.message)
 | 
			
		||||
        if not self.smtp:
 | 
			
		||||
        mail.attach(MIMEText(msg.message))
 | 
			
		||||
        if not hasattr(self, "smtp"):
 | 
			
		||||
            self.__connect()
 | 
			
		||||
        self.smtp.sendmail(self.mail, recipients, msg.as_string())
 | 
			
		||||
        self.smtp.sendmail(self.mail, recipients, mail.as_string())
 | 
			
		||||
 | 
			
		||||
    def __connect(self):
 | 
			
		||||
        if self.crypt == "SSL":
 | 
			
		||||
            self.smtp = smtplib.SMTP_SSL(self.server, self.port)
 | 
			
		||||
        if self.crypt == "STARTTLS":
 | 
			
		||||
            self.smtp = smtplib.SMTP(self.smtpServer, self.port)
 | 
			
		||||
        elif self.crypt == "STARTTLS":
 | 
			
		||||
            self.smtp = smtplib.SMTP(self.server, self.port)
 | 
			
		||||
            self.smtp.starttls()
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError("Invalid CRYPT given")
 | 
			
		||||
        self.smtp.login(self.user, self.password)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,67 +12,73 @@ class RolesPlugin(Plugin):
 | 
			
		|||
    def __init__(self, config):
 | 
			
		||||
        super().__init__(config, roles_bp)
 | 
			
		||||
 | 
			
		||||
    ######################################################
 | 
			
		||||
    #                       Routes                       #
 | 
			
		||||
    #                                                    #
 | 
			
		||||
    # /roles              POST: register new             #
 | 
			
		||||
    #                      GET: get all roles            #
 | 
			
		||||
    # /roles/permissions   GET: get all permissions      #
 | 
			
		||||
    # /roles/<rid>         GET: get role with rid        #
 | 
			
		||||
    #                      PUT: modify role / permission #
 | 
			
		||||
    #                   DELETE: remove role              #
 | 
			
		||||
    ######################################################
 | 
			
		||||
######################################################
 | 
			
		||||
#                       Routes                       #
 | 
			
		||||
#                                                    #
 | 
			
		||||
# /roles              POST: register new             #
 | 
			
		||||
#                      GET: get all roles            #
 | 
			
		||||
# /roles/permissions   GET: get all permissions      #
 | 
			
		||||
# /roles/<rid>         GET: get role with rid        #
 | 
			
		||||
#                      PUT: modify role / permission #
 | 
			
		||||
#                   DELETE: remove role              #
 | 
			
		||||
######################################################
 | 
			
		||||
 | 
			
		||||
    @roles_bp.route("/roles", methods=["POST"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def add_role(self):
 | 
			
		||||
        data = request.get_json()
 | 
			
		||||
        if not data or "name" not in data:
 | 
			
		||||
            raise BadRequest
 | 
			
		||||
        if "permissions" in data:
 | 
			
		||||
            permissions = data["permissions"]
 | 
			
		||||
        role = roleController.create_role(data["name"], permissions)
 | 
			
		||||
        return jsonify({"ok": "ok", "id": role.id})
 | 
			
		||||
 | 
			
		||||
    @roles_bp.route("/roles", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def list_roles(self, **kwargs):
 | 
			
		||||
        roles = roleController.get_roles()
 | 
			
		||||
        return jsonify(roles)
 | 
			
		||||
@roles_bp.route("/roles", methods=["POST"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def add_role(self):
 | 
			
		||||
    data = request.get_json()
 | 
			
		||||
    if not data or "name" not in data:
 | 
			
		||||
        raise BadRequest
 | 
			
		||||
    if "permissions" in data:
 | 
			
		||||
        permissions = data["permissions"]
 | 
			
		||||
    role = roleController.create_role(data["name"], permissions)
 | 
			
		||||
    return jsonify({"ok": "ok", "id": role.id})
 | 
			
		||||
 | 
			
		||||
    @roles_bp.route("/roles/permissions", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def list_permissions(self, **kwargs):
 | 
			
		||||
        permissions = roleController.get_permissions()
 | 
			
		||||
        return jsonify(permissions)
 | 
			
		||||
 | 
			
		||||
    @roles_bp.route("/roles/<rid>", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __get_role(self, rid, **kwargs):
 | 
			
		||||
        role = roleController.get_role(rid)
 | 
			
		||||
        if role:
 | 
			
		||||
            return jsonify({"id": role.id, "name": role, "permissions": role.permissions})
 | 
			
		||||
@roles_bp.route("/roles", methods=["GET"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def list_roles(**kwargs):
 | 
			
		||||
    roles = roleController.get_roles()
 | 
			
		||||
    return jsonify(roles)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@roles_bp.route("/roles/permissions", methods=["GET"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def list_permissions(**kwargs):
 | 
			
		||||
    permissions = roleController.get_permissions()
 | 
			
		||||
    return jsonify(permissions)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@roles_bp.route("/roles/<rid>", methods=["GET"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __get_role(rid, **kwargs):
 | 
			
		||||
    role = roleController.get_role(rid)
 | 
			
		||||
    if role:
 | 
			
		||||
        return jsonify({"id": role.id, "name": role, "permissions": role.permissions})
 | 
			
		||||
    raise NotFound
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@roles_bp.route("/roles/<rid>", methods=["PUT"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __edit_role(rid, **kwargs):
 | 
			
		||||
    role = roleController.get_role(rid)
 | 
			
		||||
    if not role:
 | 
			
		||||
        raise NotFound
 | 
			
		||||
 | 
			
		||||
    @roles_bp.route("/roles/<rid>", methods=["PUT"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __edit_role(self, rid, **kwargs):
 | 
			
		||||
        role = roleController.get_role(rid)
 | 
			
		||||
        if not role:
 | 
			
		||||
            raise NotFound
 | 
			
		||||
    data = request.get_json()
 | 
			
		||||
    if "name" in data:
 | 
			
		||||
        role.name = data["name"]
 | 
			
		||||
    if "permissions" in data:
 | 
			
		||||
        roleController.set_permissions(role, data["permissions"])
 | 
			
		||||
    roleController.update_role(role)
 | 
			
		||||
    return jsonify({"ok": "ok"})
 | 
			
		||||
 | 
			
		||||
        data = request.get_json()
 | 
			
		||||
        if "name" in data:
 | 
			
		||||
            role.name = data["name"]
 | 
			
		||||
        if "permissions" in data:
 | 
			
		||||
            roleController.set_permissions(role, data["permissions"])
 | 
			
		||||
        roleController.update_role(role)
 | 
			
		||||
        return jsonify({"ok": "ok"})
 | 
			
		||||
 | 
			
		||||
    @roles_bp.route("/roles/<rid>", methods=["DELETE"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __delete_role(self, rid, **kwargs):
 | 
			
		||||
        if not roleController.delete_role(rid):
 | 
			
		||||
            raise NotFound
 | 
			
		||||
@roles_bp.route("/roles/<rid>", methods=["DELETE"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __delete_role(rid, **kwargs):
 | 
			
		||||
    if not roleController.delete_role(rid):
 | 
			
		||||
        raise NotFound
 | 
			
		||||
 | 
			
		||||
        return jsonify({"ok": "ok"})
 | 
			
		||||
    return jsonify({"ok": "ok"})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,171 +16,184 @@ class SchedulePlugin(Plugin):
 | 
			
		|||
    def __init__(self, config):
 | 
			
		||||
        super().__init__(blueprint=schedule_bp)
 | 
			
		||||
 | 
			
		||||
    ####################################################################################
 | 
			
		||||
    #                                    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                       #
 | 
			
		||||
    ####################################################################################
 | 
			
		||||
####################################################################################
 | 
			
		||||
#                                    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_event(self, 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(self, 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 month are returned
 | 
			
		||||
@schedule_bp.route("/events/<int:id>", methods=["GET"])
 | 
			
		||||
@login_required()  # roles=['schedule_read'])
 | 
			
		||||
def __get_event(self, id, **kwargs):
 | 
			
		||||
    event = eventController.get_event(id)
 | 
			
		||||
    if not event:
 | 
			
		||||
        raise NotFound
 | 
			
		||||
    return jsonify(event)
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
            year (int, optional): year to query, defaults to current year
 | 
			
		||||
            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:
 | 
			
		||||
            JSON list containing events found
 | 
			
		||||
        Raises:
 | 
			
		||||
            BadRequest: If date is invalid
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            begin = datetime(year=year, month=month, day=1)
 | 
			
		||||
            if day:
 | 
			
		||||
                begin += timedelta(days=day - 1)
 | 
			
		||||
                end = begin + timedelta(days=1)
 | 
			
		||||
 | 
			
		||||
@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, **kwargs):
 | 
			
		||||
    """Get Event objects for specified date (or month or year),
 | 
			
		||||
     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), defaults to current month
 | 
			
		||||
        day (int, optional): day to query events for (if set)
 | 
			
		||||
        **kwargs: contains at least access_token (see flaschengeist.decorator)
 | 
			
		||||
    Returns:
 | 
			
		||||
        JSON list containing events found
 | 
			
		||||
    Raises:
 | 
			
		||||
        BadRequest: If date is invalid
 | 
			
		||||
    """
 | 
			
		||||
    try:
 | 
			
		||||
        begin = datetime(year=year, month=month, day=1)
 | 
			
		||||
        if day:
 | 
			
		||||
            begin += timedelta(days=day - 1)
 | 
			
		||||
            end = begin + timedelta(days=1)
 | 
			
		||||
        else:
 | 
			
		||||
            if month == 12:
 | 
			
		||||
                end = datetime(year=year + 1, month=1, day=1)
 | 
			
		||||
            else:
 | 
			
		||||
                if month == 12:
 | 
			
		||||
                    end = datetime(year=year + 1, month=1, day=1)
 | 
			
		||||
                else:
 | 
			
		||||
                    end = datetime(year=year, month=month + 1, day=1)
 | 
			
		||||
                end = datetime(year=year, month=month + 1, day=1)
 | 
			
		||||
 | 
			
		||||
            events = eventController.get_events(begin, end)
 | 
			
		||||
            return jsonify(events)
 | 
			
		||||
        except ValueError:
 | 
			
		||||
            raise BadRequest("Invalid date given")
 | 
			
		||||
        events = eventController.get_events(begin, end)
 | 
			
		||||
        return jsonify(events)
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        raise BadRequest("Invalid date given")
 | 
			
		||||
 | 
			
		||||
    @schedule_bp.route("/eventKinds", methods=["POST"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __new_event_kind(self, **kwargs):
 | 
			
		||||
        data = request.get_json()
 | 
			
		||||
        if "name" not in data:
 | 
			
		||||
            raise BadRequest
 | 
			
		||||
        kind = eventController.create_event_kind(data["name"])
 | 
			
		||||
        return jsonify({"ok": "ok", "id": kind.id})
 | 
			
		||||
 | 
			
		||||
    @schedule_bp.route("/slotKinds", methods=["POST"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __new_slot_kind(self, **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("/eventKinds", methods=["POST"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __new_event_kind(**kwargs):
 | 
			
		||||
    data = request.get_json()
 | 
			
		||||
    if "name" not in data:
 | 
			
		||||
        raise BadRequest
 | 
			
		||||
    kind = eventController.create_event_kind(data["name"])
 | 
			
		||||
    return jsonify({"ok": "ok", "id": kind.id})
 | 
			
		||||
 | 
			
		||||
    @schedule_bp.route("/events", methods=["POST"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __new_event(self, **kwargs):
 | 
			
		||||
        data = request.get_json()
 | 
			
		||||
        event = eventController.create_event(
 | 
			
		||||
            begin=parser.isoparse(data["begin"]),
 | 
			
		||||
            end=parser.isoparse(data["end"]),
 | 
			
		||||
            description=data["description"],
 | 
			
		||||
            kind=EventKind.query.get(data["kind"]),
 | 
			
		||||
        )
 | 
			
		||||
        return jsonify({"ok": "ok", "id": event.id})
 | 
			
		||||
 | 
			
		||||
    @schedule_bp.route("/events/<int:id>", methods=["DELETE"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __delete_event(self, id, **kwargs):
 | 
			
		||||
        if not eventController.delete_event(id):
 | 
			
		||||
            raise NotFound
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        return jsonify({"ok": "ok"})
 | 
			
		||||
@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("/eventKinds/<int:id>", methods=["PUT"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __edit_event_kind(self, 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(self, event_id, **kwargs):
 | 
			
		||||
        event = eventController.get_event(event_id)
 | 
			
		||||
        if not event:
 | 
			
		||||
            raise NotFound
 | 
			
		||||
        return jsonify({event.slots})
 | 
			
		||||
@schedule_bp.route("/events", methods=["POST"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __new_event(**kwargs):
 | 
			
		||||
    data = request.get_json()
 | 
			
		||||
    event = eventController.create_event(
 | 
			
		||||
        begin=parser.isoparse(data["begin"]),
 | 
			
		||||
        end=parser.isoparse(data["end"]),
 | 
			
		||||
        description=data["description"],
 | 
			
		||||
        kind=EventKind.query.get(data["kind"]),
 | 
			
		||||
    )
 | 
			
		||||
    return jsonify({"ok": "ok", "id": event.id})
 | 
			
		||||
 | 
			
		||||
    @schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __get_slot(self, event_id, slot_id, **kwargs):
 | 
			
		||||
        slot = eventController.get_event_slot(slot_id, event_id)
 | 
			
		||||
        if slot:
 | 
			
		||||
            return jsonify(slot)
 | 
			
		||||
 | 
			
		||||
@schedule_bp.route("/events/<int:event_id>", methods=["DELETE"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __delete_event(event_id, **kwargs):
 | 
			
		||||
    if not eventController.delete_event(event_id):
 | 
			
		||||
        raise NotFound
 | 
			
		||||
    db.session.commit()
 | 
			
		||||
    return jsonify({"ok": "ok"})
 | 
			
		||||
 | 
			
		||||
    @schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["DELETE"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __delete_slot(self, event_id, slot_id, **kwargs):
 | 
			
		||||
        if eventController.delete_event_slot(slot_id, event_id):
 | 
			
		||||
            return jsonify({"ok": "ok"})
 | 
			
		||||
 | 
			
		||||
@schedule_bp.route("/eventKinds/<int:event_id>", methods=["PUT"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __edit_event_kind(event_id, **kwargs):
 | 
			
		||||
    data = request.get_json()
 | 
			
		||||
    if not data or "name" not in data:
 | 
			
		||||
        raise BadRequest
 | 
			
		||||
    eventController.rename_event_kind(event_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=["PUT"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __update_slot(self, event_id, slot_id, **kwargs):
 | 
			
		||||
        data = request.get_json()
 | 
			
		||||
        if not data:
 | 
			
		||||
            raise BadRequest
 | 
			
		||||
 | 
			
		||||
@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"]:
 | 
			
		||||
            eventController.add_job(job.kind, job.user)
 | 
			
		||||
        if eventController.delete_event_slot(slot_id, event_id):
 | 
			
		||||
            return jsonify({"ok": "ok"})
 | 
			
		||||
        raise NotFound
 | 
			
		||||
            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"})
 | 
			
		||||
 | 
			
		||||
    @schedule_bp.route("/events/<int:event_id>/slots", methods=["POST"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __add_slot(self, 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(self):
 | 
			
		||||
        ...
 | 
			
		||||
def __edit_event():
 | 
			
		||||
    ...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,45 +24,49 @@ class UsersPlugin(Plugin):
 | 
			
		|||
    #               DELETE: remove user             #
 | 
			
		||||
    #################################################
 | 
			
		||||
 | 
			
		||||
    @users_bp.route("/users", methods=["POST"])
 | 
			
		||||
    def __registration(self):
 | 
			
		||||
        logger.debug("Register new User...")
 | 
			
		||||
        return jsonify({"ok": "ok... well not implemented"})
 | 
			
		||||
 | 
			
		||||
    @users_bp.route("/users", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __list_users(self, **kwargs):
 | 
			
		||||
        logger.debug("Retrieve list of all users")
 | 
			
		||||
        users = userController.get_users()
 | 
			
		||||
        return jsonify(users)
 | 
			
		||||
@users_bp.route("/users", methods=["POST"])
 | 
			
		||||
def __registration(self):
 | 
			
		||||
    logger.debug("Register new User...")
 | 
			
		||||
    return jsonify({"ok": "ok... well not implemented"})
 | 
			
		||||
 | 
			
		||||
    @users_bp.route("/users/<uid>", methods=["GET"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __get_user(self, uid, **kwargs):
 | 
			
		||||
        logger.debug("Get information of user {{ {} }}".format(uid))
 | 
			
		||||
        user = userController.get_user(uid)
 | 
			
		||||
        if user:
 | 
			
		||||
            return jsonify(user)
 | 
			
		||||
 | 
			
		||||
@users_bp.route("/users", methods=["GET"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __list_users(**kwargs):
 | 
			
		||||
    logger.debug("Retrieve list of all users")
 | 
			
		||||
    users = userController.get_users()
 | 
			
		||||
    return jsonify(users)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@users_bp.route("/users/<uid>", methods=["GET"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __get_user(uid, **kwargs):
 | 
			
		||||
    logger.debug("Get information of user {{ {} }}".format(uid))
 | 
			
		||||
    user = userController.get_user(uid)
 | 
			
		||||
    if user:
 | 
			
		||||
        return jsonify(user)
 | 
			
		||||
    raise NotFound
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@users_bp.route("/users/<uid>", methods=["PUT"])
 | 
			
		||||
@login_required()
 | 
			
		||||
def __edit_user(uid, **kwargs):
 | 
			
		||||
    logger.debug("Modify information of user {{ {} }}".format(uid))
 | 
			
		||||
    user = userController.get_user(uid)
 | 
			
		||||
    if not user:
 | 
			
		||||
        raise NotFound
 | 
			
		||||
 | 
			
		||||
    @users_bp.route("/users/<uid>", methods=["PUT"])
 | 
			
		||||
    @login_required()
 | 
			
		||||
    def __edit_user(self, uid, **kwargs):
 | 
			
		||||
        logger.debug("Modify information of user {{ {} }}".format(uid))
 | 
			
		||||
        user = userController.get_user(uid)
 | 
			
		||||
        if not user:
 | 
			
		||||
            raise NotFound
 | 
			
		||||
    if uid != kwargs["access_token"].user.uid and user.has_permissions(permissions["EDIT_USER"]):
 | 
			
		||||
        return Forbidden
 | 
			
		||||
 | 
			
		||||
        if uid != kwargs["access_token"].user.uid and user.has_permissions(permissions["EDIT_USER"]):
 | 
			
		||||
            return Forbidden
 | 
			
		||||
 | 
			
		||||
        data = request.get_json()
 | 
			
		||||
        if "password" not in data:
 | 
			
		||||
            raise BadRequest("Password is missing")
 | 
			
		||||
        for key in ["firstname", "lastname", "display_name", "mail"]:
 | 
			
		||||
            if key in data:
 | 
			
		||||
                setattr(user, key, data[key])
 | 
			
		||||
        new_password = data["new_password"] if "new_password" in data else None
 | 
			
		||||
        userController.modify_user(user, data["password"], new_password)
 | 
			
		||||
        userController.update_user(user)
 | 
			
		||||
        return jsonify({"ok": "ok"})
 | 
			
		||||
    data = request.get_json()
 | 
			
		||||
    if "password" not in data:
 | 
			
		||||
        raise BadRequest("Password is missing")
 | 
			
		||||
    for key in ["firstname", "lastname", "display_name", "mail"]:
 | 
			
		||||
        if key in data:
 | 
			
		||||
            setattr(user, key, data[key])
 | 
			
		||||
    new_password = data["new_password"] if "new_password" in data else None
 | 
			
		||||
    userController.modify_user(user, data["password"], new_password)
 | 
			
		||||
    userController.update_user(user)
 | 
			
		||||
    return jsonify({"ok": "ok"})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,22 @@ or with debug messages:
 | 
			
		|||
    run_flaschengeist --debug
 | 
			
		||||
 | 
			
		||||
## Development
 | 
			
		||||
### Code Style
 | 
			
		||||
We enforce you to use PEP 8 code style with a line length of 120 as used by Black.
 | 
			
		||||
See also [Black Code Style](https://github.com/psf/black/blob/master/docs/the_black_code_style.md).
 | 
			
		||||
 | 
			
		||||
#### Code formatting
 | 
			
		||||
We use [Black](https://github.com/psf/black) as the code formatter.
 | 
			
		||||
 | 
			
		||||
Installation:
 | 
			
		||||
 | 
			
		||||
    pip install black
 | 
			
		||||
Usage:
 | 
			
		||||
 | 
			
		||||
    black -l 120 DIRECTORY_OR_FILE
 | 
			
		||||
 | 
			
		||||
### Misc
 | 
			
		||||
#### Git blame
 | 
			
		||||
When using `git blame` use this to ignore the code formatting commits:
 | 
			
		||||
 | 
			
		||||
    $ git blame FILE.py --ignore-revs-file .git-blame-ignore-revs
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
from flaschengeist import logger
 | 
			
		||||
from flaschengeist.system.hook import Hook
 | 
			
		||||
from flaschengeist.system.models.user import User, Role
 | 
			
		||||
from pyhooks import Hook
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Message:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
_hook_dict = {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Hook(object):
 | 
			
		||||
    def __init__(self, function):
 | 
			
		||||
        self.function = function
 | 
			
		||||
 | 
			
		||||
    def __call__(self, *args, **kwargs):
 | 
			
		||||
        if self.function.__name__ in _hook_dict:
 | 
			
		||||
            _hook_dict[self.function.__name__](*args, **kwargs)
 | 
			
		||||
        self.function(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HookCall(object):
 | 
			
		||||
    def __init__(self, name):
 | 
			
		||||
        self.name = name
 | 
			
		||||
 | 
			
		||||
    def __call__(self, function):
 | 
			
		||||
        _hook_dict[self.name] = function
 | 
			
		||||
        return function
 | 
			
		||||
		Loading…
	
		Reference in New Issue