diff --git a/internal/playlist/navidrome.go b/internal/clients/navidrome/navidrome.go similarity index 98% rename from internal/playlist/navidrome.go rename to internal/clients/navidrome/navidrome.go index 41f92d0..21bb515 100644 --- a/internal/playlist/navidrome.go +++ b/internal/clients/navidrome/navidrome.go @@ -1,4 +1,4 @@ -package playlist +package navidrome import ( "bytes" @@ -25,7 +25,6 @@ type NavidromePlaylist struct { CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` CoverArtID string `json:"coverArtId"` - Tracks []NavidromePlaylistTrack `json:"-"` // populated by GetPlaylist } type NavidromeTrack struct { diff --git a/internal/playlist/spotify.go b/internal/clients/spotify/spotify.go similarity index 99% rename from internal/playlist/spotify.go rename to internal/clients/spotify/spotify.go index 015994b..958e683 100644 --- a/internal/playlist/spotify.go +++ b/internal/clients/spotify/spotify.go @@ -1,4 +1,4 @@ -package playlist +package spotify import ( "encoding/base64" diff --git a/internal/playlist/playlist.go b/internal/playlist/playlist.go deleted file mode 100644 index ae8ef54..0000000 --- a/internal/playlist/playlist.go +++ /dev/null @@ -1,2 +0,0 @@ -package playlist - diff --git a/internal/syncPlaylists.go b/internal/syncPlaylists.go index 722380e..0f5ae2f 100644 --- a/internal/syncPlaylists.go +++ b/internal/syncPlaylists.go @@ -2,28 +2,29 @@ package ripsort import ( "log/slog" - "os" "regexp" - "git.kapelle.org/niklas/ripsort/internal/playlist" + "git.kapelle.org/niklas/ripsort/internal/clients/navidrome" + "git.kapelle.org/niklas/ripsort/internal/clients/spotify" ) -func SyncPlaylists(spotifyClientID, spotifyClientSecret, navidromeBase, navidromeUser, navidromePass string) { - spotifyClient, err := playlist.NewSpotifyClient(spotifyClientID, spotifyClientSecret) +func SyncPlaylists(spotifyClientID, spotifyClientSecret, navidromeBase, navidromeUser, navidromePass string) error { + spotifyClient, err := spotify.NewSpotifyClient(spotifyClientID, spotifyClientSecret) if err != nil { slog.Error("Failed to create spotify client", "err", err) - os.Exit(1) + return err } - navidromeClient, err := playlist.NewNavidromeClient(navidromeBase, navidromeUser, navidromePass) + navidromeClient, err := navidrome.NewNavidromeClient(navidromeBase, navidromeUser, navidromePass) if err != nil { slog.Error("Failed to create navidrome client", "err", err) - os.Exit(1) + return err } allPlaylists, err := navidromeClient.GetPlaylists() for _, pl := range allPlaylists { + // Only sync playlists that have a spotify URL in the comment spotifyPlaylistID := spotifyIDForPlaylist(&pl) if spotifyPlaylistID == "" { continue @@ -31,15 +32,23 @@ func SyncPlaylists(spotifyClientID, spotifyClientSecret, navidromeBase, navidrom slog.Info("Syncing playlist", "name", pl.Name) - err = syncPlaylists(spotifyClient, navidromeClient, spotifyPlaylistID, pl.ID) + spotifyPlaylist, err := spotifyClient.GetPlaylist(spotifyPlaylistID) + if err != nil { + slog.Error("Failed to fetch spotify playlist", "id", spotifyPlaylistID) + return err + } + + err = syncPlaylists(navidromeClient, spotifyPlaylist, &pl) if err != nil { slog.Error("Failed to sync playlist", "name", pl.Name, "err", err) - os.Exit(1) + return err } } + + return nil } -func spotifyIDForPlaylist(playlist *playlist.NavidromePlaylist) string { +func spotifyIDForPlaylist(playlist *navidrome.NavidromePlaylist) string { var re = regexp.MustCompile(`(?m)https:\/\/open\.spotify\.com\/playlist\/([a-zA-Z0-9]*)`) matches := re.FindAllStringSubmatch(playlist.Comment, -1) @@ -50,13 +59,8 @@ func spotifyIDForPlaylist(playlist *playlist.NavidromePlaylist) string { return matches[0][1] } -func syncPlaylists(sp *playlist.SpotifyClient, nd *playlist.NavidromeClient, spotifyid string, navidromeID string) error { - spotifyPlaylist, err := sp.GetPlaylist(spotifyid) - if err != nil { - return err - } - - navidromeFullPlaylist, err := nd.GetPlaylist(navidromeID) +func syncPlaylists(nd *navidrome.NavidromeClient, spotifyPlaylist *spotify.SpotifyPlaylist, ndPlaylist *navidrome.NavidromePlaylist) error { + tracks, err := nd.GetPlaylistTracks(ndPlaylist.ID) if err != nil { return err } @@ -64,7 +68,7 @@ func syncPlaylists(sp *playlist.SpotifyClient, nd *playlist.NavidromeClient, spo songsToAdd := []string{} for _, spotifySong := range spotifyPlaylist.Items.Items { - if ndPlaylistContainsSong(navidromeFullPlaylist, spotifySong.Item.ID) { + if ndPlaylistContainsSong(tracks, spotifySong.Item.ID) { slog.Debug("Track already in playlist", "id", spotifySong.Item.ID) continue } @@ -91,8 +95,8 @@ func syncPlaylists(sp *playlist.SpotifyClient, nd *playlist.NavidromeClient, spo return nil } - slog.Info("Adding songs to playlist", "count", len(songsToAdd), "playlist", navidromeFullPlaylist.Name) - err = nd.AddTracks(navidromeID, songsToAdd) + slog.Info("Adding songs to playlist", "count", len(songsToAdd)) + err = nd.AddTracks(ndPlaylist.ID, songsToAdd) if err != nil { slog.Error("Failed to add songs", "err", err) } @@ -100,8 +104,8 @@ func syncPlaylists(sp *playlist.SpotifyClient, nd *playlist.NavidromeClient, spo return nil } -func ndPlaylistContainsSong(pl *playlist.NavidromePlaylist, spotifyID string) bool { - for _, song := range pl.Tracks { +func ndPlaylistContainsSong(tracks []navidrome.NavidromePlaylistTrack, spotifyID string) bool { + for _, song := range tracks { tag := song.CustomTags["spotifyid"] if tag == nil || len(tag) == 0 {