from flask import Flask, redirect, render_template, send_from_directory, session import os from os.path import join from . import db, config, scanner, routes, utils app = Flask(__name__) # Manage secret key try: from . import secret app.config['SECRET_KEY'] = secret.SECRET_KEY except ImportError: # Secret key file does not exist, create it secret = os.urandom(50).hex() with open('secret.py', 'w') as f: f.write(f'SECRET_KEY = "{secret}"') app.config['SECRET_KEY'] = secret # Middlewares to help us deal with stuff @app.context_processor def inject(): """ Returns a dictionnary with the uuids of leds and the calibration state. """ conn = db.get() return { 'calibration': utils.get_calibration(conn), 'leds': config.LEDS_UUIDS, 'CalibrationState': db.CalibrationState, } @app.before_request def manage_auto_use_last_calibration(): """ Automatically use the last calibration if the config is set accordingly. """ if config.AUTO_USE_LAST_CALIBRATION and 'calibration_id' not in session: conn = db.get() last = db.Calibration.get_last(conn) if last is not None: session['calibration_id'] = last.id app.register_blueprint(routes.blueprint) @app.route('/scan/') def scan(id: int): conn = db.get() calibration_id = session.get('calibration_id', None) object = db.Object.get_from_id(id, conn) if calibration_id is None: raise RuntimeError("Impossible de faire l'acquisition sans étalonnage") return render_template('scan.html', object=object, calibrated=True) @app.route('/scan-acquisition/') def scan_existing(id: int): conn = db.get() calibrated = session.get('calibration_id', None) is not None acquisition = db.Acquisition.get_from_id(id, conn) object = acquisition.object(conn) return render_template('scan.html', object=object, acquisition=acquisition, calibrated=calibrated) @app.route("/api/scan-for-object/") def scan_object(object_id: int): conn = db.get() calibration_id = session.get('calibration_id', None) if calibration_id is None: raise RuntimeError("Impossible de faire l'acquisition sans étalonnage") object = db.Object.get_from_id(object_id, conn) if object is None: raise RuntimeError(f"Aucun objet d'id {object_id}") with conn: acquisition = object.add_acquisition(calibration_id, conn) def generate(): yield str(acquisition.id) length = len(config.LEDS_UUIDS) for index, led_uuid in enumerate(scanner.scan(join(config.OBJECT_DIR, str(object.id), str(acquisition.id)))): yield f"{led_uuid},{(index+1)/length}\n" return app.response_class(generate(), mimetype='text/plain') @app.route("/api/scan-for-acquisition/") def scan_acquisition(acquisition_id: int): conn = db.get() calibration_id = session.get('calibration_id', None) if calibration_id is None: raise RuntimeError("Impossible de faire l'acquisition sans étalonnage") acquisition = db.Acquisition.get_from_id(acquisition_id, conn) if acquisition is None: raise RuntimeError(f"Aucun acquisition d'id {acquisition_id}") object = acquisition.object(conn) def generate(): length = len(config.LEDS_UUIDS) for index, led_uuid in enumerate(scanner.scan(join(config.OBJECT_DIR, str(object.id), str(acquisition.id)))): yield f"{led_uuid},{(index+1)/length}\n" return app.response_class(generate(), mimetype='text/plain') @app.route("/validate-acquisition/") def validate_acquisition(acquisition_id: int): conn = db.get() acquisition = db.Acquisition.get_from_id(acquisition_id, conn) if acquisition is None: raise f"Aucune acquisition d'id {acquisition_id}" object = acquisition.object(conn) acquisition.validated = True with conn: acquisition.save(conn) return redirect(f'/object/{object.id}') @app.route("/delete-acquisition/") def delete_acquisition(acquisition_id: int): conn = db.get() with conn: acqusition = db.Acquisition.delete_from_id(acquisition_id, conn) return redirect('/object/' + str(acqusition.object_id)) @app.route('/static/') def send_static(path): return send_from_directory('static', path) @app.route('/data/') def send_data(path): return send_from_directory('data', path)