diff --git a/app/__init__.py b/app/__init__.py index da9369f..e896bf6 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -9,7 +9,8 @@ __all__ = ["app"] db = SQLAlchemy(app=app) # Set up migration -migration = Migrate(app=app, db=db) +migrations_dir = Path(__file__).parent / "migrations" +migration = Migrate(app=app, db=db, directory=str(migrations_dir)) # Init and upgrade with app.app_context(): diff --git a/app/aio_client/worker.py b/app/aio_client/worker.py index 79a834e..8cc252c 100644 --- a/app/aio_client/worker.py +++ b/app/aio_client/worker.py @@ -1,5 +1,5 @@ from sqlalchemy.orm import sessionmaker -from app.config import timeout as timeout_ +from config import timeout as timeout_ import aiohttp import asyncio import time diff --git a/app/flask_app/routes.py b/app/flask_app/routes.py index e8fe3db..4a29d34 100644 --- a/app/flask_app/routes.py +++ b/app/flask_app/routes.py @@ -1,7 +1,7 @@ from flask import Blueprint, render_template, abort, jsonify, send_file, json from typing import cast, Optional, Any from datetime import datetime, timedelta, timezone -from app.config import timeout +from config import timeout from ..models import service, log from app import app, db diff --git a/migrations/README b/app/migrations/README similarity index 100% rename from migrations/README rename to app/migrations/README diff --git a/migrations/alembic.ini b/app/migrations/alembic.ini similarity index 100% rename from migrations/alembic.ini rename to app/migrations/alembic.ini diff --git a/migrations/env.py b/app/migrations/env.py similarity index 100% rename from migrations/env.py rename to app/migrations/env.py diff --git a/migrations/script.py.mako b/app/migrations/script.py.mako similarity index 100% rename from migrations/script.py.mako rename to app/migrations/script.py.mako diff --git a/migrations/versions/3c05315d5b9b_.py b/app/migrations/versions/3c05315d5b9b_.py similarity index 100% rename from migrations/versions/3c05315d5b9b_.py rename to app/migrations/versions/3c05315d5b9b_.py diff --git a/migrations/versions/d7d380435347_.py b/app/migrations/versions/d7d380435347_.py similarity index 100% rename from migrations/versions/d7d380435347_.py rename to app/migrations/versions/d7d380435347_.py diff --git a/migrations/versions/f04407e8e466_.py b/app/migrations/versions/f04407e8e466_.py similarity index 100% rename from migrations/versions/f04407e8e466_.py rename to app/migrations/versions/f04407e8e466_.py diff --git a/migrations/versions/f87909a4293b_.py b/app/migrations/versions/f87909a4293b_.py similarity index 100% rename from migrations/versions/f87909a4293b_.py rename to app/migrations/versions/f87909a4293b_.py diff --git a/app/routes.py b/app/routes.py new file mode 100644 index 0000000..4a29d34 --- /dev/null +++ b/app/routes.py @@ -0,0 +1,95 @@ +from flask import Blueprint, render_template, abort, jsonify, send_file, json +from typing import cast, Optional, Any +from datetime import datetime, timedelta, timezone +from config import timeout +from ..models import service, log +from app import app, db + +bp = Blueprint( + "api", + "__name__", + url_prefix="/api", + static_folder="static", +) + + +# Prepares log data for chart.js chart +def prepare_chart_data( + logs: list[log], +) -> tuple[list[str], list[Optional[int]]]: + if len(logs) <= 0: # Return empty if there are no logs + return ([], []) + + x = [logs[0].dateCreatedUTC().isoformat()] + y = [logs[0].ping] + + for i in range(1, len(logs)): + log1 = logs[i] + log2 = logs[i - 1] + + # Check if the gap in points exceeds a threshold + if (abs(log1.dateCreatedUTC() - log2.dateCreatedUTC())) > timedelta( + milliseconds=1.5 * (timeout + 1000) + ): + x.append(log2.dateCreatedUTC().isoformat()) + y.append(None) + + x.append(log1.dateCreatedUTC().isoformat()) + y.append(log1.ping) + return (x, y) + + +@bp.route("/") +def homepage(): + return render_template("home.html") + + +@bp.route("/chart/") +def chart(id: int): + with app.app_context(): + logs = [] + s = db.session.query(service).filter_by(id=id).first() + if s: + logs = cast( + list[log], + s.logs.order_by(log.dateCreated.desc()) # type: ignore + .limit(300) + .all(), + ) + else: + return abort(code=403) + x, y = prepare_chart_data(logs=logs) + + now = datetime.now(timezone.utc) + max_ = now + min_ = now - timedelta(hours=1) + return render_template( + "chart.html", + dates=x, + values=json.dumps(y), + min=min_.isoformat(), + max=max_.isoformat(), + ) + + +@bp.route("/status") +def status(): + results: list[dict[str, Any]] = [] + with app.app_context(): + a = db.session.query(service).all() + for s in a: + b = cast( + Optional[log], + s.logs.order_by( + log.dateCreated.desc() # type: ignore + ).first(), + ) + if b: + results.append(s.to_dict() | b.to_dict()) + + return jsonify(results) + + +@bp.route("/favicon.svg") +def favicon(): + return send_file("/static/favicon.svg") diff --git a/app/config.py b/config.py similarity index 100% rename from app/config.py rename to config.py