feat(backend): Mittelweg cascade — never download wrong song on no duration match
When a track's duration is known but nothing matches the duration window, the cascade no longer falls back to blind title-only/no-filter grabs (which pulled same-titled videos by other uploaders, e.g. a "recognize" fan clip). Instead it relaxes only the duration constraint while still REQUIRING the artist channel + title. If nothing matches, the download produces no file and the job now fails cleanly with "Nicht eindeutig gefunden — bitte Direktlink im Importer nutzen" (previously it falsely reported success with no file). Single, album and playlist paths all surface the not-found state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
cf6e75b312
commit
a870f50c87
3 files changed
+23
-29
No files matched your search
@@ -601,6 +601,8 @@ app.post('/api/download', async (req, res) => {
|
||||
const result = await downloadTrack({ jobId, artist: finalArtist, rawArtist: artist, title, ...meta, sourceUrl: sourceUrl || sp.sourceUrl || undefined });
|
||||
if (result?.skipped) {
|
||||
updateJob(jobId, { status: 'done', progress: 100, message: 'Bereits vorhanden – übersprungen', skipped: true });
|
||||
} else if (result?.notFound) {
|
||||
updateJob(jobId, { status: 'error', message: 'Nicht eindeutig gefunden — bitte Direktlink im Importer nutzen' });
|
||||
} else {
|
||||
updateJob(jobId, { status: 'done', progress: 100, message: 'Fertig!' });
|
||||
}
|
||||
@@ -653,7 +655,7 @@ app.post('/api/download', async (req, res) => {
|
||||
const plTracks = req.body.tracks || [];
|
||||
if (!plTracks.length) throw new Error('Keine Tracks übergeben');
|
||||
log(jobId, `🎵 Playlist "${title}" — ${plTracks.length} Tracks`);
|
||||
let done = 0, skipped = 0;
|
||||
let done = 0, skipped = 0, notFound = 0;
|
||||
const CONC = CONFIG.maxParallel || 2;
|
||||
for (let i = 0; i < plTracks.length; i += CONC) {
|
||||
const batch = plTracks.slice(i, i + CONC);
|
||||
@@ -709,10 +711,13 @@ app.post('/api/download', async (req, res) => {
|
||||
log(jobId, `⚠️ Fehler bei "${batch[j].trackName || '?'}": ${r.reason?.message || r.reason}`);
|
||||
} else if (r.value?.skipped) {
|
||||
skipped++;
|
||||
} else if (r.value?.notFound) {
|
||||
notFound++;
|
||||
log(jobId, `⚠️ Nicht eindeutig gefunden: "${batch[j].trackName || '?'}" — Direktlink nutzen`);
|
||||
} else {
|
||||
done++;
|
||||
}
|
||||
updateJob(jobId, { progress: Math.round(((done + skipped) / plTracks.length) * 90) });
|
||||
updateJob(jobId, { progress: Math.round(((done + skipped + notFound) / plTracks.length) * 90) });
|
||||
}
|
||||
}
|
||||
const allSkipped = skipped === plTracks.length;
|
||||
@@ -720,7 +725,7 @@ app.post('/api/download', async (req, res) => {
|
||||
status: 'done', progress: 100, skipped: allSkipped,
|
||||
message: allSkipped
|
||||
? `Alle ${skipped} Tracks bereits vorhanden`
|
||||
: `Fertig! ${done} geladen${skipped ? `, ${skipped} übersprungen` : ''}`,
|
||||
: `Fertig! ${done} geladen${skipped ? `, ${skipped} übersprungen` : ''}${notFound ? `, ${notFound} nicht gefunden` : ''}`,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Reference in new issue
Block a user