diff --git a/kobrax_moonraker_bridge.py b/kobrax_moonraker_bridge.py index e959928..43dd03a 100644 --- a/kobrax_moonraker_bridge.py +++ b/kobrax_moonraker_bridge.py @@ -1514,6 +1514,19 @@ class KobraXBridge: return self._json_cors({"result": "ok"}) return self._json_cors({"error": "not found"}, status=404) + async def handle_kx_file_download(self, request): + file_id = request.match_info["file_id"] + f = self._store.get_file(file_id) + if not f: + return self._json_cors({"error": "not found"}, status=404) + path = f.get("path") or "" + if not path or not os.path.isfile(path): + return self._json_cors({"error": "not found"}, status=404) + filename = os.path.basename(f.get("filename") or path) + return web.FileResponse(path, headers={ + "Content-Disposition": f'attachment; filename="{filename}"' + }) + async def handle_kx_file_verify(self, request): file_id = request.match_info["file_id"] if self._store.clear_web_unverified(file_id): @@ -3483,6 +3496,7 @@ def build_app(bridge: KobraXBridge) -> web.Application: r.add_post("/kx/print", bridge.handle_kx_print) r.add_get("/kx/files", bridge.handle_kx_files) r.add_delete("/kx/files/{file_id}", bridge.handle_kx_file_delete) + r.add_get("/kx/files/{file_id}/download", bridge.handle_kx_file_download) r.add_post("/kx/files/{file_id}/verify", bridge.handle_kx_file_verify) r.add_get("/kx/filament/slots", bridge.handle_kx_filament_slots) r.add_get("/kx/history", bridge.handle_kx_history) diff --git a/web/themes/default/app.js b/web/themes/default/app.js index 809c02b..25848f1 100644 --- a/web/themes/default/app.js +++ b/web/themes/default/app.js @@ -146,6 +146,7 @@ var LANG_DE={ store_empty:'Noch keine Dateien hochgeladen.', store_refresh:'↻ Aktualisieren', store_print:'▶ Drucken', + store_download:'⬇ Download', store_delete_confirm:'Datei löschen?', store_print_confirm:'Datei drucken?', store_web_verify_title:'Datei verifizieren', @@ -214,6 +215,7 @@ var LANG_EN={ store_empty:'No files uploaded yet.', store_refresh:'↻ Refresh', store_print:'▶ Print', + store_download:'⬇ Download', store_delete_confirm:'Delete file?', store_print_confirm:'Print file?', store_web_verify_title:'Verify file', @@ -1663,6 +1665,8 @@ function renderStore(){ '
'+ ''+ + ''+ ''+ '
'+ @@ -2239,6 +2243,15 @@ function storeDelete(fileId){ }); } +function storeDownload(fileId){ + var a=document.createElement('a'); + a.href=_apiUrl('/kx/files/'+encodeURIComponent(fileId)+'/download'); + a.style.display='none'; + document.body.appendChild(a); + a.click(); + a.remove(); +} + // ── Drucker hinzufügen ── function openAddPrinterDialog(){ document.getElementById('apd-ip').value='';