diff --git a/server/subsonic/api.go b/server/subsonic/api.go index 1d1ee61ae..30b4d2816 100644 --- a/server/subsonic/api.go +++ b/server/subsonic/api.go @@ -171,7 +171,11 @@ func h(r chi.Router, path string, f handler) { if err != nil { // If it is not a Subsonic error, convert it to an ErrorGeneric if _, ok := err.(subError); !ok { - err = newError(responses.ErrorGeneric, "Internal Error") + if err == model.ErrNotFound { + err = newError(responses.ErrorDataNotFound, "data not found") + } else { + err = newError(responses.ErrorGeneric, "Internal Error") + } } sendError(w, r, err) return diff --git a/server/subsonic/media_retrieval.go b/server/subsonic/media_retrieval.go index 8db8a3b10..db928ca02 100644 --- a/server/subsonic/media_retrieval.go +++ b/server/subsonic/media_retrieval.go @@ -4,8 +4,10 @@ import ( "io" "net/http" + "github.com/deluan/navidrome/conf" "github.com/deluan/navidrome/consts" "github.com/deluan/navidrome/core" + "github.com/deluan/navidrome/core/gravatar" "github.com/deluan/navidrome/log" "github.com/deluan/navidrome/model" "github.com/deluan/navidrome/resources" @@ -15,13 +17,35 @@ import ( type MediaRetrievalController struct { artwork core.Artwork + ds model.DataStore } -func NewMediaRetrievalController(artwork core.Artwork) *MediaRetrievalController { - return &MediaRetrievalController{artwork: artwork} +func NewMediaRetrievalController(artwork core.Artwork, ds model.DataStore) *MediaRetrievalController { + return &MediaRetrievalController{artwork: artwork, ds: ds} } func (c *MediaRetrievalController) GetAvatar(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { + if !conf.Server.EnableGravatar { + return c.getPlaceHolderAvatar(w, r) + } + username, err := requiredParamString(r, "username") + if err != nil { + return nil, err + } + ctx := r.Context() + u, err := c.ds.User(ctx).FindByUsername(username) + if err != nil { + return nil, err + } + if u.Email == "" { + log.Warn(ctx, "User needs an email for gravatar to work", "username", username) + return c.getPlaceHolderAvatar(w, r) + } + http.Redirect(w, r, gravatar.Url(u.Email, 0), http.StatusFound) + return nil, nil +} + +func (c *MediaRetrievalController) getPlaceHolderAvatar(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { f, err := resources.AssetFile().Open(consts.PlaceholderAvatar) if err != nil { log.Error(r, "Image not found", err) diff --git a/server/subsonic/media_retrieval_test.go b/server/subsonic/media_retrieval_test.go index 78513ec7c..dc2e6b00a 100644 --- a/server/subsonic/media_retrieval_test.go +++ b/server/subsonic/media_retrieval_test.go @@ -7,6 +7,7 @@ import ( "net/http/httptest" "github.com/deluan/navidrome/model" + "github.com/deluan/navidrome/tests" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) @@ -18,7 +19,7 @@ var _ = Describe("MediaRetrievalController", func() { BeforeEach(func() { artwork = &fakeArtwork{} - controller = NewMediaRetrievalController(artwork) + controller = NewMediaRetrievalController(artwork, &tests.MockDataStore{}) w = httptest.NewRecorder() }) diff --git a/server/subsonic/wire_gen.go b/server/subsonic/wire_gen.go index dd7f3d24a..c4f28a586 100644 --- a/server/subsonic/wire_gen.go +++ b/server/subsonic/wire_gen.go @@ -57,7 +57,8 @@ func initUsersController(router *Router) *UsersController { func initMediaRetrievalController(router *Router) *MediaRetrievalController { artwork := router.Artwork - mediaRetrievalController := NewMediaRetrievalController(artwork) + dataStore := router.DataStore + mediaRetrievalController := NewMediaRetrievalController(artwork, dataStore) return mediaRetrievalController }