diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dfbbf278..d3a416b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,7 +3,7 @@ stages: - bundle variables: - VERSION: 0.0.23 + VERSION: 0.0.24 build-go: image: golang:1.16.2 diff --git a/docs/changelog.md b/docs/changelog.md index 0b6cd3b5..47bcdadc 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,7 @@ +# 0.0.24 +- Spotify will now add images on scrobble +- Renamed /api/v1/track to tracks to bypass blocklists... (uBlock :() + # 0.0.23 - Get top tracks pulling correctly :) diff --git a/internal/goscrobble/album.go b/internal/goscrobble/album.go index 31274988..ab93dfb9 100644 --- a/internal/goscrobble/album.go +++ b/internal/goscrobble/album.go @@ -16,7 +16,7 @@ type Album struct { } // insertAlbum - This will return if it exists or create it based on MBID > Name -func insertAlbum(name string, mbid string, spotifyId string, artists []string, tx *sql.Tx) (Album, error) { +func insertAlbum(name string, mbid string, spotifyId string, artists []string, img string, tx *sql.Tx) (Album, error) { album := Album{} // Try locate our album @@ -33,7 +33,7 @@ func insertAlbum(name string, mbid string, spotifyId string, artists []string, t // If we can't find it. Lets add it! if album.UUID == "" { - err := insertNewAlbum(&album, name, mbid, spotifyId, tx) + err := insertNewAlbum(&album, name, mbid, spotifyId, img, tx) if err != nil { return album, errors.New("Failed to insert album") } @@ -60,6 +60,13 @@ func insertAlbum(name string, mbid string, spotifyId string, artists []string, t album.updateAlbum("spotify_id", spotifyId, tx) } + if album.Img == "" { + if img != "" { + album.Img = img + album.updateAlbum("img", img, tx) + } + } + return album, nil } @@ -78,14 +85,15 @@ func getAlbumByCol(col string, val string, tx *sql.Tx) Album { return album } -func insertNewAlbum(album *Album, name string, mbid string, spotifyId string, tx *sql.Tx) error { +func insertNewAlbum(album *Album, name string, mbid string, spotifyId string, img string, tx *sql.Tx) error { album.UUID = newUUID() album.Name = name album.MusicBrainzID = mbid album.SpotifyID = spotifyId + album.Img = img - _, err := tx.Exec("INSERT INTO `albums` (`uuid`, `name`, `mbid`, `spotify_id`) "+ - "VALUES (UUID_TO_BIN(?, true),?,?,?)", album.UUID, album.Name, album.MusicBrainzID, album.SpotifyID) + _, err := tx.Exec("INSERT INTO `albums` (`uuid`, `name`, `mbid`, `spotify_id`, `img`) "+ + "VALUES (UUID_TO_BIN(?, true),?,?,?,?)", album.UUID, album.Name, album.MusicBrainzID, album.SpotifyID, album.Img) return err } diff --git a/internal/goscrobble/artist.go b/internal/goscrobble/artist.go index 9349d60f..e29b0a59 100644 --- a/internal/goscrobble/artist.go +++ b/internal/goscrobble/artist.go @@ -16,7 +16,7 @@ type Artist struct { } // insertArtist - This will return if it exists or create it based on MBID > Name -func insertArtist(name string, mbid string, spotifyId string, tx *sql.Tx) (Artist, error) { +func insertArtist(name string, mbid string, spotifyId string, img string, tx *sql.Tx) (Artist, error) { artist := Artist{} // Try locate our artist @@ -33,7 +33,7 @@ func insertArtist(name string, mbid string, spotifyId string, tx *sql.Tx) (Artis // If we can't find it. Lets add it! if artist.UUID == "" { - err := insertNewArtist(&artist, name, mbid, spotifyId, tx) + err := insertNewArtist(&artist, name, mbid, spotifyId, img, tx) if err != nil { log.Printf("Error inserting artist: %+v", err) return artist, errors.New("Failed to insert artist") @@ -44,7 +44,7 @@ func insertArtist(name string, mbid string, spotifyId string, tx *sql.Tx) (Artis } } - // Updates these values if we match earlier!M + // Updates these values if we have the data! if artist.MusicBrainzID == "" { if artist.MusicBrainzID != mbid { artist.MusicBrainzID = mbid @@ -59,6 +59,13 @@ func insertArtist(name string, mbid string, spotifyId string, tx *sql.Tx) (Artis } } + if artist.Img == "" { + if img != "" { + artist.Img = img + artist.updateArtist("img", img, tx) + } + } + return artist, nil } @@ -77,14 +84,15 @@ func getArtistByCol(col string, val string, tx *sql.Tx) Artist { return artist } -func insertNewArtist(artist *Artist, name string, mbid string, spotifyId string, tx *sql.Tx) error { +func insertNewArtist(artist *Artist, name string, mbid string, spotifyId string, img string, tx *sql.Tx) error { artist.UUID = newUUID() artist.Name = name artist.MusicBrainzID = mbid artist.SpotifyID = spotifyId + artist.Img = img - _, err := tx.Exec("INSERT INTO `artists` (`uuid`, `name`, `mbid`, `spotify_id`) "+ - "VALUES (UUID_TO_BIN(?, true),?,?,?)", artist.UUID, artist.Name, artist.MusicBrainzID, artist.SpotifyID) + _, err := tx.Exec("INSERT INTO `artists` (`uuid`, `name`, `mbid`, `spotify_id`, `img`) "+ + "VALUES (UUID_TO_BIN(?, true),?,?,?,?)", artist.UUID, artist.Name, artist.MusicBrainzID, artist.SpotifyID, artist.Img) return err } diff --git a/internal/goscrobble/ingress_jellyfin.go b/internal/goscrobble/ingress_jellyfin.go index 3121b4fd..89cc4e22 100644 --- a/internal/goscrobble/ingress_jellyfin.go +++ b/internal/goscrobble/ingress_jellyfin.go @@ -72,7 +72,7 @@ func ParseJellyfinInput(userUUID string, jf JellyfinRequest, ip net.IP, tx *sql. } // Insert artist if not exist - artist, err := insertArtist(jf.Artist, jf.ProviderMusicbrainzartist, "", tx) + artist, err := insertArtist(jf.Artist, jf.ProviderMusicbrainzartist, "", "", tx) if err != nil { log.Printf("%+v", err) return errors.New("Failed to map artist") @@ -80,7 +80,7 @@ func ParseJellyfinInput(userUUID string, jf JellyfinRequest, ip net.IP, tx *sql. // Insert album if not exist artists := []string{artist.UUID} - album, err := insertAlbum(jf.Album, jf.ProviderMusicbrainzalbum, "", artists, tx) + album, err := insertAlbum(jf.Album, jf.ProviderMusicbrainzalbum, "", artists, "", tx) if err != nil { log.Printf("%+v", err) return errors.New("Failed to map album") diff --git a/internal/goscrobble/ingress_multiscrobbler.go b/internal/goscrobble/ingress_multiscrobbler.go index 91fa45ef..9fe205e1 100644 --- a/internal/goscrobble/ingress_multiscrobbler.go +++ b/internal/goscrobble/ingress_multiscrobbler.go @@ -32,7 +32,7 @@ func ParseMultiScrobblerInput(userUUID string, data MultiScrobblerRequest, ip ne // Insert track artists for _, artist := range data.Artists { - artist, err := insertArtist(artist, "", "", tx) + artist, err := insertArtist(artist, "", "", "", tx) if err != nil { log.Printf("%+v", err) @@ -42,7 +42,7 @@ func ParseMultiScrobblerInput(userUUID string, data MultiScrobblerRequest, ip ne } // Insert album if not exist - album, err := insertAlbum(data.Album, "", "", albumartists, tx) + album, err := insertAlbum(data.Album, "", "", albumartists, "", tx) if err != nil { log.Printf("%+v", err) return errors.New("Failed to map album") diff --git a/internal/goscrobble/ingress_spotify.go b/internal/goscrobble/ingress_spotify.go index 14c0f5d1..e549ee0e 100644 --- a/internal/goscrobble/ingress_spotify.go +++ b/internal/goscrobble/ingress_spotify.go @@ -145,7 +145,13 @@ func ParseSpotifyInput(userUUID string, data spotify.RecentlyPlayedItem, client // Insert track artists for _, artist := range data.Track.Artists { - artist, err := insertArtist(artist.Name, "", artist.ID.String(), tx) + fullArtist, err := client.GetArtist(artist.ID) + img := "" + if len(fullArtist.Images) > 0 { + img = fullArtist.Images[0].URL + } + + artist, err := insertArtist(artist.Name, "", artist.ID.String(), img, tx) if err != nil { log.Printf("%+v", err) @@ -163,7 +169,13 @@ func ParseSpotifyInput(userUUID string, data spotify.RecentlyPlayedItem, client // Insert album artists for _, artist := range fulltrack.Album.Artists { - albumartist, err := insertArtist(artist.Name, "", artist.ID.String(), tx) + fullArtist, err := client.GetArtist(artist.ID) + img := "" + if len(fullArtist.Images) > 0 { + img = fullArtist.Images[0].URL + } + + albumartist, err := insertArtist(artist.Name, "", artist.ID.String(), img, tx) if err != nil { log.Printf("%+v", err) @@ -173,7 +185,11 @@ func ParseSpotifyInput(userUUID string, data spotify.RecentlyPlayedItem, client } // Insert album if not exist - album, err := insertAlbum(fulltrack.Album.Name, "", fulltrack.Album.ID.String(), albumartists, tx) + albumImage := "" + if len(fulltrack.Album.Images) > 0 { + albumImage = fulltrack.Album.Images[0].URL + } + album, err := insertAlbum(fulltrack.Album.Name, "", fulltrack.Album.ID.String(), albumartists, albumImage, tx) if err != nil { log.Printf("%+v", err) return errors.New("Failed to map album") @@ -197,3 +213,7 @@ func ParseSpotifyInput(userUUID string, data spotify.RecentlyPlayedItem, client return nil } + +func (track *Track) updateImageFromSpotify() error { + return nil +} diff --git a/internal/goscrobble/server.go b/internal/goscrobble/server.go index 8085e23d..460eca3b 100644 --- a/internal/goscrobble/server.go +++ b/internal/goscrobble/server.go @@ -50,12 +50,12 @@ func HandleRequests(port string) { // No Auth v1.HandleFunc("/stats", limitMiddleware(handleStats, lightLimiter)).Methods("GET") v1.HandleFunc("/profile/{username}", limitMiddleware(getProfile, lightLimiter)).Methods("GET") - v1.HandleFunc("/artist/top/{uuid}", limitMiddleware(getArtists, lightLimiter)).Methods("GET") - v1.HandleFunc("/artist/{uuid}", limitMiddleware(getArtist, lightLimiter)).Methods("GET") - v1.HandleFunc("/album/top/{uuid}", limitMiddleware(getArtists, lightLimiter)).Methods("GET") - v1.HandleFunc("/album/{uuid}", limitMiddleware(getAlbum, lightLimiter)).Methods("GET") - v1.HandleFunc("/track/top/{uuid}", limitMiddleware(getTracks, lightLimiter)).Methods("GET") - v1.HandleFunc("/track/{uuid}", limitMiddleware(getTrack, lightLimiter)).Methods("GET") + v1.HandleFunc("/artists/top/{uuid}", limitMiddleware(getArtists, lightLimiter)).Methods("GET") + v1.HandleFunc("/artists/{uuid}", limitMiddleware(getArtist, lightLimiter)).Methods("GET") + v1.HandleFunc("/albums/top/{uuid}", limitMiddleware(getArtists, lightLimiter)).Methods("GET") + v1.HandleFunc("/albums/{uuid}", limitMiddleware(getAlbum, lightLimiter)).Methods("GET") + v1.HandleFunc("/tracks/top/{uuid}", limitMiddleware(getTracks, lightLimiter)).Methods("GET") + v1.HandleFunc("/tracks/{uuid}", limitMiddleware(getTrack, lightLimiter)).Methods("GET") v1.HandleFunc("/register", limitMiddleware(handleRegister, heavyLimiter)).Methods("POST") v1.HandleFunc("/login", limitMiddleware(handleLogin, standardLimiter)).Methods("POST") @@ -665,7 +665,7 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) { } info := ServerInfo{ - Version: "0.0.23", + Version: "0.0.24", RegistrationEnabled: cachedRegistrationEnabled, } diff --git a/internal/goscrobble/timers.go b/internal/goscrobble/timers.go index 52b67b70..e2d74906 100644 --- a/internal/goscrobble/timers.go +++ b/internal/goscrobble/timers.go @@ -13,7 +13,7 @@ func StartBackgroundWorkers() { endTicker := make(chan bool) hourTicker := time.NewTicker(time.Hour) - minuteTicker := time.NewTicker(time.Duration(1) * time.Minute) + minuteTicker := time.NewTicker(time.Duration(60) * time.Second) go func() { for { diff --git a/web/src/Api/index.js b/web/src/Api/index.js index c84184c0..5e8ee6ce 100644 --- a/web/src/Api/index.js +++ b/web/src/Api/index.js @@ -292,7 +292,7 @@ export const getServerInfo = () => { } export const getArtist = (uuid) => { - return axios.get(process.env.REACT_APP_API_URL + "artist/" + uuid).then( + return axios.get(process.env.REACT_APP_API_URL + "artists/" + uuid).then( (data) => { return data.data; }).catch((error) => { @@ -301,7 +301,7 @@ export const getArtist = (uuid) => { }; export const getAlbum = (uuid) => { - return axios.get(process.env.REACT_APP_API_URL + "album/" + uuid).then( + return axios.get(process.env.REACT_APP_API_URL + "albums/" + uuid).then( (data) => { return data.data; }).catch((error) => { @@ -310,7 +310,7 @@ export const getAlbum = (uuid) => { }; export const getTrack = (uuid) => { - return axios.get(process.env.REACT_APP_API_URL + "track/" + uuid).then( + return axios.get(process.env.REACT_APP_API_URL + "tracks/" + uuid).then( (data) => { return data.data; }).catch((error) => { @@ -319,7 +319,7 @@ export const getTrack = (uuid) => { }; export const getTopTracks = (uuid) => { - return axios.get(process.env.REACT_APP_API_URL + "track/top/" + uuid).then( + return axios.get(process.env.REACT_APP_API_URL + "tracks/top/" + uuid).then( (data) => { return data.data; }).catch((error) => {