From c454f2ef3a93658450aba97454ac6ae29ad15ce0 Mon Sep 17 00:00:00 2001 From: pablorevilla-meshtastic Date: Thu, 5 Feb 2026 06:53:49 -0800 Subject: [PATCH] started work on new traceroute template --- README.md | 96 +++++++++++--------- meshview/templates/traceroute.html | 138 +++++++++++++++++++++++++++++ meshview/web.py | 9 ++ meshview/web_api/api.py | 33 ++++++- 4 files changed, 233 insertions(+), 43 deletions(-) create mode 100644 meshview/templates/traceroute.html diff --git a/README.md b/README.md index fd8f62c..a2f59a9 100644 --- a/README.md +++ b/README.md @@ -554,60 +554,76 @@ echo "Database cleanup completed on $(date)" - If you are using PostgreSQL, use this version instead (adjust credentials/DB name): ```bash #!/bin/bash +set -euo pipefail -DB_NAME="meshview" -DB_USER="meshview" -DB_HOST="localhost" -DB_PORT="5432" +DB="postgresql://meshview@localhost:5432/meshview" +RETENTION_DAYS=14 +BATCH_SIZE=100 -# Stop DB service -sudo systemctl stop meshview-db.service -sudo systemctl stop meshview-web.service +PSQL="/usr/bin/psql" -sleep 5 -echo "Run cleanup..." -# Run cleanup queries -psql "postgresql://${DB_USER}@${DB_HOST}:${DB_PORT}/${DB_NAME}" <<'EOF' -WITH deleted AS ( - DELETE FROM packet +echo "[$(date)] Starting batched cleanup..." + +while true; do + DELETED=$( + $PSQL "$DB" -At -v ON_ERROR_STOP=1 < +{% endblock %} + +{% block css %} +#traceroute-graph { + width: 100%; + height: 85vh; + border: 1px solid #2a2f36; + background: linear-gradient(135deg, #0f1216 0%, #171b22 100%); + border-radius: 10px; +} + +#traceroute-meta { + padding: 12px 16px; + color: #c8d0da; +} + +#traceroute-error { + color: #ff6b6b; +} +{% endblock %} + +{% block body %} +
+
Traceroute
+
+
+
+ + +{% endblock %} diff --git a/meshview/web.py b/meshview/web.py index 09486fe..a050474 100644 --- a/meshview/web.py +++ b/meshview/web.py @@ -314,6 +314,15 @@ async def stats(request): ) +@routes.get("/traceroute/{packet_id}") +async def traceroute_page(request): + template = env.get_template("traceroute.html") + return web.Response( + text=template.render(), + content_type="text/html", + ) + + # Keep !! @routes.get("/graph/traceroute/{packet_id}") async def graph_traceroute(request): diff --git a/meshview/web_api/api.py b/meshview/web_api/api.py index 6c7626e..e318ed5 100644 --- a/meshview/web_api/api.py +++ b/meshview/web_api/api.py @@ -761,7 +761,8 @@ async def api_traceroute(request): forward_paths = [] reverse_paths = [] - winning_paths = [] + winning_forward_paths = [] + winning_reverse_paths = [] for tr in tr_groups: f = tuple(tr["forward_hops"]) @@ -774,7 +775,10 @@ async def api_traceroute(request): reverse_paths.append(r) if tr["done"]: - winning_paths.append(f) + if tr["forward_hops"]: + winning_forward_paths.append(f) + if tr["reverse_hops"]: + winning_reverse_paths.append(r) # Deduplicate unique_forward_paths = sorted(set(forward_paths)) @@ -790,7 +794,30 @@ async def api_traceroute(request): unique_reverse_paths_json = [list(p) for p in unique_reverse_paths] - winning_paths_json = [list(p) for p in set(winning_paths)] + from_node_id = packet.from_node_id + to_node_id = packet.to_node_id + winning_forward_with_endpoints = [] + for path in set(winning_forward_paths): + full_path = list(path) + if from_node_id is not None and (not full_path or full_path[0] != from_node_id): + full_path = [from_node_id, *full_path] + if to_node_id is not None and (not full_path or full_path[-1] != to_node_id): + full_path = [*full_path, to_node_id] + winning_forward_with_endpoints.append(full_path) + + winning_reverse_with_endpoints = [] + for path in set(winning_reverse_paths): + full_path = list(path) + if to_node_id is not None and (not full_path or full_path[0] != to_node_id): + full_path = [to_node_id, *full_path] + if from_node_id is not None and (not full_path or full_path[-1] != from_node_id): + full_path = [*full_path, from_node_id] + winning_reverse_with_endpoints.append(full_path) + + winning_paths_json = { + "forward": winning_forward_with_endpoints, + "reverse": winning_reverse_with_endpoints, + } # -------------------------------------------- # Final API output