feat: new "Subsonic Minimal Clients" configuration option (#4850)
* Add `.editorconfig` file Hints to users how to properly indent Go files (my setup was defaulting to 2 spaces). * Add Subsonic API minimal config option This will allow users to specify clients which can operate with or need the minimum required fields as per the [SubSonic API spec](https://subsonic.org/pages/api.jsp). * Return only required fields for Child Objects For a minimal client, only return the required fields for Child Objects. * Return only required fields for Playlist objects * refactor: simplify client list checks and improve playlist response handling Signed-off-by: Deluan <deluan@navidrome.org> * test: add unit tests for client list checks and playlist building logic Signed-off-by: Deluan <deluan@navidrome.org> * fix: revert Child.IsVideo and Playlist.Public fields from pointer to boolean, and add omitempty to XML tag Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org> Co-authored-by: Deluan Quintão <deluan@navidrome.org>
This commit is contained in:
@@ -7,8 +7,10 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/navidrome/navidrome/conf"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
"github.com/navidrome/navidrome/utils/slice"
|
||||
@@ -23,7 +25,7 @@ func (api *Router) GetPlaylists(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
response := newResponse()
|
||||
response.Playlists = &responses.Playlists{
|
||||
Playlist: slice.Map(allPls, api.buildPlaylist),
|
||||
Playlist: slice.MapWithArg(allPls, ctx, api.buildPlaylist),
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
@@ -51,7 +53,7 @@ func (api *Router) getPlaylist(ctx context.Context, id string) (*responses.Subso
|
||||
|
||||
response := newResponse()
|
||||
response.Playlist = &responses.PlaylistWithSongs{
|
||||
Playlist: api.buildPlaylist(*pls),
|
||||
Playlist: api.buildPlaylist(ctx, *pls),
|
||||
}
|
||||
response.Playlist.Entry = slice.MapWithArg(pls.MediaFiles(), ctx, childFromMediaFile)
|
||||
return response, nil
|
||||
@@ -152,21 +154,28 @@ func (api *Router) UpdatePlaylist(r *http.Request) (*responses.Subsonic, error)
|
||||
return newResponse(), nil
|
||||
}
|
||||
|
||||
func (api *Router) buildPlaylist(p model.Playlist) responses.Playlist {
|
||||
func (api *Router) buildPlaylist(ctx context.Context, p model.Playlist) responses.Playlist {
|
||||
pls := responses.Playlist{}
|
||||
pls.Id = p.ID
|
||||
pls.Name = p.Name
|
||||
pls.Comment = p.Comment
|
||||
pls.SongCount = int32(p.SongCount)
|
||||
pls.Owner = p.OwnerName
|
||||
pls.Duration = int32(p.Duration)
|
||||
pls.Public = p.Public
|
||||
pls.Created = p.CreatedAt
|
||||
pls.CoverArt = p.CoverArtID().String()
|
||||
if p.IsSmartPlaylist() {
|
||||
pls.Changed = time.Now()
|
||||
} else {
|
||||
pls.Changed = p.UpdatedAt
|
||||
}
|
||||
|
||||
player, ok := request.PlayerFrom(ctx)
|
||||
if ok && isClientInList(conf.Server.Subsonic.MinimalClients, player.Client) {
|
||||
return pls
|
||||
}
|
||||
|
||||
pls.Comment = p.Comment
|
||||
pls.Owner = p.OwnerName
|
||||
pls.Public = p.Public
|
||||
pls.CoverArt = p.CoverArtID().String()
|
||||
|
||||
return pls
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user