diff --git a/app/flask_app/templates/chart.html b/app/flask_app/templates/chart.html
index 4690859..f8adf2f 100644
--- a/app/flask_app/templates/chart.html
+++ b/app/flask_app/templates/chart.html
@@ -1,10 +1,12 @@
-
+
-
-
+
Simple Line Chart
+
+
@@ -43,14 +45,18 @@
x: {
type: 'time', // Important for datetime axis
time: {
- unit: 'hour',
+ unit: 'minute',
tooltipFormat: 'HH:mm:ss',
- displayFormats: {
- hour: 'HH:mm'
- }
+ displayFormats: { hour: 'HH:mm' }
},
min: min,
- max: max
+ max: max,
+ ticks: { color: '#ffffff' }, // X-axis labels
+ grid: { color: 'rgba(255, 255, 255, 0.1)' } // X-axis grid lines
+ },
+ y: {
+ ticks: { color: '#ffffff' }, // Y-axis labels
+ grid: { color: 'rgba(255, 255, 255, 0.1)' } // Y-axis grid lines
}
}
}
diff --git a/app/routes.py b/app/routes.py
new file mode 100644
index 0000000..d66be49
--- /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(
+ "main",
+ "__name__",
+ url_prefix="/",
+ 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("/api/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")