From a37efbf7e07843955c3fa1a979c5f248d46af44a Mon Sep 17 00:00:00 2001 From: Matt Gleich Date: Sun, 1 Dec 2024 17:40:34 -0500 Subject: [PATCH] feat: convert apple music to use shared request sender Signed-off-by: Matt Gleich --- internal/apis/applemusic/applemusic.go | 2 + internal/apis/applemusic/playlists.go | 42 +++++++++++++++---- internal/apis/applemusic/recent.go | 22 ++++++++-- .../apis/{applemusic/api.go => request.go} | 16 ++----- 4 files changed, 59 insertions(+), 23 deletions(-) rename internal/apis/{applemusic/api.go => request.go} (64%) diff --git a/internal/apis/applemusic/applemusic.go b/internal/apis/applemusic/applemusic.go index 4049e81..5dc5ce3 100644 --- a/internal/apis/applemusic/applemusic.go +++ b/internal/apis/applemusic/applemusic.go @@ -8,6 +8,8 @@ import ( "github.com/go-chi/chi/v5" ) +const API_ENDPOINT = "https://api.music.apple.com/" + type cacheData struct { RecentlyPlayed []song `json:"recently_played"` Playlists map[string]playlist `json:"playlists"` diff --git a/internal/apis/applemusic/playlists.go b/internal/apis/applemusic/playlists.go index b58755a..fe415e3 100644 --- a/internal/apis/applemusic/playlists.go +++ b/internal/apis/applemusic/playlists.go @@ -1,9 +1,11 @@ package applemusic import ( - "path" + "net/http" + "net/url" "time" + "github.com/gleich/lcp-v2/internal/apis" "github.com/gleich/lumber/v3" ) @@ -30,26 +32,50 @@ type playlistResponse struct { } func fetchPlaylist(id string) (playlist, error) { - playlistData, err := sendAPIRequest[playlistResponse](path.Join("v1/me/library/playlists/", id)) + u, err := url.JoinPath(API_ENDPOINT, "v1/me/library/playlist") + if err != nil { + lumber.Error(err, "failed to join urls") + return playlist{}, err + } + req, err := http.NewRequest("GET", u, nil) + if err != nil { + lumber.Error(err, "failed to make new request") + return playlist{}, err + } + playlistData, err := apis.SendRequest[playlistResponse](req) if err != nil { lumber.Error(err, "failed to fetch playlist for", id) return playlist{}, err } + u, err = url.JoinPath(API_ENDPOINT, "v1/me/library/playlists", id, "tracks") + if err != nil { + lumber.Error(err, "failed to join urls") + return playlist{}, err + } + req, err = http.NewRequest("GET", u, nil) + if err != nil { + lumber.Error(err, "failed to make new request") + return playlist{}, err + } + var totalResponseData []songResponse - trackData, err := sendAPIRequest[playlistTracksResponse]( - path.Join("v1/me/library/playlists/", id, "tracks"), - ) + trackData, err := apis.SendRequest[playlistTracksResponse](req) if err != nil { lumber.Error(err, "failed to get tracks for playlist with id of", id) - return playlist{}, nil + return playlist{}, err } totalResponseData = append(totalResponseData, trackData.Data...) for trackData.Next != "" { - trackData, err = sendAPIRequest[playlistTracksResponse](trackData.Next) + req, err := http.NewRequest("GET", trackData.Next, nil) + if err != nil { + lumber.Error(err, "failed to make request for paginated track data", trackData.Next) + return playlist{}, err + } + trackData, err = apis.SendRequest[playlistTracksResponse](req) if err != nil { lumber.Error(err, "failed to paginate through tracks for playlist with id of", id) - return playlist{}, nil + return playlist{}, err } } diff --git a/internal/apis/applemusic/recent.go b/internal/apis/applemusic/recent.go index ac56542..56e9aa9 100644 --- a/internal/apis/applemusic/recent.go +++ b/internal/apis/applemusic/recent.go @@ -1,13 +1,29 @@ package applemusic +import ( + "net/http" + "net/url" + + "github.com/gleich/lcp-v2/internal/apis" + "github.com/gleich/lumber/v3" +) + type recentlyPlayedResponse struct { Data []songResponse `json:"data"` } func fetchRecentlyPlayed() ([]song, error) { - response, err := sendAPIRequest[recentlyPlayedResponse]( - "v1/me/recent/played/tracks", - ) + u, err := url.JoinPath(API_ENDPOINT, "v1/me/recent/played/tracks") + if err != nil { + lumber.Error(err, "failed to create URl") + return []song{}, err + } + req, err := http.NewRequest("GET", u, nil) + if err != nil { + lumber.Error(err, "failed to create request") + return []song{}, err + } + response, err := apis.SendRequest[recentlyPlayedResponse](req) if err != nil { return []song{}, err } diff --git a/internal/apis/applemusic/api.go b/internal/apis/request.go similarity index 64% rename from internal/apis/applemusic/api.go rename to internal/apis/request.go index 69c489d..c79f714 100644 --- a/internal/apis/applemusic/api.go +++ b/internal/apis/request.go @@ -1,4 +1,4 @@ -package applemusic +package apis import ( "encoding/json" @@ -6,20 +6,12 @@ import ( "io" "net/http" - "github.com/gleich/lcp-v2/internal/secrets" "github.com/gleich/lumber/v3" ) -func sendAPIRequest[T any](endpoint string) (T, error) { +// sends a given http.Request and will unmarshal the JSON from the response body and return that as the given type. +func SendRequest[T any](req *http.Request) (T, error) { var zeroValue T // to be used as "nil" when returning errors - req, err := http.NewRequest("GET", "https://api.music.apple.com/"+endpoint, nil) - if err != nil { - lumber.Error(err, "creating request failed") - return zeroValue, err - } - req.Header.Set("Authorization", "Bearer "+secrets.SECRETS.AppleMusicAppToken) - req.Header.Set("Music-User-Token", secrets.SECRETS.AppleMusicUserToken) - resp, err := http.DefaultClient.Do(req) if err != nil { lumber.Error(err, "sending request failed") @@ -34,7 +26,7 @@ func sendAPIRequest[T any](endpoint string) (T, error) { } if resp.StatusCode != http.StatusOK { err = fmt.Errorf( - "status code of %d returned from apple music API. Code of 200 expected", + "status code of %d returned from API. Code of 200 expected", resp.StatusCode, ) if resp.StatusCode == http.StatusBadGateway ||