Always access artist images through Navidrome (proxy calls to external URLs)

This commit is contained in:
Deluan
2022-12-31 17:29:58 -05:00
committed by Deluan Quintão
parent 918fee3ea3
commit 77a99a735b
6 changed files with 41 additions and 43 deletions
-18
View File
@@ -2,10 +2,7 @@ package agents
import ( import (
"context" "context"
"path/filepath"
"github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/core/artwork"
"github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/model"
) )
@@ -29,25 +26,10 @@ func (p *localAgent) GetBiography(ctx context.Context, id, name, mbid string) (s
return localBiography, nil return localBiography, nil
} }
func (p *localAgent) GetImages(_ context.Context, id, name, mbid string) ([]ArtistImage, error) {
return []ArtistImage{
p.artistImage(id, 300),
p.artistImage(id, 174),
p.artistImage(id, 64),
}, nil
}
func (p *localAgent) GetTopSongs(ctx context.Context, id, artistName, mbid string, count int) ([]Song, error) { func (p *localAgent) GetTopSongs(ctx context.Context, id, artistName, mbid string, count int) ([]Song, error) {
return nil, nil // TODO return 5-stars and liked songs sorted by playCount return nil, nil // TODO return 5-stars and liked songs sorted by playCount
} }
func (p *localAgent) artistImage(id string, size int) ArtistImage {
return ArtistImage{
filepath.Join(consts.URLPathPublicImages, artwork.PublicLink(model.NewArtworkID(model.KindArtistArtwork, id), size)),
size,
}
}
func init() { func init() {
Register(LocalAgentName, localsConstructor) Register(LocalAgentName, localsConstructor)
} }
+6 -3
View File
@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"path/filepath"
"strings" "strings"
"time" "time"
@@ -16,7 +17,7 @@ type artistReader struct {
cacheKey cacheKey
a *artwork a *artwork
artist model.Artist artist model.Artist
files []string files string
} }
func newArtistReader(ctx context.Context, artwork *artwork, artID model.ArtworkID) (*artistReader, error) { func newArtistReader(ctx context.Context, artwork *artwork, artID model.ArtworkID) (*artistReader, error) {
@@ -33,12 +34,14 @@ func newArtistReader(ctx context.Context, artwork *artwork, artID model.ArtworkI
artist: *ar, artist: *ar,
} }
a.cacheKey.lastUpdate = ar.ExternalInfoUpdatedAt a.cacheKey.lastUpdate = ar.ExternalInfoUpdatedAt
var files []string
for _, al := range als { for _, al := range als {
a.files = append(a.files, al.ImageFiles) files = append(files, al.ImageFiles)
if a.cacheKey.lastUpdate.Before(al.UpdatedAt) { if a.cacheKey.lastUpdate.Before(al.UpdatedAt) {
a.cacheKey.lastUpdate = al.UpdatedAt a.cacheKey.lastUpdate = al.UpdatedAt
} }
} }
a.files = strings.Join(files, string(filepath.ListSeparator))
a.cacheKey.artID = artID a.cacheKey.artID = artID
return a, nil return a, nil
} }
@@ -49,7 +52,7 @@ func (a *artistReader) LastUpdated() time.Time {
func (a *artistReader) Reader(ctx context.Context) (io.ReadCloser, string, error) { func (a *artistReader) Reader(ctx context.Context) (io.ReadCloser, string, error) {
return selectImageReader(ctx, a.artID, return selectImageReader(ctx, a.artID,
//fromExternalFile() fromExternalFile(ctx, a.files, "artist.*"),
fromExternalSource(ctx, a.artist), fromExternalSource(ctx, a.artist),
fromArtistPlaceholder(), fromArtistPlaceholder(),
) )
+1 -1
View File
@@ -124,7 +124,7 @@ func (api *Router) GetStarred(r *http.Request) (*responses.Subsonic, error) {
response := newResponse() response := newResponse()
response.Starred = &responses.Starred{} response.Starred = &responses.Starred{}
response.Starred.Artist = toArtists(ctx, artists) response.Starred.Artist = toArtists(r, artists)
response.Starred.Album = childrenFromAlbums(r.Context(), albums) response.Starred.Album = childrenFromAlbums(r.Context(), albums)
response.Starred.Song = childrenFromMediaFiles(r.Context(), mediaFiles) response.Starred.Song = childrenFromMediaFiles(r.Context(), mediaFiles)
return response, nil return response, nil
+12 -10
View File
@@ -28,7 +28,8 @@ func (api *Router) GetMusicFolders(r *http.Request) (*responses.Subsonic, error)
return response, nil return response, nil
} }
func (api *Router) getArtistIndex(ctx context.Context, mediaFolderId int, ifModifiedSince time.Time) (*responses.Indexes, error) { func (api *Router) getArtistIndex(r *http.Request, mediaFolderId int, ifModifiedSince time.Time) (*responses.Indexes, error) {
ctx := r.Context()
folder, err := api.ds.MediaFolder(ctx).Get(int32(mediaFolderId)) folder, err := api.ds.MediaFolder(ctx).Get(int32(mediaFolderId))
if err != nil { if err != nil {
log.Error(ctx, "Error retrieving MediaFolder", "id", mediaFolderId, err) log.Error(ctx, "Error retrieving MediaFolder", "id", mediaFolderId, err)
@@ -60,7 +61,7 @@ func (api *Router) getArtistIndex(ctx context.Context, mediaFolderId int, ifModi
res.Index = make([]responses.Index, len(indexes)) res.Index = make([]responses.Index, len(indexes))
for i, idx := range indexes { for i, idx := range indexes {
res.Index[i].Name = idx.ID res.Index[i].Name = idx.ID
res.Index[i].Artists = toArtists(ctx, idx.Artists) res.Index[i].Artists = toArtists(r, idx.Artists)
} }
return res, nil return res, nil
} }
@@ -69,7 +70,7 @@ func (api *Router) GetIndexes(r *http.Request) (*responses.Subsonic, error) {
musicFolderId := utils.ParamInt(r, "musicFolderId", 0) musicFolderId := utils.ParamInt(r, "musicFolderId", 0)
ifModifiedSince := utils.ParamTime(r, "ifModifiedSince", time.Time{}) ifModifiedSince := utils.ParamTime(r, "ifModifiedSince", time.Time{})
res, err := api.getArtistIndex(r.Context(), musicFolderId, ifModifiedSince) res, err := api.getArtistIndex(r, musicFolderId, ifModifiedSince)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -81,7 +82,7 @@ func (api *Router) GetIndexes(r *http.Request) (*responses.Subsonic, error) {
func (api *Router) GetArtists(r *http.Request) (*responses.Subsonic, error) { func (api *Router) GetArtists(r *http.Request) (*responses.Subsonic, error) {
musicFolderId := utils.ParamInt(r, "musicFolderId", 0) musicFolderId := utils.ParamInt(r, "musicFolderId", 0)
res, err := api.getArtistIndex(r.Context(), musicFolderId, time.Time{}) res, err := api.getArtistIndex(r, musicFolderId, time.Time{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -148,7 +149,7 @@ func (api *Router) GetArtist(r *http.Request) (*responses.Subsonic, error) {
} }
response := newResponse() response := newResponse()
response.ArtistWithAlbumsID3 = api.buildArtist(ctx, artist, albums) response.ArtistWithAlbumsID3 = api.buildArtist(r, artist, albums)
return response, nil return response, nil
} }
@@ -238,7 +239,7 @@ func (api *Router) GetArtistInfo(r *http.Request) (*responses.Subsonic, error) {
response.ArtistInfo.LastFmUrl = artist.ExternalUrl response.ArtistInfo.LastFmUrl = artist.ExternalUrl
response.ArtistInfo.MusicBrainzID = artist.MbzArtistID response.ArtistInfo.MusicBrainzID = artist.MbzArtistID
for _, s := range artist.SimilarArtists { for _, s := range artist.SimilarArtists {
similar := toArtist(ctx, s) similar := toArtist(r, s)
response.ArtistInfo.SimilarArtist = append(response.ArtistInfo.SimilarArtist, similar) response.ArtistInfo.SimilarArtist = append(response.ArtistInfo.SimilarArtist, similar)
} }
return response, nil return response, nil
@@ -260,7 +261,8 @@ func (api *Router) GetArtistInfo2(r *http.Request) (*responses.Subsonic, error)
similar.AlbumCount = s.AlbumCount similar.AlbumCount = s.AlbumCount
similar.Starred = s.Starred similar.Starred = s.Starred
similar.UserRating = s.UserRating similar.UserRating = s.UserRating
similar.ArtistImageUrl = server.AbsoluteURL(r, s.ArtistImageUrl) similar.CoverArt = s.CoverArt
similar.ArtistImageUrl = s.ArtistImageUrl
response.ArtistInfo2.SimilarArtist = append(response.ArtistInfo2.SimilarArtist, similar) response.ArtistInfo2.SimilarArtist = append(response.ArtistInfo2.SimilarArtist, similar)
} }
return response, nil return response, nil
@@ -342,10 +344,10 @@ func (api *Router) buildArtistDirectory(ctx context.Context, artist *model.Artis
return dir, nil return dir, nil
} }
func (api *Router) buildArtist(ctx context.Context, artist *model.Artist, albums model.Albums) *responses.ArtistWithAlbumsID3 { func (api *Router) buildArtist(r *http.Request, artist *model.Artist, albums model.Albums) *responses.ArtistWithAlbumsID3 {
a := &responses.ArtistWithAlbumsID3{} a := &responses.ArtistWithAlbumsID3{}
a.ArtistID3 = toArtistID3(ctx, *artist) a.ArtistID3 = toArtistID3(r, *artist)
a.Album = childrenFromAlbums(ctx, albums) a.Album = childrenFromAlbums(r.Context(), albums)
return a return a
} }
+15 -6
View File
@@ -5,11 +5,14 @@ import (
"fmt" "fmt"
"mime" "mime"
"net/http" "net/http"
"path/filepath"
"strings" "strings"
"github.com/navidrome/navidrome/consts" "github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/core/artwork"
"github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/model/request" "github.com/navidrome/navidrome/model/request"
"github.com/navidrome/navidrome/server"
"github.com/navidrome/navidrome/server/subsonic/responses" "github.com/navidrome/navidrome/server/subsonic/responses"
"github.com/navidrome/navidrome/utils" "github.com/navidrome/navidrome/utils"
) )
@@ -72,22 +75,22 @@ func getUser(ctx context.Context) model.User {
return model.User{} return model.User{}
} }
func toArtists(ctx context.Context, artists model.Artists) []responses.Artist { func toArtists(r *http.Request, artists model.Artists) []responses.Artist {
as := make([]responses.Artist, len(artists)) as := make([]responses.Artist, len(artists))
for i, artist := range artists { for i, artist := range artists {
as[i] = toArtist(ctx, artist) as[i] = toArtist(r, artist)
} }
return as return as
} }
func toArtist(_ context.Context, a model.Artist) responses.Artist { func toArtist(r *http.Request, a model.Artist) responses.Artist {
artist := responses.Artist{ artist := responses.Artist{
Id: a.ID, Id: a.ID,
Name: a.Name, Name: a.Name,
AlbumCount: a.AlbumCount, AlbumCount: a.AlbumCount,
UserRating: a.Rating, UserRating: a.Rating,
CoverArt: a.CoverArtID().String(), CoverArt: a.CoverArtID().String(),
ArtistImageUrl: a.ArtistImageUrl(), ArtistImageUrl: artistCoverArtURL(r, a.CoverArtID(), 0),
} }
if a.Starred { if a.Starred {
artist.Starred = &a.StarredAt artist.Starred = &a.StarredAt
@@ -95,13 +98,13 @@ func toArtist(_ context.Context, a model.Artist) responses.Artist {
return artist return artist
} }
func toArtistID3(_ context.Context, a model.Artist) responses.ArtistID3 { func toArtistID3(r *http.Request, a model.Artist) responses.ArtistID3 {
artist := responses.ArtistID3{ artist := responses.ArtistID3{
Id: a.ID, Id: a.ID,
Name: a.Name, Name: a.Name,
AlbumCount: a.AlbumCount, AlbumCount: a.AlbumCount,
CoverArt: a.CoverArtID().String(), CoverArt: a.CoverArtID().String(),
ArtistImageUrl: a.ArtistImageUrl(), ArtistImageUrl: artistCoverArtURL(r, a.CoverArtID(), 0),
UserRating: a.Rating, UserRating: a.Rating,
} }
if a.Starred { if a.Starred {
@@ -110,6 +113,12 @@ func toArtistID3(_ context.Context, a model.Artist) responses.ArtistID3 {
return artist return artist
} }
func artistCoverArtURL(r *http.Request, artID model.ArtworkID, size int) string {
link := artwork.PublicLink(artID, size)
url := filepath.Join(consts.URLPathPublicImages, link)
return server.AbsoluteURL(r, url)
}
func toGenres(genres model.Genres) *responses.Genres { func toGenres(genres model.Genres) *responses.Genres {
response := make([]responses.Genre, len(genres)) response := make([]responses.Genre, len(genres))
for i, g := range genres { for i, g := range genres {
+3 -1
View File
@@ -111,6 +111,8 @@ func (api *Router) Search2(r *http.Request) (*responses.Subsonic, error) {
Name: artist.Name, Name: artist.Name,
AlbumCount: artist.AlbumCount, AlbumCount: artist.AlbumCount,
UserRating: artist.Rating, UserRating: artist.Rating,
CoverArt: artist.CoverArtID().String(),
ArtistImageUrl: artistCoverArtURL(r, artist.CoverArtID(), 0),
} }
if artist.Starred { if artist.Starred {
searchResult2.Artist[i].Starred = &as[i].StarredAt searchResult2.Artist[i].Starred = &as[i].StarredAt
@@ -134,7 +136,7 @@ func (api *Router) Search3(r *http.Request) (*responses.Subsonic, error) {
searchResult3 := &responses.SearchResult3{} searchResult3 := &responses.SearchResult3{}
searchResult3.Artist = make([]responses.ArtistID3, len(as)) searchResult3.Artist = make([]responses.ArtistID3, len(as))
for i, artist := range as { for i, artist := range as {
searchResult3.Artist[i] = toArtistID3(ctx, artist) searchResult3.Artist[i] = toArtistID3(r, artist)
} }
searchResult3.Album = childrenFromAlbums(ctx, als) searchResult3.Album = childrenFromAlbums(ctx, als)
searchResult3.Song = childrenFromMediaFiles(ctx, mfs) searchResult3.Song = childrenFromMediaFiles(ctx, mfs)