mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
fix(local-audio): reference-aware cleanup, upload quota, stricter validation
Uploaded local files were deleted whenever a track left the current slot, with no check on whether the file was still needed — causing data loss in several flows. Replace with reference-aware cleanup: a file is deleted only once it has been played AND is no longer referenced by ANY bot's queue (BotManager.getReferencedLocalSongIds wired into the provider via setInUseResolver), with the sweep run AFTER each queue mutation. Fixes: - play-song replay no longer deletes the file it is about to play - loop / repeat-all / prev no longer destroy uploads mid-cycle - a shared upload queued on multiple bots is not deleted while still in use - !play / play-playlist / play-album clean the whole replaced queue, and an empty/failed playlist/album load keeps the previous queue + files intact - bound disk use with an upload quota (evict oldest UNREFERENCED files) - validate uploads by extension against the audio whitelist (never trust the client Content-Type); the stored extension is always a known audio type Deletion now unlinks the file FIRST and drops the record only on success, with a bounded non-blocking retry for briefly-locked files (Windows/ffmpeg), so a failed unlink never orphans a file or diverges index.json. The quota never evicts the just-uploaded file, and long filenames keep their extension. Adds src/music/local.test.ts covering the cleanup lifecycle, quota eviction, and upload validation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
e12cbf8863
commit
e849db2286
5 files changed
+453
-77
No files matched your search
@@ -100,6 +100,12 @@ export class BotManager extends EventEmitter {
|
||||
this.bilibiliProvider = bilibiliProvider;
|
||||
this.youtubeProvider = new YouTubeProvider();
|
||||
this.localProvider = localProvider ?? neteaseProvider;
|
||||
// Let the local provider see which uploads are still referenced by any
|
||||
// bot's queue, so it never deletes a file another queue/bot still needs.
|
||||
const referenceable = this.localProvider as Partial<{
|
||||
setInUseResolver: (resolver: () => Set<string>) => void;
|
||||
}>;
|
||||
referenceable.setInUseResolver?.(() => this.getReferencedLocalSongIds());
|
||||
this.database = database;
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
@@ -214,6 +220,18 @@ export class BotManager extends EventEmitter {
|
||||
return Array.from(this.bots.values());
|
||||
}
|
||||
|
||||
/** Local upload ids still referenced by any bot's queue. The local provider
|
||||
* uses this to avoid deleting a file another queue/bot is still using. */
|
||||
getReferencedLocalSongIds(): Set<string> {
|
||||
const ids = new Set<string>();
|
||||
for (const bot of this.bots.values()) {
|
||||
for (const song of bot.getQueueManager().list()) {
|
||||
if (song.platform === "local") ids.add(song.id);
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
async startBot(id: string): Promise<void> {
|
||||
const oldBot = this.bots.get(id);
|
||||
if (!oldBot) throw new Error(`Bot ${id} not found`);
|
||||
|
||||
Reference in new issue
Block a user