Files
2022-12-01 11:42:39 +01:00

148 lines
5.6 KiB
Python

# -*- encoding: utf-8 -*-
# @author : vincent.benoit@benserv.fr
# @brief : Scheduler routes
#########################################################
# Importation de modules externes #
import sys, re, os
import logging as log
from datetime import datetime, timezone
from flask import Flask, Blueprint, request, abort, jsonify, current_app
from flask_api import status
from flask_jwt_extended import create_access_token
from flask_jwt_extended import get_jwt
from flask_jwt_extended import set_access_cookies
from flask_jwt_extended import unset_jwt_cookies
from flask_jwt_extended import get_jwt_identity
from flask_jwt_extended import jwt_required
import json
import shutil
import hashlib
from werkzeug.exceptions import HTTPException
from ConfBack.manager import Sock
#########################################################
# Class et Methods #
schedule = Blueprint('schedule', __name__, url_prefix='/api/configurateur')
@schedule.errorhandler(HTTPException)
def handle_exception(e):
''' return JSON instead of HTML for HTTP errors '''
response = e.get_response()
# replace the body with JSON
response.data = json.dumps({
'code': e.code,
'name': e.name,
'description': e.description,
})
response.content_type = "application/json"
return response
@schedule.after_request
def refresh_expiring_tokens(response):
''' Using an 'after_request' callback, we refresh any token that is within
30 minutes of expiring.'''
try:
exp_timestamp = get_jwt()['exp']
now = datetime.now(timezone.utc)
target_timestamp = datetime.timestamp(now + current_app.config['DELTA'])
if target_timestamp > exp_timestamp:
current_app.logger.warning("On doit recréer un token JWT ....")
access_token = create_access_token(identity=get_jwt_identity())
# refresh token in storage place
if os.path.exists(os.path.join("/tmp", current_app.config['PROJECT'])):
with open(os.path.join("/tmp", current_app.config['PROJECT'], get_jwt_identity()['id']), 'w') as f:
f.write(access_token)
# Modifiy a Flask Response to set a cookie containing the access JWT.
set_access_cookies(response, access_token)
return response
except (RuntimeError, KeyError):
return response
@schedule.route('/scheduler', methods=['GET'])
@jwt_required()
def retreive_scheduler():
''' Récupération des horaires
'''
current_app.logger.info("Récupération des horaires")
current_user = get_jwt_identity()
# load data from JSON database
try:
with open(current_app.config['DB_PATH'], 'r') as f:
data = json.load(f)
content = {'mode':'', 'days':[]}
if 'OPERATION' in data:
content['mode'] = data['OPERATION']
else:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="mode d'opération manquant en base de données")
sched = []
if 'HORAIRES' in data:
for day in data['HORAIRES']:
h = []
for hour in data['HORAIRES'][day]:
h.append(hour)
sched.append({'name': day, 'horaires': h})
content['days'] = sched
else:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="horaire manquant en base de données")
except FileNotFoundError as e:
current_app.logger.error("Fichier ({}) manquant".format(current_app.config['DB_PATH']))
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Fichier manquant")
return content, status.HTTP_200_OK
@schedule.route('/update_schedulers', methods=['POST'])
@jwt_required()
def update_scheduler():
''' Mise à jour des horaires
'''
current_app.logger.info("Mise à jour des horaires")
current_user = get_jwt_identity()
# recuperation des attributs JSON de la requete
data_req = request.get_json()
# load data from JSON database
try:
with open(current_app.config['DB_PATH'], 'r') as f:
data_db = json.load(f)
except FileNotFoundError as e:
current_app.logger.error("Fichier ({}) manquant".format(current_app.config['DB_PATH']))
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Fichier manquant")
if 'mode' not in data_req or 'days' not in data_req:
current_app.logger.error("paramètre(s) manquant(s) dans la requete")
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Paramètre(s) manquant(s)")
data_db['OPERATION'] = data_req['mode']
for day in data_db['HORAIRES']:
for d in data_req['days']:
if 'name' in d and d['name'] == day:
data_db['HORAIRES'][day] = d['horaires']
elif 'name' not in d:
abort(status.HTTP_406_NOT_ACCEPTABLE, description="erreur des données de la requete")
with open(current_app.config['DB_PATH'], 'w') as f:
json.dump(data_db, f)
conn = Sock(addr=current_app.config['UNIX_ADDR'], logger=current_app.logger)
if not conn.connect():
current_app.logger.error("impossible de se connecter au serveur")
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Impossible de se connecter au serveur")
# send order to KineIntercom process
if not conn.send(b"RELOAD_HOURS\n"):
conn.disconnect()
current_app.logger.error("impossible de communiquer avec le serveur")
abort(status.HTTP_406_NOT_ACCEPTABLE, description="Impossible de communiquer avec le serveur")
conn.disconnect()
content = {'message':'maj parameters successful!'}
return content, status.HTTP_200_OK