refactor: remove dead code from backend and lib
- Remove unused spotifyClientId/spotifyClientSecret from config - Remove AUDIO_EXTS from metadata exports (internal-only) - Remove tryYtdlp wrapper in ytdlp.js (direct spawnYtdlp calls) - Remove _spArtistName wrapper in server (direct _spAllArtists calls) - Fix stale comment: primary resolver is SpotipyFree, not curl_cffi Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
c36dbb3c94
commit
0f1e6ff531
4 files changed
+14
-22
No files matched your search
@@ -9,9 +9,6 @@ const CONFIG = {
|
|||||||
downloadBackend: (process.env.DOWNLOAD_BACKEND || 'auto').toLowerCase(),
|
downloadBackend: (process.env.DOWNLOAD_BACKEND || 'auto').toLowerCase(),
|
||||||
// squid.wtf quality: 'mp3' | 'flac' | 'hi-res'
|
// squid.wtf quality: 'mp3' | 'flac' | 'hi-res'
|
||||||
squidQuality: (process.env.SQUID_QUALITY || 'mp3').toLowerCase(),
|
squidQuality: (process.env.SQUID_QUALITY || 'mp3').toLowerCase(),
|
||||||
// Spotify Developer credentials (Client Credentials Flow — free, no Premium needed)
|
|
||||||
spotifyClientId: process.env.SPOTIFY_CLIENT_ID || '',
|
|
||||||
spotifyClientSecret: process.env.SPOTIFY_CLIENT_SECRET || '',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = CONFIG;
|
module.exports = CONFIG;
|
||||||
@@ -138,6 +138,6 @@ async function searchItunesAlbumTracks(artist, album) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sanitize, navidromeArtist,
|
sanitize, navidromeArtist,
|
||||||
downloadArtwork, AUDIO_EXTS, findExistingTrack,
|
downloadArtwork, findExistingTrack,
|
||||||
fetchLyrics, lookupItunesTrackMeta, fetchItunesTracks, searchItunesAlbumTracks,
|
fetchLyrics, lookupItunesTrackMeta, fetchItunesTracks, searchItunesAlbumTracks,
|
||||||
};
|
};
|
||||||
+10
-11
@@ -108,7 +108,6 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
const ytmUrl = `https://music.youtube.com/search?q=${encodeURIComponent(ytmQuery)}¶ms=${YTM_SONGS_PARAM}`;
|
const ytmUrl = `https://music.youtube.com/search?q=${encodeURIComponent(ytmQuery)}¶ms=${YTM_SONGS_PARAM}`;
|
||||||
const expectedAudio = path.join(dir, `${trackPrefix}${safeTitle}.${CONFIG.audioFmt}`);
|
const expectedAudio = path.join(dir, `${trackPrefix}${safeTitle}.${CONFIG.audioFmt}`);
|
||||||
const hasAudio = () => fs.existsSync(expectedAudio);
|
const hasAudio = () => fs.existsSync(expectedAudio);
|
||||||
const tryYtdlp = async (args) => { await spawnYtdlp(args); };
|
|
||||||
|
|
||||||
// Fetch YTM search result URLs as a flat list (no channel expansion) and return only
|
// Fetch YTM search result URLs as a flat list (no channel expansion) and return only
|
||||||
// actual video URLs (watch?v=…). This prevents yt-dlp from following an artist channel
|
// actual video URLs (watch?v=…). This prevents yt-dlp from following an artist channel
|
||||||
@@ -152,7 +151,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
const tryYtmSearch = async (maxItems, mfArgs) => {
|
const tryYtmSearch = async (maxItems, mfArgs) => {
|
||||||
const urls = await getYtmVideoUrls(maxItems);
|
const urls = await getYtmVideoUrls(maxItems);
|
||||||
if (!urls.length) return;
|
if (!urls.length) return;
|
||||||
await tryYtdlp([...urls, '--max-downloads', '1', ...mfArgs, ...baseArgs]);
|
await spawnYtdlp([...urls, '--max-downloads', '1', ...mfArgs, ...baseArgs]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const variantFilter = buildVariantFilter(title);
|
const variantFilter = buildVariantFilter(title);
|
||||||
@@ -189,7 +188,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 2. YT top-5 — strict: same filters including channel check
|
// 2. YT top-5 — strict: same filters including channel check
|
||||||
log(jobId, '⚠️ Kein YTM-Treffer — Fallback zu YouTube…');
|
log(jobId, '⚠️ Kein YTM-Treffer — Fallback zu YouTube…');
|
||||||
await tryYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(dur, true, true), ...baseArgs]);
|
await spawnYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(dur, true, true), ...baseArgs]);
|
||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 3. YTM top-10 — no channel check (label channels, etc.)
|
// 3. YTM top-10 — no channel check (label channels, etc.)
|
||||||
@@ -198,7 +197,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 4. YT top-10 — no channel check
|
// 4. YT top-10 — no channel check
|
||||||
await tryYtdlp([`ytsearch10:${query}`, ...PI_FILTERED_10, ...mf(dur, true), ...baseArgs]);
|
await spawnYtdlp([`ytsearch10:${query}`, ...PI_FILTERED_10, ...mf(dur, true), ...baseArgs]);
|
||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 5. YTM top-5 — no duration check
|
// 5. YTM top-5 — no duration check
|
||||||
@@ -207,7 +206,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 6. YT top-5 — no duration check
|
// 6. YT top-5 — no duration check
|
||||||
await tryYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, true), ...baseArgs]);
|
await spawnYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, true), ...baseArgs]);
|
||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 7. YTM top-5 — title only (no variant filter)
|
// 7. YTM top-5 — title only (no variant filter)
|
||||||
@@ -216,7 +215,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 8. YT top-5 — title only
|
// 8. YT top-5 — title only
|
||||||
await tryYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, false), ...baseArgs]);
|
await spawnYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, false), ...baseArgs]);
|
||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 9. YTM — no filter at all, take first video result
|
// 9. YTM — no filter at all, take first video result
|
||||||
@@ -225,7 +224,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 10. YT — no filter
|
// 10. YT — no filter
|
||||||
await tryYtdlp([`ytsearch1:${query}`, ...PI_UNFILTERED, ...baseArgs]);
|
await spawnYtdlp([`ytsearch1:${query}`, ...PI_UNFILTERED, ...baseArgs]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log(jobId, `🔍 Suche YT Music: "${query}"`);
|
log(jobId, `🔍 Suche YT Music: "${query}"`);
|
||||||
@@ -233,7 +232,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
await tryYtmSearch(5, mf(null, true, true));
|
await tryYtmSearch(5, mf(null, true, true));
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 2. YT top-5 — strict
|
// 2. YT top-5 — strict
|
||||||
await tryYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, true, true), ...baseArgs]);
|
await spawnYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, true, true), ...baseArgs]);
|
||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 3. YTM top-5 — no channel check
|
// 3. YTM top-5 — no channel check
|
||||||
@@ -241,7 +240,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 4. YT top-5 — no channel check
|
// 4. YT top-5 — no channel check
|
||||||
await tryYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, true), ...baseArgs]);
|
await spawnYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, true), ...baseArgs]);
|
||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 5. YTM top-5 — title only
|
// 5. YTM top-5 — title only
|
||||||
@@ -250,7 +249,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 6. YT top-5 — title only
|
// 6. YT top-5 — title only
|
||||||
await tryYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, false), ...baseArgs]);
|
await spawnYtdlp([`ytsearch5:${query}`, ...PI_FILTERED, ...mf(null, false), ...baseArgs]);
|
||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 7. YTM — first video result, no filter
|
// 7. YTM — first video result, no filter
|
||||||
@@ -259,7 +258,7 @@ async function downloadTrack({ jobId, artist, albumArtist, title, album, year, t
|
|||||||
}
|
}
|
||||||
if (!hasAudio()) {
|
if (!hasAudio()) {
|
||||||
// 8. YT — no filter
|
// 8. YT — no filter
|
||||||
await tryYtdlp([`ytsearch1:${query}`, ...PI_UNFILTERED, ...baseArgs]);
|
await spawnYtdlp([`ytsearch1:${query}`, ...PI_UNFILTERED, ...baseArgs]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -296,10 +296,6 @@ function _spAllArtists(artistsRaw) {
|
|||||||
return arr.map(a => a?.profile?.name || a?.name || '').filter(Boolean).join(', ');
|
return arr.map(a => a?.profile?.name || a?.name || '').filter(Boolean).join(', ');
|
||||||
}
|
}
|
||||||
|
|
||||||
function _spArtistName(artistsRaw) {
|
|
||||||
return _spAllArtists(artistsRaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _spTrackItem(t, defaultAlbum, defaultArt, defaultAlbumArtist) {
|
function _spTrackItem(t, defaultAlbum, defaultArt, defaultAlbumArtist) {
|
||||||
const trackName = t?.name || '';
|
const trackName = t?.name || '';
|
||||||
const artist = _spAllArtists(t?.artists) || defaultAlbumArtist || '';
|
const artist = _spAllArtists(t?.artists) || defaultAlbumArtist || '';
|
||||||
@@ -377,7 +373,7 @@ async function _resolveSpotifyViaSpotdl(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function _resolveSpotify(type, id, originalUrl) {
|
async function _resolveSpotify(type, id, originalUrl) {
|
||||||
// Primary: curl_cffi Chrome-impersonation + TOTP (no rate limit bucket as api keys)
|
// Primary: SpotipyFree (SpotAPI + tls_client Chrome fingerprint, Spotify internal endpoints)
|
||||||
try {
|
try {
|
||||||
console.log('[spotify] trying spotdl resolver');
|
console.log('[spotify] trying spotdl resolver');
|
||||||
return await _resolveSpotifyViaSpotdl(originalUrl);
|
return await _resolveSpotifyViaSpotdl(originalUrl);
|
||||||
@@ -391,7 +387,7 @@ async function _resolveSpotify(type, id, originalUrl) {
|
|||||||
|
|
||||||
if (type === 'track') {
|
if (type === 'track') {
|
||||||
const t = await _spApi(`/tracks/${id}`, token);
|
const t = await _spApi(`/tracks/${id}`, token);
|
||||||
const artist = _spArtistName(t.artists);
|
const artist = _spAllArtists(t.artists);
|
||||||
const artUrl = _spArtwork(t);
|
const artUrl = _spArtwork(t);
|
||||||
return { type: 'track', name: t.name || '', artist, artworkUrl: artUrl,
|
return { type: 'track', name: t.name || '', artist, artworkUrl: artUrl,
|
||||||
tracks: [_spTrackItem(t, t.album?.name, artUrl, artist)] };
|
tracks: [_spTrackItem(t, t.album?.name, artUrl, artist)] };
|
||||||
@@ -399,7 +395,7 @@ async function _resolveSpotify(type, id, originalUrl) {
|
|||||||
|
|
||||||
if (type === 'album') {
|
if (type === 'album') {
|
||||||
const album = await _spApi(`/albums/${id}`, token);
|
const album = await _spApi(`/albums/${id}`, token);
|
||||||
const artist = _spArtistName(album.artists);
|
const artist = _spAllArtists(album.artists);
|
||||||
const artUrl = _spArtwork(album);
|
const artUrl = _spArtwork(album);
|
||||||
const trackItems = await _spAllAlbumTracks(id, token);
|
const trackItems = await _spAllAlbumTracks(id, token);
|
||||||
return { type: 'album', name: album.name || '', artist, artworkUrl: artUrl,
|
return { type: 'album', name: album.name || '', artist, artworkUrl: artUrl,
|
||||||
|
|||||||
Reference in new issue
Block a user