2016-03-09 16:09:15 +01:00
|
|
|
package engine
|
|
|
|
|
|
|
|
import (
|
2020-01-09 02:45:07 +01:00
|
|
|
"context"
|
2020-04-11 22:45:21 +02:00
|
|
|
"time"
|
2016-03-24 17:06:39 +01:00
|
|
|
|
2020-01-24 01:44:08 +01:00
|
|
|
"github.com/deluan/navidrome/model"
|
|
|
|
"github.com/deluan/navidrome/utils"
|
2016-03-09 16:09:15 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Playlists interface {
|
2020-01-22 14:32:31 +01:00
|
|
|
GetAll(ctx context.Context) (model.Playlists, error)
|
2020-01-22 05:01:43 +01:00
|
|
|
Get(ctx context.Context, id string) (*PlaylistInfo, error)
|
2020-01-21 22:35:57 +01:00
|
|
|
Create(ctx context.Context, playlistId, name string, ids []string) error
|
2020-01-09 02:45:07 +01:00
|
|
|
Delete(ctx context.Context, playlistId string) error
|
2020-01-21 22:35:57 +01:00
|
|
|
Update(ctx context.Context, playlistId string, name *string, idsToAdd []string, idxToRemove []int) error
|
2016-03-09 16:09:15 +01:00
|
|
|
}
|
|
|
|
|
2020-01-19 21:37:41 +01:00
|
|
|
func NewPlaylists(ds model.DataStore) Playlists {
|
|
|
|
return &playlists{ds}
|
2016-03-09 16:09:15 +01:00
|
|
|
}
|
|
|
|
|
2016-03-10 00:28:11 +01:00
|
|
|
type playlists struct {
|
2020-01-19 21:37:41 +01:00
|
|
|
ds model.DataStore
|
2016-03-09 16:09:15 +01:00
|
|
|
}
|
|
|
|
|
2020-01-21 22:35:57 +01:00
|
|
|
func (p *playlists) Create(ctx context.Context, playlistId, name string, ids []string) error {
|
2020-01-21 23:18:46 +01:00
|
|
|
owner := p.getUser(ctx)
|
2020-01-21 22:35:57 +01:00
|
|
|
var pls *model.Playlist
|
|
|
|
var err error
|
|
|
|
// If playlistID is present, override tracks
|
|
|
|
if playlistId != "" {
|
2020-01-27 15:41:33 +01:00
|
|
|
pls, err = p.ds.Playlist(ctx).Get(playlistId)
|
2020-01-21 22:35:57 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-01-21 23:18:46 +01:00
|
|
|
if owner != pls.Owner {
|
|
|
|
return model.ErrNotAuthorized
|
|
|
|
}
|
2020-01-21 22:35:57 +01:00
|
|
|
pls.Tracks = nil
|
|
|
|
} else {
|
|
|
|
pls = &model.Playlist{
|
|
|
|
Name: name,
|
|
|
|
Owner: owner,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, id := range ids {
|
|
|
|
pls.Tracks = append(pls.Tracks, model.MediaFile{ID: id})
|
|
|
|
}
|
|
|
|
|
2020-01-27 15:41:33 +01:00
|
|
|
return p.ds.Playlist(ctx).Put(pls)
|
2020-01-21 22:35:57 +01:00
|
|
|
}
|
|
|
|
|
2020-01-21 23:18:46 +01:00
|
|
|
func (p *playlists) getUser(ctx context.Context) string {
|
2020-03-01 02:01:09 +01:00
|
|
|
user, ok := ctx.Value("user").(model.User)
|
2020-01-21 23:18:46 +01:00
|
|
|
if ok {
|
2020-01-30 20:43:24 +01:00
|
|
|
return user.UserName
|
2020-01-21 23:18:46 +01:00
|
|
|
}
|
2020-01-30 20:43:24 +01:00
|
|
|
return ""
|
2020-01-21 23:18:46 +01:00
|
|
|
}
|
|
|
|
|
2020-01-21 22:35:57 +01:00
|
|
|
func (p *playlists) Delete(ctx context.Context, playlistId string) error {
|
2020-01-27 15:41:33 +01:00
|
|
|
pls, err := p.ds.Playlist(ctx).Get(playlistId)
|
2020-01-21 23:18:46 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
owner := p.getUser(ctx)
|
|
|
|
if owner != pls.Owner {
|
|
|
|
return model.ErrNotAuthorized
|
|
|
|
}
|
2020-04-26 18:06:38 +02:00
|
|
|
return p.ds.Playlist(ctx).Delete(playlistId)
|
2020-01-21 22:35:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *playlists) Update(ctx context.Context, playlistId string, name *string, idsToAdd []string, idxToRemove []int) error {
|
2020-01-27 15:41:33 +01:00
|
|
|
pls, err := p.ds.Playlist(ctx).Get(playlistId)
|
2020-03-20 05:02:31 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-01-21 23:18:46 +01:00
|
|
|
|
|
|
|
owner := p.getUser(ctx)
|
|
|
|
if owner != pls.Owner {
|
|
|
|
return model.ErrNotAuthorized
|
|
|
|
}
|
|
|
|
|
2020-01-21 22:35:57 +01:00
|
|
|
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
|
|
|
|
|
2020-01-27 15:41:33 +01:00
|
|
|
return p.ds.Playlist(ctx).Put(pls)
|
2020-01-21 22:35:57 +01:00
|
|
|
}
|
|
|
|
|
2020-01-22 14:32:31 +01:00
|
|
|
func (p *playlists) GetAll(ctx context.Context) (model.Playlists, error) {
|
2020-02-23 06:10:05 +01:00
|
|
|
all, err := p.ds.Playlist(ctx).GetAll(model.QueryOptions{})
|
|
|
|
for i := range all {
|
|
|
|
all[i].Public = true
|
|
|
|
}
|
|
|
|
return all, err
|
2016-03-09 16:09:15 +01:00
|
|
|
}
|
2016-03-10 00:28:11 +01:00
|
|
|
|
|
|
|
type PlaylistInfo struct {
|
2016-03-21 17:26:55 +01:00
|
|
|
Id string
|
|
|
|
Name string
|
|
|
|
Entries Entries
|
|
|
|
SongCount int
|
|
|
|
Duration int
|
|
|
|
Public bool
|
|
|
|
Owner string
|
2016-03-24 18:28:20 +01:00
|
|
|
Comment string
|
2020-04-11 22:45:21 +02:00
|
|
|
Created time.Time
|
|
|
|
Changed time.Time
|
2016-03-10 00:28:11 +01:00
|
|
|
}
|
|
|
|
|
2020-01-22 05:01:43 +01:00
|
|
|
func (p *playlists) Get(ctx context.Context, id string) (*PlaylistInfo, error) {
|
2020-04-12 01:05:51 +02:00
|
|
|
pl, err := p.ds.Playlist(ctx).Get(id)
|
2016-03-10 00:28:11 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-01-22 00:10:29 +01:00
|
|
|
// TODO Use model.Playlist when got rid of Entries
|
2020-01-31 04:07:02 +01:00
|
|
|
plsInfo := &PlaylistInfo{
|
2020-01-10 05:33:01 +01:00
|
|
|
Id: pl.ID,
|
2016-03-21 17:26:55 +01:00
|
|
|
Name: pl.Name,
|
2020-01-22 00:10:29 +01:00
|
|
|
SongCount: len(pl.Tracks),
|
2020-02-20 23:00:56 +01:00
|
|
|
Duration: int(pl.Duration),
|
2016-03-21 17:26:55 +01:00
|
|
|
Public: pl.Public,
|
|
|
|
Owner: pl.Owner,
|
2016-03-24 18:28:20 +01:00
|
|
|
Comment: pl.Comment,
|
2020-04-11 22:45:21 +02:00
|
|
|
Changed: pl.UpdatedAt,
|
|
|
|
Created: pl.CreatedAt,
|
2016-03-21 17:26:55 +01:00
|
|
|
}
|
2016-03-10 00:28:11 +01:00
|
|
|
|
2020-01-31 04:07:02 +01:00
|
|
|
plsInfo.Entries = FromMediaFiles(pl.Tracks)
|
|
|
|
return plsInfo, nil
|
2016-03-10 00:28:11 +01:00
|
|
|
}
|