upated
This commit is contained in:
11
app.py
11
app.py
@@ -21,12 +21,7 @@ from datetime import datetime
|
|||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from flask import Flask, jsonify, request, render_template
|
from flask import Flask, jsonify, request, render_template
|
||||||
|
from config import SERIES_MAX_POINTS_DEFAULT, DB_PATH, SERIES_MAX_POINTS_HARD, PAGE_SIZE_MAX, PAGE_SIZE_DEFAULT
|
||||||
DB_PATH = os.environ.get("DB_PATH", "./speed_tests.sqlite3")
|
|
||||||
PAGE_SIZE_DEFAULT = 200
|
|
||||||
PAGE_SIZE_MAX = 1000
|
|
||||||
SERIES_MAX_POINTS_DEFAULT = 5000
|
|
||||||
SERIES_MAX_POINTS_HARD = 20000
|
|
||||||
|
|
||||||
app = Flask(__name__, template_folder="templates")
|
app = Flask(__name__, template_folder="templates")
|
||||||
|
|
||||||
@@ -60,7 +55,7 @@ def api_series():
|
|||||||
q_from = request.args.get("from", type=float)
|
q_from = request.args.get("from", type=float)
|
||||||
q_to = request.args.get("to", type=float)
|
q_to = request.args.get("to", type=float)
|
||||||
max_points = request.args.get("max_points", type=int) or SERIES_MAX_POINTS_DEFAULT
|
max_points = request.args.get("max_points", type=int) or SERIES_MAX_POINTS_DEFAULT
|
||||||
max_points = max(100, min(max_points, SERIES_MAX_POINTS_HARD))
|
max_points = max(1, min(max_points, SERIES_MAX_POINTS_HARD))
|
||||||
|
|
||||||
params = []
|
params = []
|
||||||
where = []
|
where = []
|
||||||
@@ -167,5 +162,5 @@ def index():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
port = int(os.environ.get("PORT", 5000))
|
port = int(os.environ.get("PORT", 5000))
|
||||||
app.run(host="0.0.0.0", port=port, debug=True)
|
app.run(host="0.0.0.0", port=port)
|
||||||
|
|
||||||
|
|||||||
89
db.py
Normal file
89
db.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import sqlite3
|
||||||
|
from config import DB_PATH
|
||||||
|
|
||||||
|
|
||||||
|
def init_db(db_path=DB_PATH):
|
||||||
|
conn = sqlite3.connect(db_path)
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS speed_tests (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
timestamp REAL NOT NULL,
|
||||||
|
failed BOOLEAN NOT NULL,
|
||||||
|
isp TEXT,
|
||||||
|
ip TEXT,
|
||||||
|
location_code TEXT,
|
||||||
|
location_city TEXT,
|
||||||
|
location_region TEXT,
|
||||||
|
latency REAL,
|
||||||
|
jitter REAL,
|
||||||
|
down_100kB REAL,
|
||||||
|
down_1MB REAL,
|
||||||
|
down_10MB REAL,
|
||||||
|
down_25MB REAL,
|
||||||
|
down_90th REAL,
|
||||||
|
up_100kB REAL,
|
||||||
|
up_1MB REAL,
|
||||||
|
up_10MB REAL,
|
||||||
|
up_90th REAL
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
def insert_result(results: dict|None, db_path=DB_PATH):
|
||||||
|
conn = sqlite3.connect(db_path)
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
# If the test failed entirely, store it as a failure with timestamp now
|
||||||
|
if results is None or "tests" not in results:
|
||||||
|
from time import time
|
||||||
|
c.execute("INSERT INTO speed_tests (timestamp, failed) VALUES (?, ?)", (time(), True))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
tests = results.get("tests", {})
|
||||||
|
meta = results.get("meta", {})
|
||||||
|
|
||||||
|
# Get a consistent timestamp from any TestResult (or fallback to now)
|
||||||
|
from time import time as now
|
||||||
|
sample_test = next(iter(tests.values()), None)
|
||||||
|
timestamp = sample_test.time if sample_test else now()
|
||||||
|
|
||||||
|
print(tests)
|
||||||
|
print(meta)
|
||||||
|
|
||||||
|
def get(tests, key):
|
||||||
|
return tests[key].value if key in tests else None
|
||||||
|
|
||||||
|
c.execute('''
|
||||||
|
INSERT INTO speed_tests (
|
||||||
|
timestamp, failed, isp, ip, location_code, location_city, location_region,
|
||||||
|
latency, jitter,
|
||||||
|
down_100kB, down_1MB, down_10MB, down_25MB, down_90th,
|
||||||
|
up_100kB, up_1MB, up_10MB, up_90th
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
''', (
|
||||||
|
timestamp, False,
|
||||||
|
get(tests, "isp"),
|
||||||
|
get(meta, "ip"),
|
||||||
|
get(meta, "location_code"),
|
||||||
|
get(meta, "location_city"),
|
||||||
|
get(meta, "location_region"),
|
||||||
|
get(tests, "latency"),
|
||||||
|
get(tests, "jitter"),
|
||||||
|
get(tests, "100kB_down_mbps"),
|
||||||
|
get(tests, "1MB_down_mbps"),
|
||||||
|
get(tests, "10MB_down_mbps"),
|
||||||
|
get(tests, "25MB_down_mbps"),
|
||||||
|
get(tests, "90th_percentile_down_mbps"),
|
||||||
|
get(tests, "100kB_up_mbps"),
|
||||||
|
get(tests, "1MB_up_mbps"),
|
||||||
|
get(tests, "10MB_up_mbps"),
|
||||||
|
get(tests, "90th_percentile_up_mbps")
|
||||||
|
))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
<main class="wrap" style="display:grid; gap: 1rem;">
|
<main class="wrap" style="display:grid; gap: 1rem;">
|
||||||
<section class="card">
|
<section class="card">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label>Max points <input id="maxPoints" type="number" value="{{ SERIES_MAX_POINTS_DEFAULT }}" min="200" max="{{ SERIES_MAX_POINTS_HARD }}" step="200"></label>
|
<label>Max points <input id="maxPoints" type="number" value="{{ SERIES_MAX_POINTS_DEFAULT }}" min="0" max="{{ SERIES_MAX_POINTS_HARD }}" step="200"></label>
|
||||||
<button id="reloadSeries">Reload series</button>
|
<button id="reloadSeries">Reload series</button>
|
||||||
<span class="muted" id="seriesMeta"></span>
|
<span class="muted" id="seriesMeta"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function loadSeries() {
|
async function loadSeries() {
|
||||||
const maxPoints = Math.max(200, Math.min({{ SERIES_MAX_POINTS_HARD }}, Number(document.getElementById('maxPoints').value||{{ SERIES_MAX_POINTS_DEFAULT }})));
|
const maxPoints = Math.max(1, Math.min({{ SERIES_MAX_POINTS_HARD }}, Number(document.getElementById('maxPoints').value||{{ SERIES_MAX_POINTS_DEFAULT }})));
|
||||||
const url = new URL('/api/series', window.location.origin);
|
const url = new URL('/api/series', window.location.origin);
|
||||||
url.searchParams.set('max_points', maxPoints);
|
url.searchParams.set('max_points', maxPoints);
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
|
|||||||
Reference in New Issue
Block a user