From cb6b33a9fb69589bf73e33773c6f16bf073ce865 Mon Sep 17 00:00:00 2001 From: Zach Myers Date: Mon, 20 Dec 2021 15:46:21 -0500 Subject: [PATCH] feat: render local artist images for getArtistInfo2 --- .gitignore | 1 + server/ctrladmin/handlers.go | 22 +------- server/ctrlbase/ctrl.go | 24 +++++++++ server/ctrlsubsonic/handlers_by_tags.go | 71 +++++++++++++++++++------ server/scanner/scanner.go | 3 +- 5 files changed, 83 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index 7fa87c80..f9424e8c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ dist gonic gonicscan gonicembed +.vscode \ No newline at end of file diff --git a/server/ctrladmin/handlers.go b/server/ctrladmin/handlers.go index 529628a2..af25b090 100644 --- a/server/ctrladmin/handlers.go +++ b/server/ctrladmin/handlers.go @@ -16,15 +16,6 @@ import ( "go.senan.xyz/gonic/server/scrobble/listenbrainz" ) -func firstExisting(or string, strings ...string) string { - for _, s := range strings { - if s != "" { - return s - } - } - return or -} - func doScan(scanner *scanner.Scanner, opts scanner.ScanOptions) { go func() { if err := scanner.ScanAndClean(opts); err != nil { @@ -48,18 +39,7 @@ func (c *Controller) ServeHome(r *http.Request) *Response { c.DB.Model(&db.Album{}).Count(&data.AlbumCount) c.DB.Table("tracks").Count(&data.TrackCount) // lastfm box - scheme := firstExisting( - "http", // fallback - r.Header.Get("X-Forwarded-Proto"), - r.Header.Get("X-Forwarded-Scheme"), - r.URL.Scheme, - ) - host := firstExisting( - "localhost:4747", // fallback - r.Header.Get("X-Forwarded-Host"), - r.Host, - ) - data.RequestRoot = fmt.Sprintf("%s://%s", scheme, host) + data.RequestRoot = c.BaseURL(r) data.CurrentLastFMAPIKey, _ = c.DB.GetSetting("lastfm_api_key") data.DefaultListenBrainzURL = listenbrainz.BaseURL // users box diff --git a/server/ctrlbase/ctrl.go b/server/ctrlbase/ctrl.go index a2f91c14..59841cb9 100644 --- a/server/ctrlbase/ctrl.go +++ b/server/ctrlbase/ctrl.go @@ -55,6 +55,21 @@ func (c *Controller) Path(rel string) string { return path.Join(c.ProxyPrefix, rel) } +func (c *Controller) BaseURL(r *http.Request) string { + scheme := firstExisting( + "http", // fallback + r.Header.Get("X-Forwarded-Proto"), + r.Header.Get("X-Forwarded-Scheme"), + r.URL.Scheme, + ) + host := firstExisting( + "localhost:4747", // fallback + r.Header.Get("X-Forwarded-Host"), + r.Host, + ) + return fmt.Sprintf("%s://%s", scheme, host) +} + func (c *Controller) WithLogging(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // this is (should be) the first middleware. pass right though it @@ -87,3 +102,12 @@ func (c *Controller) WithCORS(next http.Handler) http.Handler { next.ServeHTTP(w, r) }) } + +func firstExisting(or string, strings ...string) string { + for _, s := range strings { + if s != "" { + return s + } + } + return or +} diff --git a/server/ctrlsubsonic/handlers_by_tags.go b/server/ctrlsubsonic/handlers_by_tags.go index 31748322..769d12a3 100644 --- a/server/ctrlsubsonic/handlers_by_tags.go +++ b/server/ctrlsubsonic/handlers_by_tags.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "net/http" + "net/url" + "strconv" "strings" "github.com/jinzhu/gorm" @@ -248,12 +250,32 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response { if err != nil { return spec.NewError(10, "please provide an `id` parameter") } + + sub := spec.NewResponse() + sub.ArtistInfoTwo = &spec.ArtistInfo{} + + guessedArtistFolder := &db.Album{} + err = c.DB. + Select("parent.*"). + Joins("JOIN albums parent ON parent.id=albums.parent_id"). + Where("albums.tag_artist_id=?", id.Value). + Find(&guessedArtistFolder). + Error + if err != nil { + return spec.NewError(0, "finding artist folder: %v", err) + } + + if guessedArtistFolder.Cover != "" { + sub.ArtistInfoTwo.SmallImageURL = c.genAlbumCoverURL(r, guessedArtistFolder, 64) + sub.ArtistInfoTwo.MediumImageURL = c.genAlbumCoverURL(r, guessedArtistFolder, 126) + sub.ArtistInfoTwo.LargeImageURL = c.genAlbumCoverURL(r, guessedArtistFolder, 256) + } + apiKey, _ := c.DB.GetSetting("lastfm_api_key") if apiKey == "" { - sub := spec.NewResponse() - sub.ArtistInfoTwo = &spec.ArtistInfo{} return sub } + artist := &db.Artist{} err = c.DB. Where("id=?", id.Value). @@ -262,26 +284,29 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response { if errors.Is(err, gorm.ErrRecordNotFound) { return spec.NewError(70, "artist with id `%s` not found", id) } + info, err := lastfm.ArtistGetInfo(apiKey, artist) if err != nil { return spec.NewError(0, "fetching artist info: %v", err) } - sub := spec.NewResponse() - sub.ArtistInfoTwo = &spec.ArtistInfo{ - Biography: info.Bio.Summary, - MusicBrainzID: info.MBID, - LastFMURL: info.URL, - } - for _, image := range info.Image { - switch image.Size { - case "small": - sub.ArtistInfoTwo.SmallImageURL = image.Text - case "medium": - sub.ArtistInfoTwo.MediumImageURL = image.Text - case "large": - sub.ArtistInfoTwo.LargeImageURL = image.Text + + sub.ArtistInfoTwo.Biography = info.Bio.Summary + sub.ArtistInfoTwo.MusicBrainzID = info.MBID + sub.ArtistInfoTwo.LastFMURL = info.URL + + if guessedArtistFolder.Cover == "" { + for _, image := range info.Image { + switch image.Size { + case "small": + sub.ArtistInfoTwo.SmallImageURL = image.Text + case "medium": + sub.ArtistInfoTwo.MediumImageURL = image.Text + case "large": + sub.ArtistInfoTwo.LargeImageURL = image.Text + } } } + count := params.GetOrInt("count", 20) inclNotPresent := params.GetOrBool("includeNotPresent", false) for i, similarInfo := range info.Similar.Artists { @@ -310,6 +335,7 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response { sub.ArtistInfoTwo.SimilarArtist = append( sub.ArtistInfoTwo.SimilarArtist, similar) } + return sub } @@ -371,3 +397,16 @@ func (c *Controller) ServeGetStarredTwo(r *http.Request) *spec.Response { } return sub } + +func (c *Controller) genAlbumCoverURL(r *http.Request, folder *db.Album, size int) string { + coverURL, _ := url.Parse(c.BaseURL(r)) + coverURL.Path = c.Path("/rest/getCoverArt") + + id := specid.ID{Type: specid.Album, Value: folder.ID} + query := r.URL.Query() + query.Set("id", id.String()) + query.Set("size", strconv.Itoa(size)) + coverURL.RawQuery = query.Encode() + + return coverURL.String() +} diff --git a/server/scanner/scanner.go b/server/scanner/scanner.go index 18caa4d6..ce5af918 100644 --- a/server/scanner/scanner.go +++ b/server/scanner/scanner.go @@ -471,7 +471,8 @@ func isCover(name string) bool { "folder.png", "folder.jpg", "folder.jpeg", "album.png", "album.jpg", "album.jpeg", "albumart.png", "albumart.jpg", "albumart.jpeg", - "front.png", "front.jpg", "front.jpeg": + "front.png", "front.jpg", "front.jpeg", + "artist.png", "artist.jpg", "artist.jpeg": return true default: return false