Live Counter get total count per batch

This commit is contained in:
proitlab committed 2026-07-29 14:27:49 +07:00
1 parent fe220504fd
commit e3ae89de3d
4 files changed
+82 -1

No files matched your search

+1
View File
@@ -98,6 +98,7 @@ api: GET /api/live-video → MJPEG stream from shared-memory JPEG
api: GET / → recounting HTML
api: GET /api/live-progress → proxy to LIVE_API_URL:/api/current-batch
api: GET /api/recount-progress → proxy to RECOUNT_API_URL:/api/current-batch
api: GET /api/batch-result?file=<path> → parse `batch_NN_YYYYMMDD_HHmmSS.mp4`, query live API for count
api: GET /api/mp4-files → [ {name, path, size, mtime} ... ]
api: POST /api/start-recount {path} → configure go2rtc stream, return {stream_url}
api: POST /api/stop-recount → tear down go2rtc stream
+39
View File
@@ -5,6 +5,7 @@ lists OUTPUT_DIR MP4 files, streams via go2rtc for preview.
"""
import json
import os
import re
import subprocess
import requests
from datetime import datetime
@@ -34,6 +35,18 @@ FLASK_DEBUG = os.getenv("FLASK_DEBUG", "false").lower() == "true"
_http_session = requests.Session()
_http_session.timeout = 3
_FILENAME_RE = re.compile(r"batch_(\d+)_(\d{8})_\d{6}\.mp4")
def _parse_filename(filename):
m = _FILENAME_RE.match(filename)
if m:
batch_num = int(m.group(1))
date_str = m.group(2)
date_formatted = f"{date_str[:4]}-{date_str[4:6]}-{date_str[6:8]}"
return batch_num, date_formatted
return None, None
def _api_get(base_url, path, default=None):
try:
@@ -107,6 +120,32 @@ def start_recount():
return jsonify({"success": True, "stream_url": stream_url, "file": Path(mp4_path).name})
@app.route("/api/batch-result")
def api_batch_result():
fpath = request.args.get("file", "")
filename = Path(fpath).name
batch_num, date_str = _parse_filename(filename)
if batch_num is None:
return jsonify({"success": False, "error": "Cannot parse batch number from filename"}), 200
data = _api_get(LIVE_API_URL, f"/api/day-detail/{date_str}")
if not data:
return jsonify({"success": False, "error": "Live API unreachable"}), 200
for b in data.get("batches", []):
if b.get("batch_number") == batch_num:
return jsonify({
"success": True,
"batch_number": batch_num,
"date": date_str,
"count": b["count"],
"start_time": b.get("start_time"),
"end_time": b.get("end_time"),
})
return jsonify({"success": False, "error": f"Batch #{batch_num} not found on {date_str}"}), 200
@app.route("/api/stop-recount", methods=["POST"])
def stop_recount():
try:
+1
View File
@@ -4,3 +4,4 @@ opencv-python
flask
python-dotenv
openpyxl
requests
+41 -1
View File
@@ -356,6 +356,22 @@
<div class="counter-status disconnected" id="live-status">
waiting...
</div>
<div class="batch-result" id="batch-result" style="display:none;margin-top:16px;padding:12px;border-top:1px solid var(--divider);">
<div style="font-size:9px;color:var(--text-secondary);letter-spacing:1px;text-transform:uppercase;margin-bottom:6px;">
Selected Batch Result
</div>
<div style="display:flex;align-items:center;justify-content:center;gap:32px;">
<div>
<div style="font-size:8px;color:var(--text-secondary);letter-spacing:1px;">BATCH</div>
<div style="font-family:'Orbitron',sans-serif;font-size:20px;font-weight:700;color:var(--accent);" id="br-batch">--</div>
</div>
<div>
<div style="font-size:8px;color:var(--text-secondary);letter-spacing:1px;">COUNT</div>
<div style="font-family:'Orbitron',sans-serif;font-size:20px;font-weight:700;color:var(--accent4);" id="br-count">--</div>
</div>
</div>
<div style="font-size:9px;color:var(--text-secondary);margin-top:6px;" id="br-date">--</div>
</div>
</div>
</div>
<div class="panel">
@@ -467,7 +483,31 @@ function selectFile(path, name) {
selectedFile = path;
document.getElementById('btn-start').disabled = false;
document.getElementById('stream-file-name').textContent = name;
loadFiles(); // refresh selection
loadFiles();
loadBatchResult(path);
}
async function loadBatchResult(filePath) {
const el = document.getElementById('batch-result');
if (!filePath) {
el.style.display = 'none';
return;
}
try {
const res = await fetch('/api/batch-result?file=' + encodeURIComponent(filePath));
const data = await res.json();
if (!data.success) {
el.style.display = 'none';
return;
}
document.getElementById('br-batch').textContent = '#' + data.batch_number;
document.getElementById('br-count').textContent = data.count.toLocaleString();
document.getElementById('br-date').textContent = data.date;
el.style.display = 'block';
} catch (err) {
console.error('Failed to load batch result:', err);
el.style.display = 'none';
}
}
function formatSize(bytes) {