diff --git a/app.py b/app.py index e02e393..a70688a 100755 --- a/app.py +++ b/app.py @@ -30,14 +30,23 @@ def create_object(): def object(id: int): conn = db.get() object = db.Object.get_from_id(id, conn) - return render_template('object.html', object=object) + calibration = object.calibration(conn) + return render_template('object.html', object=object, calibration=calibration) @app.route("/calibrate/") def calibrate(id: int): conn = db.get() object = db.Object.get_from_id(id, conn) - return render_template('calibrate.html', object=object) + if object.calibration_id is None: + with conn: + calibration = db.Calibration.create(conn) + object.calibration_id = calibration.id + object.save(conn) + else: + calibration = object.calibration(conn) + + return render_template('calibrate.html', object=object, calibration=calibration, leds=config.LEDS_UUIDS) @app.route("/api/preview/") @@ -54,22 +63,26 @@ def preview(id: int): @app.route("/api/scan-for-calibration/") def scan_calibration(id: int): conn = db.get() - db.Object.get_from_id(id, conn) + calibration = db.Calibration.get_from_id(id, conn) def generate(): length = len(config.LEDS_UUIDS) - for index, led_uuid in enumerate(scanner.scan(join(config.DATA_DIR, id, 'calibration'))): + for index, led_uuid in enumerate(scanner.scan(join(config.CALIBRATION_DIR, id))): yield f"{led_uuid},{(index+1)/length}\n" + with conn: + calibration.state = db.CalibrationState.HasData + calibration.save(conn) + return app.response_class(generate(), mimetype='text/plain') @app.route("/api/calibrate/") def run_calibration(id: int): conn = db.get() - db.Object.get_from_id(id, conn) - calibration_json = calibration.calibrate(join(config.DATA_DIR, str(id), 'calibration')) - with open(join(config.DATA_DIR, str(id), 'calibration.json'), 'w') as f: + db.Calibration.get_from_id(id, conn) + calibration_json = calibration.calibrate(join(config.CALIBRATION_DIR, str(id))) + with open(join(config.CALIBRATION_DIR, str(id), 'calibration.json'), 'w') as f: json.dump(calibration_json, f, indent=4) return 'ok' @@ -77,8 +90,8 @@ def run_calibration(id: int): @app.route("/calibration/") def calibration_page(id: int): conn = db.get() - object = db.Object.get_from_id(id, conn) - return render_template('calibration.html', object=object) + calibration = db.Calibration.get_from_id(id, conn) + return render_template('calibration.html', calibration=calibration) @app.route('/static/') diff --git a/config.py b/config.py index 0c9d396..010fdca 100644 --- a/config.py +++ b/config.py @@ -1,4 +1,7 @@ +from os.path import join + DATA_DIR = 'data' +CALIBRATION_DIR = join(DATA_DIR, 'calibration') LEDS_UUIDS = [ 'ac59350e-3787-46d2-88fa-743c1d34fe86', diff --git a/db.py b/db.py index 6b94240..92e7aaa 100755 --- a/db.py +++ b/db.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from enum import IntEnum from flask import g import os import sqlite3 @@ -13,6 +14,8 @@ def get() -> sqlite3.Connection: detect_types=sqlite3.PARSE_DECLTYPES, ) g.db.row_factory = sqlite3.Row + cur = g.db.cursor() + cur.execute('PRAGMA foreign_keys = on') return g.db @@ -43,34 +46,75 @@ if __name__ == '__main__': init(db) +class CalibrationState(IntEnum): + Empty = 0 + HasData = 1 + IsValidated = 2 + + +class Calibration: + @staticmethod + def select_args() -> str: + return 'id, state' + + def __init__(self, calibration_id: int, state: int): + self.id = calibration_id + self.state = CalibrationState(state) + + @staticmethod + def create(db: sqlite3.Connection) -> 'Calibration': + cur = db.cursor() + response = cur.execute( + 'INSERT INTO calibration(state) VALUES (?) RETURNING ' + Calibration.select_args() + ';', + [int(CalibrationState.Empty)] + ) + return Calibration.from_row(response.fetchone()) + + @staticmethod + def from_row(row: sqlite3.Row) -> 'Calibration': + return Calibration(*row) + + def save(self, db: sqlite3.Connection): + cur = db.cursor() + cur.execute( + 'UPDATE calibration SET state = ? WHERE id = ?', + [int(self.state), self.id] + ) + + @staticmethod + def get_from_id(calibration_id: int, db: sqlite3.Connection) -> Optional['Calibration']: + cur = db.cursor() + response = cur.execute( + 'SELECT ' + Calibration.select_args() + ' FROM calibration WHERE id = ?;', + [calibration_id] + ) + return Calibration.from_row(response.fetchone()) + + class Object: @staticmethod def select_args() -> str: - return 'id, name, calibrated' + return 'id, name, calibration_id' - def __init__(self, object_id: int, name: str, calibrated: int): + def __init__(self, object_id: int, name: str, calibration: int): self.id = object_id self.name = name - - # 0 means no data available - # 1 means data available but calibration not done - # 2 means calibration done - self.calibrated = calibrated + self.calibration_id = calibration @staticmethod def create(name: str, db: sqlite3.Connection) -> 'Object': cur = db.cursor() response = cur.execute( - 'INSERT INTO object(name, calibrated) VALUES (?, ?) RETURNING ' + Object.select_args() + ';', - [name, 0] + 'INSERT INTO object(name, calibration_id) VALUES (?, ?) RETURNING ' + Object.select_args() + ';', + [name, None] ) return Object.from_row(response.fetchone()) def save(self, db: sqlite3.Connection): cur = db.cursor() cur.execute( - 'UPDATE object SET name = ? WHERE id = ?', - [self.name, self.id] + 'UPDATE object SET name = ?, calibration_id = ? WHERE id = ?', + [self.name, self.calibration_id, self.id] ) @staticmethod @@ -94,3 +138,9 @@ class Object: [] ) return list(map(Object.from_row, response.fetchall())) + + def calibration(self, db: sqlite3.Connection) -> Optional[Calibration]: + if self.calibration_id is None: + return None + + return Calibration.get_from_id(self.calibration_id, db) diff --git a/schema.sql b/schema.sql index 2b8db13..e6e5d30 100644 --- a/schema.sql +++ b/schema.sql @@ -1,7 +1,14 @@ DROP TABLE IF EXISTS object; +DROP TABLE IF EXISTS calibration; + +CREATE TABLE calibration ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + state INTEGER NOT NULL +); CREATE TABLE object ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, - calibrated INT NOT NULL + calibration_id INTEGER, + CONSTRAINT fk_calibration FOREIGN KEY(calibration_id) REFERENCES calibration(id) ); diff --git a/templates/calibrate.html b/templates/calibrate.html index 2831001..f8d99ae 100644 --- a/templates/calibrate.html +++ b/templates/calibrate.html @@ -30,7 +30,7 @@ -