From 9b05201fdfcedab71687da968e205085b78ca59e Mon Sep 17 00:00:00 2001 From: Daniel Mason Date: Sat, 26 Feb 2022 12:16:45 +1300 Subject: [PATCH] 0.1.8 - Add list of tracks on artist/album pages --- .gitlab-ci.yml | 2 +- docs/changelog.md | 3 ++ internal/goscrobble/server.go | 54 +++++++++++++++++++++++++- internal/goscrobble/track.go | 73 ++++++++++++++++++++++++++++++++++- 4 files changed, 129 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 75d97685..788aff37 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ stages: - build variables: - VERSION: 0.1.7 + VERSION: 0.1.8 build-go: image: golang:1.17 diff --git a/docs/changelog.md b/docs/changelog.md index 552f009b..dd7ee022 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,6 @@ +# 0.1.8 +- Add list of tracks on artist/album pages + # 0.1.7 - Fix navidrome logging 2x scrobbles if second player is paused - Fix jellyfin logging 2x scrobbles if 2 players are playing diff --git a/internal/goscrobble/server.go b/internal/goscrobble/server.go index f5cd09dc..bfe6bd15 100644 --- a/internal/goscrobble/server.go +++ b/internal/goscrobble/server.go @@ -89,6 +89,8 @@ func HandleRequests(port string) { v1.HandleFunc("/tracks/top/{uuid}/{days:[0-9]+}", limitMiddleware(getTracks, lightLimiter)).Methods("GET") // User UUID - Top Tracks (With Date) v1.HandleFunc("/tracks/{uuid}", limitMiddleware(getTrack, lightLimiter)).Methods("GET") // Track UUID v1.HandleFunc("/tracks/{uuid}/top", limitMiddleware(getTopUsersForTrack, lightLimiter)).Methods("GET") // TrackUUID - Top Listeners + v1.HandleFunc("/tracks/artist/{uuid}", limitMiddleware(getTracksForArtist, lightLimiter)).Methods("GET") // ArtistUUID - All tracks + v1.HandleFunc("/tracks/album/{uuid}", limitMiddleware(getTracksForAlbum, lightLimiter)).Methods("GET") // AlbumUUID - All tracks v1.HandleFunc("/albums/{uuid}", limitMiddleware(getAlbum, lightLimiter)).Methods("GET") v1.HandleFunc("/albums/{uuid}/top", limitMiddleware(getTopUsersForAlbum, lightLimiter)).Methods("GET") @@ -653,6 +655,56 @@ func getTracks(w http.ResponseWriter, r *http.Request) { w.Write(json) } +// getTracksForArtist - Returns track data for an artist +func getTracksForArtist(w http.ResponseWriter, r *http.Request) { + var uuid string + for k, v := range mux.Vars(r) { + if k == "uuid" { + uuid = v + } + } + + if uuid == "" { + throwOkError(w, "Invalid UUID") + return + } + + track, err := getAllTracksForArtist(uuid) + if err != nil { + throwOkError(w, err.Error()) + return + } + + json, _ := json.Marshal(&track) + w.WriteHeader(http.StatusOK) + w.Write(json) +} + +// getTracksForAlbum - Returns track data for an album +func getTracksForAlbum(w http.ResponseWriter, r *http.Request) { + var uuid string + for k, v := range mux.Vars(r) { + if k == "uuid" { + uuid = v + } + } + + if uuid == "" { + throwOkError(w, "Invalid UUID") + return + } + + track, err := getAllTracksForAlbum(uuid) + if err != nil { + throwOkError(w, err.Error()) + return + } + + json, _ := json.Marshal(&track) + w.WriteHeader(http.StatusOK) + w.Write(json) +} + // getTopUsersForTrack - I suck at naming. Returns top users that have scrobbled this track. func getTopUsersForTrack(w http.ResponseWriter, r *http.Request) { var uuid string @@ -825,7 +877,7 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) { } info := ServerInfo{ - Version: "0.1.7", + Version: "0.1.8", RegistrationEnabled: registrationEnabled, } diff --git a/internal/goscrobble/track.go b/internal/goscrobble/track.go index 898037eb..0fea31f5 100644 --- a/internal/goscrobble/track.go +++ b/internal/goscrobble/track.go @@ -104,7 +104,6 @@ func getTrackWithArtists(name string, artists []string, album string, tx *sql.Tx "WHERE `name` = ? AND BIN_TO_UUID(`track_artist`.`artist`, true) IN ('"+artistString+"') "+ "AND BIN_TO_UUID(`track_album`.`album`,true) = ? LIMIT 1", name, album).Scan(&track.UUID, &track.Name, &track.Desc, &track.Img, &track.MusicBrainzID) - if err != nil { if err != sql.ErrNoRows { log.Printf("Error fetching tracks: %+v", err) @@ -114,6 +113,78 @@ func getTrackWithArtists(name string, artists []string, album string, tx *sql.Tx return track } +// getAllTracksForAlbum - return all album tracks! +func getAllTracksForAlbum(uuid string) (TopTracks, error) { + var topTracks TopTracks + + rows, err := db.Query("SELECT BIN_TO_UUID(`tracks`.`uuid`, true), `tracks`.`name` "+ + "FROM `albums` "+ + "JOIN `track_album` ON `track_album`.`album` = `albums`.`uuid` "+ + "JOIN `tracks` ON `tracks`.`uuid` = `track_album`.`track` "+ + "WHERE albums.uuid = UUID_TO_BIN(?, true)", uuid) + + if err != nil { + log.Printf("Failed to fetch top tracks: %+v", err) + return topTracks, errors.New("Failed to fetch top tracks") + } + defer rows.Close() + + i := 1 + tempTracks := make(map[int]TopTrack) + + for rows.Next() { + var track TopTrack + err := rows.Scan(&track.UUID, &track.Name) + if err != nil { + log.Printf("Failed to fetch track: %+v", err) + return topTracks, errors.New("Failed to fetch track") + } + + tempTracks[i] = track + i++ + } + + topTracks.Tracks = tempTracks + + return topTracks, nil +} + +// getAllTracksForArtist - return all album tracks! +func getAllTracksForArtist(uuid string) (TopTracks, error) { + var topTracks TopTracks + + rows, err := db.Query("SELECT BIN_TO_UUID(`tracks`.`uuid`, true), `tracks`.`name` "+ + "FROM `artists` "+ + "JOIN `track_artist` ON `track_artist`.`artist` = `artists`.`uuid` "+ + "JOIN `tracks` ON `tracks`.`uuid` = `track_artist`.`track` "+ + "WHERE artists.uuid = UUID_TO_BIN(?,true)", uuid) + + if err != nil { + log.Printf("Failed to fetch top tracks: %+v", err) + return topTracks, errors.New("Failed to fetch top tracks") + } + defer rows.Close() + + i := 1 + tempTracks := make(map[int]TopTrack) + + for rows.Next() { + var track TopTrack + err := rows.Scan(&track.UUID, &track.Name) + if err != nil { + log.Printf("Failed to fetch track: %+v", err) + return topTracks, errors.New("Failed to fetch track") + } + + tempTracks[i] = track + i++ + } + + topTracks.Tracks = tempTracks + + return topTracks, nil +} + func insertNewTrack(track *Track, name string, length int, mbid string, spotifyId string, tx *sql.Tx) error { track.UUID = newUUID() track.Name = name