From cc6e9c8de0a7cf53c69b2c9ac91dab61084d3a9b Mon Sep 17 00:00:00 2001 From: Mathieu Moran Date: Mon, 10 Aug 2026 02:17:29 -0400 Subject: [PATCH] feat: add download button to Pi videos list - /api/local-video/file?download=1 serves file as attachment - Download link (green DL button) added to each row in local-videos.js - Dashcam USB files skipped: no persistent mount for direct serve; use Import then download from Pi Videos Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- app.py | 12 +++++++++++- static/js/local-videos.js | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index b180cc4..fbbe5a1 100644 --- a/app.py +++ b/app.py @@ -146,7 +146,17 @@ def local_video_file(): return jsonify(error=str(error)), 400 except FileNotFoundError: return jsonify(error=f"Local video not found: {relative_path}"), 404 - return send_file(path, conditional=True, as_attachment=False) + as_attachment = request.args.get("download") == "1" + return send_file(path, conditional=True, as_attachment=as_attachment) + +@app.route('/api/dash/file/download') +def dash_file_download(): + relative_path = request.args.get("path", "") + try: + path = app_dash.safe_video_path(app_dash.DEFAULT_MOUNT_POINT, relative_path) + except (ValueError, FileNotFoundError) as error: + return jsonify(error=str(error)), 400 + return send_file(path, as_attachment=True) @app.route('/api/local-video/thumbnail') def local_video_thumbnail(): diff --git a/static/js/local-videos.js b/static/js/local-videos.js index 263b0d4..edc58ac 100644 --- a/static/js/local-videos.js +++ b/static/js/local-videos.js @@ -188,6 +188,13 @@ actionsDiv.appendChild(convertButton); } + const downloadLink = document.createElement("a"); + downloadLink.href = `/api/local-video/file?path=${encodeURIComponent(file.path)}&download=1`; + downloadLink.className = "btn btn-sm btn-outline-success btn-icon-mobile"; + downloadLink.download = file.path.split("/").pop(); + downloadLink.innerHTML = ' DL'; + actionsDiv.appendChild(downloadLink); + const deleteButton = document.createElement("button"); deleteButton.type = "button"; deleteButton.className = "btn btn-sm btn-outline-danger btn-icon-mobile";