From 89673db0bff3cf1604ee1a9e9e2d5723050950e0 Mon Sep 17 00:00:00 2001 From: dsutanto Date: Wed, 5 Aug 2026 07:58:00 +0700 Subject: [PATCH] Add cross-dashboard header links (UPLOAD_DASHBOARD_URL, LIVE_DASHBOARD_URL) --- AGENTS.md | 1 + SPEC.md | 3 +++ config.env.example | 4 ++++ counter_dashboard.py | 3 ++- recounting_dashboard_upload.py | 3 ++- templates/dashboard.html | 1 + templates/dashboard_lamborghini.html | 1 + templates/dashboard_tesla.html | 1 + templates/recounting_upload.html | 1 + 9 files changed, 16 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1b2b5ef..59ad2ae 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,6 +48,7 @@ PYTHONNOUSERSITE=1 venv/bin/python recounting_dashboard_upload.py - **Reset flow**: `POST /api/reset` → deletes state JSON + touches `{SHM_DIR}/.reset`. `batch_store._check_reset_signal()` watches this marker and clears in-memory state on next crossing. - **Upload filename contract**: uploads are expected as `batch_XX_YYYYMMDD_HHmmSS.mp4` (XX = batch number, timestamp = date). `recounting_dashboard_upload.py` parses both to query the live API's `/api/day-detail/` for the recorded count. - **`RECOUNT_CMD`** in the upload dashboard is a template with a `{path}` placeholder, e.g. `bytetrack-counter config.env --source {path}`; the uploaded file path is `shlex.quote()`d before substitution. +- **Cross-dashboard header links**: `UPLOAD_DASHBOARD_URL` (live → upload dashboard, `counter_dashboard.py`) and `LIVE_DASHBOARD_URL` (upload → live dashboard, `recounting_dashboard_upload.py`); empty value hides the header link. ## Code conventions diff --git a/SPEC.md b/SPEC.md index 8ea2bef..875f5b1 100644 --- a/SPEC.md +++ b/SPEC.md @@ -54,6 +54,7 @@ env: MIN_OBJECT_PER_BATCH → min count to persist batch (default 60) env: MIN_DURATION_PER_BATCH → min seconds to persist batch (default 60) env: LIVE_STREAM_ENABLED → write annotated JPEG snapshot each N frames env: EXPORT_CSV → write per-crossing CSV (default true) +env: UPLOAD_DASHBOARD_URL → header link to upload recounting dashboard (default empty → hidden) ### Recounting dashboard config ``` @@ -70,6 +71,7 @@ env: RECOUNTING_UPLOAD_PORT → port for upload UI (default 5003) env: UPLOAD_DIR → dir for uploaded MP4s (default /uploads) env: RECOUNT_CMD → replay command template with {path} placeholder (default "bytetrack-counter config.env --source {path}") env: RECOUNTING_UPLOAD_TEMPLATE → template (default recounting_upload.html) +env: LIVE_DASHBOARD_URL → header link to live counter dashboard (default empty → hidden) ``` ``` @@ -178,6 +180,7 @@ T12|x|add recounting dashboard — dual-API counter panels, MP4 browser, go2rtc T13|x|add template system — DASHBOARD_TEMPLATE env var selects dashboard.html|lamborghini|tesla| T14|x|harden reset API — separate SHM marker creation from state file cleanup; return 500 on SHM failure|V20 T15|x|add upload recounting dashboard — MP4 upload, progress bar, RECOUNT_CMD replay|V21 +T16|x|add cross-dashboard header links — UPLOAD_DASHBOARD_URL (live→upload) & LIVE_DASHBOARD_URL (upload→live)|I.config ``` ## §B — Bugs diff --git a/config.env.example b/config.env.example index 6ce2ad1..b3ac86c 100644 --- a/config.env.example +++ b/config.env.example @@ -159,6 +159,8 @@ SECRET_KEY=change-me-in-production DASHBOARD_HOST=0.0.0.0 # Listen port for the dashboard web UI DASHBOARD_PORT=5000 +# URL of the upload recounting dashboard (recounting_dashboard_upload.py); empty hides the header link +UPLOAD_DASHBOARD_URL=http://localhost:5003 # Enable Flask debug mode (true/false) — auto-reloads on code changes; disable in production FLASK_DEBUG=false # Fallback name for the active-batch JSON state file used by the dashboard @@ -188,3 +190,5 @@ UPLOAD_DIR=/opt/bytetrack-counter/uploads RECOUNT_CMD=bytetrack-counter config.env --source {path} # Template file for the upload dashboard: "recounting_upload.html" (default) RECOUNTING_UPLOAD_TEMPLATE=recounting_upload.html +# URL of the live counter dashboard (counter_dashboard.py); empty hides the header link +LIVE_DASHBOARD_URL=http://localhost:5000 diff --git a/counter_dashboard.py b/counter_dashboard.py index 3f0b00a..1b13c3f 100644 --- a/counter_dashboard.py +++ b/counter_dashboard.py @@ -40,6 +40,7 @@ SHM_DIR = os.getenv("SHM_DIR", "/dev/shm/bytetrack-counter") SITE_NAME = os.getenv("SITE_NAME", "LIVE") TEMPLATE = os.getenv("DASHBOARD_TEMPLATE", "dashboard.html") +UPLOAD_DASHBOARD_URL = os.getenv("UPLOAD_DASHBOARD_URL", "") DASHBOARD_PORT = int(os.getenv("DASHBOARD_PORT", "5000")) DASHBOARD_HOST = os.getenv("DASHBOARD_HOST", "0.0.0.0") @@ -132,7 +133,7 @@ def get_counting_date(dt=None, cutoff_str=CUTOFF_TIME): @app.route("/") def index(): - return render_template(TEMPLATE, site_name=SITE_NAME) + return render_template(TEMPLATE, site_name=SITE_NAME, upload_dashboard_url=UPLOAD_DASHBOARD_URL) @app.route("/api/current-batch") diff --git a/recounting_dashboard_upload.py b/recounting_dashboard_upload.py index e30fdc6..47f3122 100644 --- a/recounting_dashboard_upload.py +++ b/recounting_dashboard_upload.py @@ -36,6 +36,7 @@ RECOUNT_API_URL = os.getenv("RECOUNT_API_URL", "http://localhost:5001") SITE_NAME = os.getenv("SITE_NAME", "RECOUNT") TEMPLATE = os.getenv("RECOUNTING_UPLOAD_TEMPLATE", "recounting_upload.html") +LIVE_DASHBOARD_URL = os.getenv("LIVE_DASHBOARD_URL", "") DASHBOARD_PORT = int(os.getenv("RECOUNTING_UPLOAD_PORT", "5003")) DASHBOARD_HOST = os.getenv("DASHBOARD_HOST", "0.0.0.0") @@ -92,7 +93,7 @@ def _folder_date(filepath, base): @app.route("/") def index(): - return render_template(TEMPLATE, site_name=SITE_NAME, upload_dir=str(UPLOAD_DIR)) + return render_template(TEMPLATE, site_name=SITE_NAME, upload_dir=str(UPLOAD_DIR), live_dashboard_url=LIVE_DASHBOARD_URL) @app.route("/api/live-progress") diff --git a/templates/dashboard.html b/templates/dashboard.html index 7416951..756220f 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -575,6 +575,7 @@ -- Counting Day + {% if upload_dashboard_url %}RECOUNT UPLOAD{% endif %}
{{ site_name }} diff --git a/templates/dashboard_lamborghini.html b/templates/dashboard_lamborghini.html index 07e21e2..b1efdf6 100644 --- a/templates/dashboard_lamborghini.html +++ b/templates/dashboard_lamborghini.html @@ -408,6 +408,7 @@ -- Counting Day
+ {% if upload_dashboard_url %}RECOUNT UPLOAD{% endif %}
{{ site_name }} diff --git a/templates/dashboard_tesla.html b/templates/dashboard_tesla.html index 9acb547..c334535 100644 --- a/templates/dashboard_tesla.html +++ b/templates/dashboard_tesla.html @@ -418,6 +418,7 @@ -- Counting Day
+ {% if upload_dashboard_url %}RECOUNT UPLOAD{% endif %}
{{ site_name }} diff --git a/templates/recounting_upload.html b/templates/recounting_upload.html index 0efc5cc..c8c6e72 100644 --- a/templates/recounting_upload.html +++ b/templates/recounting_upload.html @@ -432,6 +432,7 @@
+ {% if live_dashboard_url %}LIVE DASHBOARD{% endif %}
LIVE