Merge branch 'dev-0.1.4' into 'master'

0.1.4

See merge request goscrobble/goscrobble-api!7
This commit is contained in:
Daniel Mason 2022-01-08 07:47:54 +00:00
commit 26880e3c2b
10 changed files with 106 additions and 21 deletions

View File

@ -2,7 +2,7 @@ stages:
- build - build
variables: variables:
VERSION: 0.1.3 VERSION: 0.1.4
build-go: build-go:
image: golang:1.17 image: golang:1.17

View File

@ -1,5 +1,9 @@
# 0.1.4
- Fix spotify image import on scrobble for new artists/albums
- Create image resizer
# 0.1.3 # 0.1.3
- - Added date ranges to profile scrobbles
# 0.1.2 # 0.1.2
- Add docker-compose file for local dev - Add docker-compose file for local dev

2
go.mod
View File

@ -4,6 +4,7 @@ go 1.17
require ( require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/disintegration/imaging v1.6.2
github.com/go-redis/redis/v8 v8.8.0 github.com/go-redis/redis/v8 v8.8.0
github.com/go-sql-driver/mysql v1.5.0 github.com/go-sql-driver/mysql v1.5.0
github.com/golang-migrate/migrate v3.5.4+incompatible github.com/golang-migrate/migrate v3.5.4+incompatible
@ -38,6 +39,7 @@ require (
go.opentelemetry.io/otel v0.19.0 // indirect go.opentelemetry.io/otel v0.19.0 // indirect
go.opentelemetry.io/otel/metric v0.19.0 // indirect go.opentelemetry.io/otel/metric v0.19.0 // indirect
go.opentelemetry.io/otel/trace v0.19.0 // indirect go.opentelemetry.io/otel/trace v0.19.0 // indirect
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3 // indirect google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3 // indirect

5
go.sum
View File

@ -52,6 +52,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible h1:iWPIG7pWIsCwT6ZtHnTUpoVMnete7O/pzd9HFE3+tn8= github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible h1:iWPIG7pWIsCwT6ZtHnTUpoVMnete7O/pzd9HFE3+tn8=
@ -220,6 +222,9 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=

View File

@ -62,8 +62,14 @@ func insertAlbum(name string, mbid string, spotifyId string, artists []string, i
if album.Img == "" { if album.Img == "" {
if img != "" { if img != "" {
album.Img = img err := importImage(album.UUID, img)
album.updateAlbum("img", img, tx) if err != nil {
log.Printf("Failed to import image: %+v. For Album: %s", err, album.Name)
return album, nil
}
album.Img = "pending"
_ = album.updateAlbum("img", "pending", tx)
} }
} }

View File

@ -72,8 +72,14 @@ func insertArtist(name string, mbid string, spotifyId string, img string, tx *sq
if artist.Img == "" { if artist.Img == "" {
if img != "" { if img != "" {
artist.Img = img err := importImage(artist.UUID, img)
artist.updateArtist("img", img, tx) if err != nil {
log.Printf("Failed to import image: %+v. For Album: %s", err, artist.Name)
return artist, nil
}
artist.Img = "pending"
_ = artist.updateArtist("img", "pending", tx)
} }
} }

View File

@ -3,8 +3,11 @@ package goscrobble
import ( import (
"fmt" "fmt"
"io" "io"
"log"
"net/http" "net/http"
"os" "os"
"github.com/disintegration/imaging"
) )
func importImage(uuid string, url string) error { func importImage(uuid string, url string) error {
@ -33,13 +36,67 @@ func importImage(uuid string, url string) error {
return err return err
} }
// Goroutine the resize to keep it _faaaast_
go resizeImage(uuid)
return nil return nil
} }
func resizeImage(uuid string) { func resizeImages() {
// resize to 300x300 and maybe smaller? resizeBulk("artists")
resizeBulk("albums")
}
func resizeBulk(recordType string) {
// Fetch pending 500 at a time cause we do it every minute anyway
rows, err := db.Query("SELECT BIN_TO_UUID(`uuid`, true) FROM `" + recordType + "` WHERE `img` = 'pending' LIMIT 500")
if err != nil {
log.Printf("Failed to get pending images: %+v", err)
return return
} }
// Fetch pending 100 at a time
for rows.Next() {
var uuid string
err := rows.Scan(&uuid)
if err != nil {
log.Printf("Failed to fetch record image resize: %+v", err)
rows.Close()
return
}
// Run the resize to 300px
success := resizeImage(uuid, 300)
if !success {
// If we get an error.. lets just remove the image link for now so it can reimport
_, err = db.Exec("UPDATE `"+recordType+"` SET `img` = NULL WHERE `uuid` = UUID_TO_BIN(?,true)", uuid)
} else {
// Update DB to reflect complete
_, err = db.Exec("UPDATE `"+recordType+"` SET `img` = 'complete' WHERE `uuid` = UUID_TO_BIN(?,true)", uuid)
}
}
rows.Close()
}
func resizeAlbums() {
}
func resizeImage(uuid string, size int) bool {
// Open source image
src, err := imaging.Open(DataDirectory + string(os.PathSeparator) + "img" + string(os.PathSeparator) + uuid + "_full.jpg")
if err != nil {
log.Printf("Failed to open image: %+v", err)
return false
}
// Resize image to specified size
resizedImage := imaging.Resize(src, size, size, imaging.Lanczos)
// Save resized image
err = imaging.Save(resizedImage, DataDirectory+string(os.PathSeparator)+"img"+string(os.PathSeparator)+uuid+"_300px.jpg")
if err != nil {
log.Printf("failed to save image: %v", err)
return false
}
return true
}

View File

@ -324,12 +324,14 @@ func (user *User) updateImageDataFromSpotify() {
for uuid, img := range toUpdate { for uuid, img := range toUpdate {
album, err = getAlbumByUUID(uuid) album, err = getAlbumByUUID(uuid)
err = importImage(uuid, img) err = importImage(uuid, img)
if err != nil { if err != nil {
continue continue
} }
// Update
_ = album.updateAlbum("img", "pending", tx) _ = album.updateAlbum("img", "pending", tx)
} }
tx.Commit() tx.Commit()
return return

View File

@ -821,7 +821,7 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) {
} }
info := ServerInfo{ info := ServerInfo{
Version: "0.1.3", Version: "0.1.4",
RegistrationEnabled: registrationEnabled, RegistrationEnabled: registrationEnabled,
} }

View File

@ -10,8 +10,8 @@ var endTicker chan bool
func StartBackgroundWorkers() { func StartBackgroundWorkers() {
endTicker := make(chan bool) endTicker := make(chan bool)
hourTicker := time.NewTicker(time.Duration(1) * time.Hour)
minuteTicker := time.NewTicker(time.Duration(60) * time.Second) minuteTicker := time.NewTicker(time.Duration(60) * time.Second)
hourTicker := time.NewTicker(time.Duration(1) * time.Hour)
go func() { go func() {
for { for {
@ -19,6 +19,15 @@ func StartBackgroundWorkers() {
case <-endTicker: case <-endTicker:
fmt.Println("Stopping background workers") fmt.Println("Stopping background workers")
return return
case <-minuteTicker.C:
// Update playdata from Spotify
go updateSpotifyData()
// Update playdate from Navidrome
go updateNavidromeData()
// There should only be whatever new images are in pending
go resizeImages()
case <-hourTicker.C: case <-hourTicker.C:
// Clear old password reset tokens // Clear old password reset tokens
go clearOldResetTokens() go clearOldResetTokens()
@ -26,12 +35,6 @@ func StartBackgroundWorkers() {
// Attempt to pull missing images from spotify - hackerino version! // Attempt to pull missing images from spotify - hackerino version!
user, _ := getUserByUsername("idanoo") user, _ := getUserByUsername("idanoo")
go user.updateImageDataFromSpotify() go user.updateImageDataFromSpotify()
case <-minuteTicker.C:
// Update playdata from Spotify
go updateSpotifyData()
// Update playdate from Navidrome
go updateNavidromeData()
} }
} }
}() }()