From 5096c618b49937c265eb00ff6608e49e52da347e Mon Sep 17 00:00:00 2001 From: 3dtours Date: Sun, 26 Jul 2026 18:37:46 +0700 Subject: [PATCH] fix: SF3 download prefers SF2, cache invalidation on parse error - Download endpoint reverses extension priority: .sf2 > .sf3 - loadSoundFont adds ?t= cache-buster, invalidates IndexedDB on error - Retry logic: delete corrupted cache entry, allow re-download --- app/api/v1/plugins.py | 8 ++++---- app/static/js/services/soundfontPlayer.js | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/api/v1/plugins.py b/app/api/v1/plugins.py index a884d2d..074cd5d 100644 --- a/app/api/v1/plugins.py +++ b/app/api/v1/plugins.py @@ -131,18 +131,18 @@ async def download_soundfont_asset(sf_id: str): for base_dir in [UPLOAD_SF_DIR, SYSTEM_SF_DIR]: if not os.path.isdir(base_dir): continue - for ext in [".sf3", ".sf2"]: + for ext in [".sf2", ".sf3"]: for fname in os.listdir(base_dir): fbase, fext = os.path.splitext(fname) if fext.lower() == ext and fbase.lower() == clean_id.lower(): full = os.path.join(base_dir, fname) - return FileResponse(full, media_type="application/octet-stream", filename=f"{fbase}{ext}") + return FileResponse(full, media_type="application/octet-stream", filename=f"soundfont{ext}") # Fallback: try exact match on sf_id for base_dir in [UPLOAD_SF_DIR, SYSTEM_SF_DIR]: - for ext in [".sf3", ".sf2"]: + for ext in [".sf2", ".sf3"]: full = os.path.join(base_dir, clean_id + ext) if os.path.exists(full): - return FileResponse(full, media_type="application/octet-stream", filename=f"{clean_id}{ext}") + return FileResponse(full, media_type="application/octet-stream", filename=f"soundfont{ext}") raise HTTPException(status_code=404, detail="SoundFont asset not found") diff --git a/app/static/js/services/soundfontPlayer.js b/app/static/js/services/soundfontPlayer.js index af4ff81..59227ee 100644 --- a/app/static/js/services/soundfontPlayer.js +++ b/app/static/js/services/soundfontPlayer.js @@ -91,7 +91,7 @@ } if (!buffer) { try { - const resp = await fetch("/api/v1/plugins/soundfonts/download/" + encodeURIComponent(sfId)); + const resp = await fetch("/api/v1/plugins/soundfonts/download/" + encodeURIComponent(sfId) + "?t=" + Date.now()); if (!resp.ok) throw new Error("Download failed: " + resp.status); buffer = await resp.arrayBuffer(); if (window.SonicSFStorage) { @@ -107,7 +107,18 @@ _currentSfId = sfId; console.log("[SonicSF] SoundFont loaded:", sfId); } catch (e) { - console.error("[SonicSF] Error parsing SF in SpessaSynth:", e); + console.error("[SonicSF] Error parsing SF in SpessaSynth:", sfId, e); + // Invalidate cache and retry once with fresh download + if (window.SonicSFStorage) { + try { + const db = await window.SonicSFStorage.openDB(); + const tx = db.transaction(window.SonicSFStorage.storeName, "readwrite"); + tx.objectStore(window.SonicSFStorage.storeName).delete(sfId); + console.log("[SonicSF] Invalidated cache for:", sfId); + } catch (ce) {} + } + // Clear current SF so next load will actually run + _currentSfId = null; } },