feat(dashcam): async import with polling status

- Import now returns immediately with {status: 'started'}
- Backend runs copy in a daemon thread, tracks job state in _import_job
- New GET /api/dash/import/status endpoint for polling
- UI polls every 3s, shows progress bar until done
- Page reload mid-import resumes polling automatically
- Prevents double-import with 'busy' guard

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Mathieu Moran
2026-08-10 01:12:00 -04:00
co-authored by Copilot
parent 7d124b0fa0
commit 71f8ce2993
3 changed files with 115 additions and 63 deletions
+12 -15
View File
@@ -97,21 +97,18 @@ def dash_devices():
@app.route('/api/dash/import', methods=['POST'])
def dash_import():
body = request.get_json(silent=True)
if body is None:
relative_paths = None
elif isinstance(body, dict):
relative_paths = body.get("paths", [])
else:
relative_paths = []
summary = app_dash.import_dashcam(relative_paths=relative_paths)
status_code = (
200
if summary["status"] == "ok"
else 400
if summary["status"] == "invalid_selection"
else 409
)
return jsonify(summary), status_code
relative_paths = body.get("paths") if isinstance(body, dict) else None
started, err = app_dash.start_import_async(relative_paths=relative_paths)
if not started:
return jsonify({"status": "busy", "message": err}), 409
return jsonify({"status": "started"})
@app.route('/api/dash/import/status')
def dash_import_status():
job = app_dash.get_import_status()
if job is None:
return jsonify({"status": "none"})
return jsonify(job)
@app.route('/api/dash/files')
def dash_files():