mirror of
https://git.sr.ht/~joren/streamrip-go
synced 2026-06-17 15:05:39 +02:00
improve CLI error semantics and soundcloud canonicalization
Auto-upgrade outdated configs on startup, add actionable SSL verification hints in rip error paths, and harden SoundCloud search/metadata with canonical URL handling and richer source IDs.
This commit is contained in:
@@ -36,6 +36,11 @@ type Main struct {
|
||||
Media []media.Media
|
||||
}
|
||||
|
||||
type PlaylistTrackRef struct {
|
||||
Source string
|
||||
ID string
|
||||
}
|
||||
|
||||
type ripTrackOptions struct {
|
||||
albumFolder string
|
||||
albumEmbedCover string
|
||||
@@ -219,6 +224,37 @@ func (m *Main) AddPlaylistByTrackIDs(ctx context.Context, source, playlistID, pl
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Main) AddMixedPlaylistByTrackRefs(ctx context.Context, playlistID, playlistName string, refs []PlaylistTrackRef) error {
|
||||
if strings.TrimSpace(playlistName) == "" {
|
||||
playlistName = playlistID
|
||||
}
|
||||
valid := make([]PlaylistTrackRef, 0, len(refs))
|
||||
for _, ref := range refs {
|
||||
source := strings.TrimSpace(ref.Source)
|
||||
id := strings.TrimSpace(ref.ID)
|
||||
if source == "" || id == "" {
|
||||
continue
|
||||
}
|
||||
valid = append(valid, PlaylistTrackRef{Source: source, ID: id})
|
||||
}
|
||||
if len(valid) == 0 {
|
||||
return fmt.Errorf("playlist %q has no track refs", playlistName)
|
||||
}
|
||||
|
||||
pending := media.PendingFunc{
|
||||
ResolveFn: func(context.Context) (media.Media, error) {
|
||||
return media.MediaFunc{RipFn: func(ctx context.Context) error {
|
||||
if m.Config.Session.CLI.TextOutput {
|
||||
m.logf("Downloading playlist: %s\n", playlistName)
|
||||
}
|
||||
return m.ripPlaylistMixed(ctx, playlistID, playlistName, valid)
|
||||
}}, nil
|
||||
},
|
||||
}
|
||||
m.Pending = append(m.Pending, pending)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Main) ripCollection(ctx context.Context, p provider.Client, source, kind, id string, meta map[string]any) error {
|
||||
name := titleFromMetadata(meta, id)
|
||||
if n := stringFromAny(meta["name"]); n != "" {
|
||||
@@ -679,6 +715,56 @@ func (m *Main) ripPlaylist(ctx context.Context, p provider.Client, source, playl
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Main) ripPlaylistMixed(ctx context.Context, playlistID, name string, refs []PlaylistTrackRef) error {
|
||||
folder := filepath.Join(m.Config.Session.Downloads.Folder, naming.CleanName(name, naming.Config{
|
||||
RestrictCharacters: m.Config.Session.Filepaths.RestrictCharacters,
|
||||
TruncateTo: m.Config.Session.Filepaths.TruncateTo,
|
||||
}))
|
||||
|
||||
total := len(refs)
|
||||
m.logf("Playlist: %s (%d tracks)\n", name, total)
|
||||
failures := 0
|
||||
|
||||
providerCache := map[string]provider.Client{}
|
||||
getProvider := func(source string) (provider.Client, error) {
|
||||
if p, ok := providerCache[source]; ok {
|
||||
return p, nil
|
||||
}
|
||||
p, err := m.GetLoggedInProvider(ctx, source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
providerCache[source] = p
|
||||
return p, nil
|
||||
}
|
||||
|
||||
for i, ref := range refs {
|
||||
p, err := getProvider(ref.Source)
|
||||
if err != nil {
|
||||
failures++
|
||||
m.logf("track failed: id=%s source=%s reason=%v\n", ref.ID, ref.Source, err)
|
||||
continue
|
||||
}
|
||||
opts := ripTrackOptions{
|
||||
albumFolder: folder,
|
||||
index: i + 1,
|
||||
total: total,
|
||||
forPlaylist: true,
|
||||
playlistName: name,
|
||||
playlistPos: i + 1,
|
||||
}
|
||||
if err = m.ripTrack(ctx, p, ref.Source, ref.ID, "", opts); err != nil {
|
||||
failures++
|
||||
m.logf("track failed: id=%s source=%s reason=%v\n", ref.ID, ref.Source, err)
|
||||
}
|
||||
}
|
||||
|
||||
if failures > 0 {
|
||||
m.logf("Playlist done with %d failed track(s)\n", failures)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Main) ripTrack(ctx context.Context, p provider.Client, source, id, fallbackTitle string, opts ripTrackOptions) error {
|
||||
alreadyDownloaded, err := m.Store.IsDownloaded(ctx, source, id)
|
||||
if err == nil && alreadyDownloaded {
|
||||
|
||||
Reference in New Issue
Block a user