mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-22 03:05:32 +02:00
feat(core+frontend): Spotify album/playlist capture via yt-dlp container path
Previously SpotifyAlbum and SpotifyPlaylist hard-failed with a DRM error.
yt-dlp does support Spotify (experimentally), so they now go through the
same probe/container/child path as YouTube playlists.
ytdlp.rs:
- Extract normalize_item_url() helper used by both fetch_playlist_info
and probe_playlist_qualities; eliminates the duplicate URL-normalization
blocks and the YouTube-specific fallback_host variable
- Fallback logic is now platform-aware: YouTube/YTM bare IDs → watch URL,
Spotify → open.spotify.com/track/{id}, unknown → skip with warning
capture.rs:
- locator_to_playlist_url: accept SpotifyAlbum | SpotifyPlaylist so the
probe-playlist endpoint accepts Spotify album/playlist URLs
- Container branch: add SpotifyAlbum | SpotifyPlaylist to the matches!
- is_audio: true for SpotifyAlbum | SpotifyPlaylist (audio-only, like YTM)
- child_source: SpotifyTrack for Spotify containers (not YouTubeMusicTrack)
- generate_entry_title and record_media_entry both use the correct child
source so entity_kind, source_kind, and representation_kind are right
CaptureDialog.jsx:
- isPlaylistSource: recognise open.spotify.com/album/ and /playlist/,
and spotify:album:ID / spotify:playlist:ID shorthands, so Spotify
containers get the probe UI, per-track excludes, and sync toggle
This commit is contained in:
parent
5e7ce4774b
commit
6a7826eba5
5 changed files with 82 additions and 71 deletions
|
|
@ -85,24 +85,28 @@ function isPlaylistSource(locator) {
|
|||
return ll.slice(4).startsWith('playlist/')
|
||||
}
|
||||
|
||||
// spotify: shorthands — album and playlist (not track)
|
||||
if (ll.startsWith('spotify:')) {
|
||||
const after = ll.slice(8)
|
||||
return after.startsWith('album:') || after.startsWith('playlist:')
|
||||
}
|
||||
|
||||
// HTTP/HTTPS URLs
|
||||
if (ll.startsWith('http://') || ll.startsWith('https://')) {
|
||||
try {
|
||||
const url = new URL(l)
|
||||
const host = url.hostname
|
||||
if (host === 'youtube.com' || host === 'www.youtube.com') {
|
||||
// Mirror determine_source exactly:
|
||||
// - /playlist?list=... → YouTubePlaylist
|
||||
// - /@handle, /channel/, /c/, /user/ → YouTubeChannel
|
||||
// - everything else (incl. /watch&list=, /shorts?list=) → NOT a playlist
|
||||
if (url.pathname === '/playlist' && url.searchParams.has('list')) return true
|
||||
if (url.pathname.startsWith('/@') || url.pathname.startsWith('/channel/') ||
|
||||
url.pathname.startsWith('/c/') || url.pathname.startsWith('/user/')) return true
|
||||
}
|
||||
if (host === 'music.youtube.com') {
|
||||
// /watch is a single YTM track; only /playlist?list=... is a YTM playlist
|
||||
if (url.pathname === '/playlist' && url.searchParams.has('list')) return true
|
||||
}
|
||||
if (host === 'open.spotify.com') {
|
||||
if (url.pathname.startsWith('/album/') || url.pathname.startsWith('/playlist/')) return true
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue