diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 0f5fa90c0..90984c84e 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -13,7 +13,6 @@ import ( "github.com/deluan/navidrome/server" "github.com/deluan/navidrome/server/app" "github.com/deluan/navidrome/server/subsonic" - "github.com/deluan/navidrome/server/subsonic/engine" "github.com/google/wire" ) @@ -44,7 +43,6 @@ func CreateSubsonicAPIRouter() *subsonic.Router { dataStore := persistence.New() artworkCache := core.NewImageCache() artwork := core.NewArtwork(dataStore, artworkCache) - playlists := engine.NewPlaylists(dataStore) transcoderTranscoder := transcoder.New() transcodingCache := core.NewTranscodingCache() mediaStreamer := core.NewMediaStreamer(dataStore, transcoderTranscoder, transcodingCache) @@ -53,10 +51,10 @@ func CreateSubsonicAPIRouter() *subsonic.Router { client := core.LastFMNewClient() spotifyClient := core.SpotifyNewClient() externalInfo := core.NewExternalInfo(dataStore, client, spotifyClient) - router := subsonic.New(artwork, playlists, mediaStreamer, archiver, players, externalInfo, dataStore) + router := subsonic.New(artwork, mediaStreamer, archiver, players, externalInfo, dataStore) return router } // wire_injectors.go: -var allProviders = wire.NewSet(engine.Set, core.Set, scanner.New, subsonic.New, app.New, persistence.New) +var allProviders = wire.NewSet(core.Set, scanner.New, subsonic.New, app.New, persistence.New) diff --git a/cmd/wire_injectors.go b/cmd/wire_injectors.go index 3d3da67b0..0572578cc 100644 --- a/cmd/wire_injectors.go +++ b/cmd/wire_injectors.go @@ -9,12 +9,10 @@ import ( "github.com/deluan/navidrome/server" "github.com/deluan/navidrome/server/app" "github.com/deluan/navidrome/server/subsonic" - "github.com/deluan/navidrome/server/subsonic/engine" "github.com/google/wire" ) var allProviders = wire.NewSet( - engine.Set, core.Set, scanner.New, subsonic.New, diff --git a/core/wire_providers.go b/core/wire_providers.go index 691998238..dec7edfe1 100644 --- a/core/wire_providers.go +++ b/core/wire_providers.go @@ -19,6 +19,7 @@ var Set = wire.NewSet( NewNowPlayingRepository, NewExternalInfo, NewCacheWarmer, + NewPlayers, LastFMNewClient, SpotifyNewClient, transcoder.New, diff --git a/go.sum b/go.sum index 976e238c1..f5afb5a78 100644 --- a/go.sum +++ b/go.sum @@ -311,8 +311,7 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= diff --git a/server/subsonic/api.go b/server/subsonic/api.go index 278a0a723..1b383e44a 100644 --- a/server/subsonic/api.go +++ b/server/subsonic/api.go @@ -11,7 +11,6 @@ import ( "github.com/deluan/navidrome/core" "github.com/deluan/navidrome/log" "github.com/deluan/navidrome/model" - "github.com/deluan/navidrome/server/subsonic/engine" "github.com/deluan/navidrome/server/subsonic/responses" "github.com/deluan/navidrome/utils" "github.com/go-chi/chi" @@ -24,7 +23,6 @@ type Handler = func(http.ResponseWriter, *http.Request) (*responses.Subsonic, er type Router struct { Artwork core.Artwork - Playlists engine.Playlists Streamer core.MediaStreamer Archiver core.Archiver Players core.Players @@ -34,11 +32,16 @@ type Router struct { mux http.Handler } -func New(artwork core.Artwork, - playlists engine.Playlists, streamer core.MediaStreamer, - archiver core.Archiver, players core.Players, externalInfo core.ExternalInfo, ds model.DataStore) *Router { - r := &Router{Artwork: artwork, Playlists: playlists, - Streamer: streamer, Archiver: archiver, Players: players, ExternalInfo: externalInfo, DataStore: ds} +func New(artwork core.Artwork, streamer core.MediaStreamer, archiver core.Archiver, players core.Players, + externalInfo core.ExternalInfo, ds model.DataStore) *Router { + r := &Router{ + Artwork: artwork, + Streamer: streamer, + Archiver: archiver, + Players: players, + ExternalInfo: externalInfo, + DataStore: ds, + } r.mux = r.routes() return r } @@ -181,7 +184,7 @@ func HGone(r chi.Router, path string) { func SendError(w http.ResponseWriter, r *http.Request, err error) { response := newResponse() code := responses.ErrorGeneric - if e, ok := err.(SubsonicError); ok { + if e, ok := err.(Error); ok { code = e.code } response.Status = "fail" diff --git a/server/subsonic/engine/common.go b/server/subsonic/engine/common.go deleted file mode 100644 index 20e812176..000000000 --- a/server/subsonic/engine/common.go +++ /dev/null @@ -1,106 +0,0 @@ -package engine - -import ( - "fmt" - "time" - - "github.com/deluan/navidrome/consts" - "github.com/deluan/navidrome/model" -) - -type Entry struct { - Id string - Title string - IsDir bool - Parent string - Album string - Year int - Artist string - Genre string - CoverArt string - Starred time.Time - Track int - Duration int - Size int64 - Suffix string - BitRate int - ContentType string - Path string - PlayCount int32 - DiscNumber int - Created time.Time - AlbumId string - ArtistId string - Type string - UserRating int - SongCount int - UserName string - MinutesAgo int - PlayerId int - PlayerName string - AlbumCount int - BookmarkPosition int64 - AbsolutePath string -} - -type Entries []Entry - -func FromMediaFile(mf *model.MediaFile) Entry { - e := Entry{} - e.Id = mf.ID - e.Title = mf.Title - e.IsDir = false - e.Parent = mf.AlbumID - e.Album = mf.Album - e.Year = mf.Year - e.Artist = mf.Artist - e.Genre = mf.Genre - e.Track = mf.TrackNumber - e.Duration = int(mf.Duration) - e.Size = mf.Size - e.Suffix = mf.Suffix - e.BitRate = mf.BitRate - if mf.HasCoverArt { - e.CoverArt = mf.ID - } else { - e.CoverArt = "al-" + mf.AlbumID - } - e.ContentType = mf.ContentType() - e.AbsolutePath = mf.Path - // Creates a "pseudo" Path, to avoid sending absolute paths to the client - if mf.Path != "" { - e.Path = fmt.Sprintf("%s/%s/%s.%s", realArtistName(mf), mf.Album, mf.Title, mf.Suffix) - } - e.DiscNumber = mf.DiscNumber - e.Created = mf.CreatedAt - e.AlbumId = mf.AlbumID - e.ArtistId = mf.ArtistID - e.Type = "music" - e.PlayCount = int32(mf.PlayCount) - if mf.Starred { - e.Starred = mf.StarredAt - } - e.UserRating = mf.Rating - e.BookmarkPosition = mf.BookmarkPosition - return e -} - -func realArtistName(mf *model.MediaFile) string { - switch { - case mf.Compilation: - return consts.VariousArtists - case mf.AlbumArtist != "": - return mf.AlbumArtist - } - - return mf.Artist -} - -func FromMediaFiles(mfs model.MediaFiles) Entries { - entries := make(Entries, len(mfs)) - for i := range mfs { - mf := mfs[i] - entries[i] = FromMediaFile(&mf) - } - return entries -} diff --git a/server/subsonic/engine/playlists.go b/server/subsonic/engine/playlists.go deleted file mode 100644 index efba8f258..000000000 --- a/server/subsonic/engine/playlists.go +++ /dev/null @@ -1,151 +0,0 @@ -package engine - -import ( - "context" - "time" - - "github.com/deluan/navidrome/model" - "github.com/deluan/navidrome/model/request" - "github.com/deluan/navidrome/utils" -) - -type Playlists interface { - GetAll(ctx context.Context) (model.Playlists, error) - Get(ctx context.Context, id string) (*PlaylistInfo, error) - Create(ctx context.Context, playlistId, name string, ids []string) error - Delete(ctx context.Context, playlistId string) error - Update(ctx context.Context, playlistId string, name *string, idsToAdd []string, idxToRemove []int) error -} - -func NewPlaylists(ds model.DataStore) Playlists { - return &playlists{ds} -} - -type playlists struct { - ds model.DataStore -} - -func (p *playlists) Create(ctx context.Context, playlistId, name string, ids []string) error { - return p.ds.WithTx(func(tx model.DataStore) error { - owner := p.getUser(ctx) - var pls *model.Playlist - var err error - - // If playlistID is present, override tracks - if playlistId != "" { - pls, err = tx.Playlist(ctx).Get(playlistId) - if err != nil { - return err - } - if owner != pls.Owner { - return model.ErrNotAuthorized - } - pls.Tracks = nil - } else { - pls = &model.Playlist{ - Name: name, - Owner: owner, - } - } - for _, id := range ids { - pls.Tracks = append(pls.Tracks, model.MediaFile{ID: id}) - } - - return tx.Playlist(ctx).Put(pls) - }) -} - -func (p *playlists) getUser(ctx context.Context) string { - user, ok := request.UserFrom(ctx) - if ok { - return user.UserName - } - return "" -} - -func (p *playlists) Delete(ctx context.Context, playlistId string) error { - return p.ds.WithTx(func(tx model.DataStore) error { - pls, err := tx.Playlist(ctx).Get(playlistId) - if err != nil { - return err - } - - owner := p.getUser(ctx) - if owner != pls.Owner { - return model.ErrNotAuthorized - } - return tx.Playlist(ctx).Delete(playlistId) - }) -} - -func (p *playlists) Update(ctx context.Context, playlistId string, name *string, idsToAdd []string, idxToRemove []int) error { - return p.ds.WithTx(func(tx model.DataStore) error { - pls, err := tx.Playlist(ctx).Get(playlistId) - if err != nil { - return err - } - - owner := p.getUser(ctx) - if owner != pls.Owner { - return model.ErrNotAuthorized - } - - if name != nil { - pls.Name = *name - } - newTracks := model.MediaFiles{} - for i, t := range pls.Tracks { - if utils.IntInSlice(i, idxToRemove) { - continue - } - newTracks = append(newTracks, t) - } - - for _, id := range idsToAdd { - newTracks = append(newTracks, model.MediaFile{ID: id}) - } - pls.Tracks = newTracks - - return tx.Playlist(ctx).Put(pls) - }) -} - -func (p *playlists) GetAll(ctx context.Context) (model.Playlists, error) { - return p.ds.Playlist(ctx).GetAll() -} - -type PlaylistInfo struct { - Id string - Name string - Entries Entries - SongCount int - Duration int - Public bool - Owner string - Comment string - Created time.Time - Changed time.Time -} - -func (p *playlists) Get(ctx context.Context, id string) (*PlaylistInfo, error) { - pl, err := p.ds.Playlist(ctx).Get(id) - if err != nil { - return nil, err - } - - // TODO Use model.Playlist when got rid of Entries - plsInfo := &PlaylistInfo{ - Id: pl.ID, - Name: pl.Name, - SongCount: pl.SongCount, - Duration: int(pl.Duration), - Public: pl.Public, - Owner: pl.Owner, - Comment: pl.Comment, - Changed: pl.UpdatedAt, - Created: pl.CreatedAt, - } - - plsInfo.Entries = FromMediaFiles(pl.Tracks) - return plsInfo, nil -} diff --git a/server/subsonic/engine/wire_providers.go b/server/subsonic/engine/wire_providers.go deleted file mode 100644 index 124e2c339..000000000 --- a/server/subsonic/engine/wire_providers.go +++ /dev/null @@ -1,11 +0,0 @@ -package engine - -import ( - "github.com/deluan/navidrome/core" - "github.com/google/wire" -) - -var Set = wire.NewSet( - NewPlaylists, - core.NewPlayers, -) diff --git a/server/subsonic/helpers.go b/server/subsonic/helpers.go index 403cf5a87..815f63907 100644 --- a/server/subsonic/helpers.go +++ b/server/subsonic/helpers.go @@ -9,7 +9,6 @@ import ( "github.com/deluan/navidrome/consts" "github.com/deluan/navidrome/model" "github.com/deluan/navidrome/model/request" - "github.com/deluan/navidrome/server/subsonic/engine" "github.com/deluan/navidrome/server/subsonic/responses" "github.com/deluan/navidrome/utils" ) @@ -42,19 +41,19 @@ func requiredParamInt(r *http.Request, param string, msg string) (int, error) { return utils.ParamInt(r, param, 0), nil } -type SubsonicError struct { +type Error struct { code int messages []interface{} } func newError(code int, message ...interface{}) error { - return SubsonicError{ + return Error{ code: code, messages: message, } } -func (e SubsonicError) Error() string { +func (e Error) Error() string { var msg string if len(e.messages) == 0 { msg = responses.ErrorMsg(e.code) @@ -64,6 +63,14 @@ func (e SubsonicError) Error() string { return msg } +func getUser(ctx context.Context) string { + user, ok := request.UserFrom(ctx) + if ok { + return user.UserName + } + return "" +} + func toArtists(ctx context.Context, artists model.Artists) []responses.Artist { as := make([]responses.Artist, len(artists)) for i, artist := range artists { @@ -80,55 +87,6 @@ func toArtists(ctx context.Context, artists model.Artists) []responses.Artist { return as } -func toChildren(ctx context.Context, entries engine.Entries) []responses.Child { - children := make([]responses.Child, len(entries)) - for i, entry := range entries { - children[i] = toChild(ctx, entry) - } - return children -} - -func toChild(ctx context.Context, entry engine.Entry) responses.Child { - child := responses.Child{} - child.Id = entry.Id - child.Title = entry.Title - child.IsDir = entry.IsDir - child.Parent = entry.Parent - child.Album = entry.Album - child.Year = entry.Year - child.Artist = entry.Artist - child.Genre = entry.Genre - child.CoverArt = entry.CoverArt - child.Track = entry.Track - child.Duration = entry.Duration - child.Size = entry.Size - child.Suffix = entry.Suffix - child.BitRate = entry.BitRate - child.ContentType = entry.ContentType - if !entry.Starred.IsZero() { - child.Starred = &entry.Starred - } - child.Path = entry.Path - child.PlayCount = int64(entry.PlayCount) - child.DiscNumber = entry.DiscNumber - if !entry.Created.IsZero() { - child.Created = &entry.Created - } - child.AlbumId = entry.AlbumId - child.ArtistId = entry.ArtistId - child.Type = entry.Type - child.IsVideo = false - child.UserRating = entry.UserRating - child.SongCount = entry.SongCount - format, _ := getTranscoding(ctx) - if entry.Suffix != "" && format != "" && entry.Suffix != format { - child.TranscodedSuffix = format - child.TranscodedContentType = mime.TypeByExtension("." + format) - } - child.BookmarkPosition = entry.BookmarkPosition - return child -} - func toGenres(genres model.Genres) *responses.Genres { response := make([]responses.Genre, len(genres)) for i, g := range genres { diff --git a/server/subsonic/playlists.go b/server/subsonic/playlists.go index aa6b0513e..9edb6dba6 100644 --- a/server/subsonic/playlists.go +++ b/server/subsonic/playlists.go @@ -8,36 +8,28 @@ import ( "github.com/deluan/navidrome/log" "github.com/deluan/navidrome/model" - "github.com/deluan/navidrome/server/subsonic/engine" "github.com/deluan/navidrome/server/subsonic/responses" "github.com/deluan/navidrome/utils" ) type PlaylistsController struct { - pls engine.Playlists + ds model.DataStore } -func NewPlaylistsController(pls engine.Playlists) *PlaylistsController { - return &PlaylistsController{pls: pls} +func NewPlaylistsController(ds model.DataStore) *PlaylistsController { + return &PlaylistsController{ds: ds} } func (c *PlaylistsController) GetPlaylists(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { - allPls, err := c.pls.GetAll(r.Context()) + ctx := r.Context() + allPls, err := c.ds.Playlist(ctx).GetAll() if err != nil { log.Error(r, err) return nil, newError(responses.ErrorGeneric, "Internal error") } playlists := make([]responses.Playlist, len(allPls)) for i, p := range allPls { - playlists[i].Id = p.ID - playlists[i].Name = p.Name - playlists[i].Comment = p.Comment - playlists[i].SongCount = p.SongCount - playlists[i].Duration = int(p.Duration) - playlists[i].Owner = p.Owner - playlists[i].Public = p.Public - playlists[i].Created = p.CreatedAt - playlists[i].Changed = p.UpdatedAt + playlists[i] = *c.buildPlaylist(p) } response := newResponse() response.Playlists = &responses.Playlists{Playlist: playlists} @@ -45,11 +37,12 @@ func (c *PlaylistsController) GetPlaylists(w http.ResponseWriter, r *http.Reques } func (c *PlaylistsController) GetPlaylist(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { + ctx := r.Context() id, err := requiredParamString(r, "id", "id parameter required") if err != nil { return nil, err } - pinfo, err := c.pls.Get(r.Context(), id) + pls, err := c.ds.Playlist(ctx).Get(id) switch { case err == model.ErrNotFound: log.Error(r, err.Error(), "id", id) @@ -60,18 +53,48 @@ func (c *PlaylistsController) GetPlaylist(w http.ResponseWriter, r *http.Request } response := newResponse() - response.Playlist = c.buildPlaylistWithSongs(r.Context(), pinfo) + response.Playlist = c.buildPlaylistWithSongs(ctx, pls) return response, nil } +func (c *PlaylistsController) create(ctx context.Context, playlistId, name string, ids []string) error { + return c.ds.WithTx(func(tx model.DataStore) error { + owner := getUser(ctx) + var pls *model.Playlist + var err error + + // If playlistID is present, override tracks + if playlistId != "" { + pls, err = tx.Playlist(ctx).Get(playlistId) + if err != nil { + return err + } + if owner != pls.Owner { + return model.ErrNotAuthorized + } + pls.Tracks = nil + } else { + pls = &model.Playlist{ + Name: name, + Owner: owner, + } + } + for _, id := range ids { + pls.Tracks = append(pls.Tracks, model.MediaFile{ID: id}) + } + + return tx.Playlist(ctx).Put(pls) + }) +} + func (c *PlaylistsController) CreatePlaylist(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { songIds := utils.ParamStrings(r, "songId") playlistId := utils.ParamString(r, "playlistId") name := utils.ParamString(r, "name") if playlistId == "" && name == "" { - return nil, errors.New("Required parameter name is missing") + return nil, errors.New("required parameter name is missing") } - err := c.pls.Create(r.Context(), playlistId, name, songIds) + err := c.create(r.Context(), playlistId, name, songIds) if err != nil { log.Error(r, err) return nil, newError(responses.ErrorGeneric, "Internal Error") @@ -79,12 +102,27 @@ func (c *PlaylistsController) CreatePlaylist(w http.ResponseWriter, r *http.Requ return newResponse(), nil } +func (c *PlaylistsController) delete(ctx context.Context, playlistId string) error { + return c.ds.WithTx(func(tx model.DataStore) error { + pls, err := tx.Playlist(ctx).Get(playlistId) + if err != nil { + return err + } + + owner := getUser(ctx) + if owner != pls.Owner { + return model.ErrNotAuthorized + } + return tx.Playlist(ctx).Delete(playlistId) + }) +} + func (c *PlaylistsController) DeletePlaylist(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { id, err := requiredParamString(r, "id", "Required parameter id is missing") if err != nil { return nil, err } - err = c.pls.Delete(r.Context(), id) + err = c.delete(r.Context(), id) if err == model.ErrNotAuthorized { return nil, newError(responses.ErrorAuthorizationFail) } @@ -95,6 +133,38 @@ func (c *PlaylistsController) DeletePlaylist(w http.ResponseWriter, r *http.Requ return newResponse(), nil } +func (p *PlaylistsController) update(ctx context.Context, playlistId string, name *string, idsToAdd []string, idxToRemove []int) error { + return p.ds.WithTx(func(tx model.DataStore) error { + pls, err := tx.Playlist(ctx).Get(playlistId) + if err != nil { + return err + } + + owner := getUser(ctx) + if owner != pls.Owner { + return model.ErrNotAuthorized + } + + if name != nil { + pls.Name = *name + } + newTracks := model.MediaFiles{} + for i, t := range pls.Tracks { + if utils.IntInSlice(i, idxToRemove) { + continue + } + newTracks = append(newTracks, t) + } + + for _, id := range idsToAdd { + newTracks = append(newTracks, model.MediaFile{ID: id}) + } + pls.Tracks = newTracks + + return tx.Playlist(ctx).Put(pls) + }) +} + func (c *PlaylistsController) UpdatePlaylist(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { playlistId, err := requiredParamString(r, "playlistId", "Required parameter playlistId is missing") if err != nil { @@ -103,20 +173,20 @@ func (c *PlaylistsController) UpdatePlaylist(w http.ResponseWriter, r *http.Requ songsToAdd := utils.ParamStrings(r, "songIdToAdd") songIndexesToRemove := utils.ParamInts(r, "songIndexToRemove") - var pname *string + var plsName *string if len(r.URL.Query()["name"]) > 0 { s := r.URL.Query()["name"][0] - pname = &s + plsName = &s } log.Debug(r, "Updating playlist", "id", playlistId) - if pname != nil { - log.Trace(r, fmt.Sprintf("-- New Name: '%s'", *pname)) + if plsName != nil { + log.Trace(r, fmt.Sprintf("-- New Name: '%s'", *plsName)) } log.Trace(r, fmt.Sprintf("-- Adding: '%v'", songsToAdd)) log.Trace(r, fmt.Sprintf("-- Removing: '%v'", songIndexesToRemove)) - err = c.pls.Update(r.Context(), playlistId, pname, songsToAdd, songIndexesToRemove) + err = c.update(r.Context(), playlistId, plsName, songsToAdd, songIndexesToRemove) if err == model.ErrNotAuthorized { return nil, newError(responses.ErrorAuthorizationFail) } @@ -127,24 +197,24 @@ func (c *PlaylistsController) UpdatePlaylist(w http.ResponseWriter, r *http.Requ return newResponse(), nil } -func (c *PlaylistsController) buildPlaylistWithSongs(ctx context.Context, d *engine.PlaylistInfo) *responses.PlaylistWithSongs { +func (c *PlaylistsController) buildPlaylistWithSongs(ctx context.Context, p *model.Playlist) *responses.PlaylistWithSongs { pls := &responses.PlaylistWithSongs{ - Playlist: *c.buildPlaylist(d), + Playlist: *c.buildPlaylist(*p), } - pls.Entry = toChildren(ctx, d.Entries) + pls.Entry = childrenFromMediaFiles(ctx, p.Tracks) return pls } -func (c *PlaylistsController) buildPlaylist(d *engine.PlaylistInfo) *responses.Playlist { +func (c *PlaylistsController) buildPlaylist(p model.Playlist) *responses.Playlist { pls := &responses.Playlist{} - pls.Id = d.Id - pls.Name = d.Name - pls.Comment = d.Comment - pls.SongCount = d.SongCount - pls.Owner = d.Owner - pls.Duration = d.Duration - pls.Public = d.Public - pls.Created = d.Created - pls.Changed = d.Changed + pls.Id = p.ID + pls.Name = p.Name + pls.Comment = p.Comment + pls.SongCount = p.SongCount + pls.Owner = p.Owner + pls.Duration = int(p.Duration) + pls.Public = p.Public + pls.Created = p.CreatedAt + pls.Changed = p.UpdatedAt return pls } diff --git a/server/subsonic/wire_gen.go b/server/subsonic/wire_gen.go index 799412133..439e12108 100644 --- a/server/subsonic/wire_gen.go +++ b/server/subsonic/wire_gen.go @@ -39,8 +39,8 @@ func initMediaAnnotationController(router *Router) *MediaAnnotationController { } func initPlaylistsController(router *Router) *PlaylistsController { - playlists := router.Playlists - playlistsController := NewPlaylistsController(playlists) + dataStore := router.DataStore + playlistsController := NewPlaylistsController(dataStore) return playlistsController } @@ -87,5 +87,5 @@ var allProviders = wire.NewSet( NewUsersController, NewMediaRetrievalController, NewStreamController, - NewBookmarksController, core.NewNowPlayingRepository, wire.FieldsOf(new(*Router), "Artwork", "Playlists", "Streamer", "Archiver", "DataStore", "ExternalInfo"), + NewBookmarksController, core.NewNowPlayingRepository, wire.FieldsOf(new(*Router), "Artwork", "Streamer", "Archiver", "DataStore", "ExternalInfo"), ) diff --git a/server/subsonic/wire_injectors.go b/server/subsonic/wire_injectors.go index 7bf9cba85..cc21188b2 100644 --- a/server/subsonic/wire_injectors.go +++ b/server/subsonic/wire_injectors.go @@ -19,7 +19,7 @@ var allProviders = wire.NewSet( NewStreamController, NewBookmarksController, core.NewNowPlayingRepository, - wire.FieldsOf(new(*Router), "Artwork", "Playlists", "Streamer", "Archiver", "DataStore", "ExternalInfo"), + wire.FieldsOf(new(*Router), "Artwork", "Streamer", "Archiver", "DataStore", "ExternalInfo"), ) func initSystemController(router *Router) *SystemController {