2020-01-15 00:23:29 +01:00
|
|
|
package persistence
|
2020-01-13 03:59:06 +01:00
|
|
|
|
|
|
|
import (
|
2020-01-28 14:22:17 +01:00
|
|
|
"context"
|
2020-01-13 03:59:06 +01:00
|
|
|
"strings"
|
2020-04-11 22:45:21 +02:00
|
|
|
"time"
|
2020-01-13 03:59:06 +01:00
|
|
|
|
2020-01-28 14:22:17 +01:00
|
|
|
. "github.com/Masterminds/squirrel"
|
2020-01-13 03:59:06 +01:00
|
|
|
"github.com/astaxie/beego/orm"
|
2020-04-11 22:45:21 +02:00
|
|
|
"github.com/deluan/navidrome/log"
|
2020-01-24 01:44:08 +01:00
|
|
|
"github.com/deluan/navidrome/model"
|
2020-01-13 03:59:06 +01:00
|
|
|
)
|
|
|
|
|
2020-01-18 03:03:54 +01:00
|
|
|
type playlist struct {
|
2020-04-11 22:45:21 +02:00
|
|
|
ID string `orm:"column(id)"`
|
|
|
|
Name string
|
|
|
|
Comment string
|
|
|
|
Duration float32
|
|
|
|
Owner string
|
|
|
|
Public bool
|
|
|
|
Tracks string
|
|
|
|
CreatedAt time.Time
|
|
|
|
UpdatedAt time.Time
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type playlistRepository struct {
|
|
|
|
sqlRepository
|
|
|
|
}
|
|
|
|
|
2020-01-28 14:22:17 +01:00
|
|
|
func NewPlaylistRepository(ctx context.Context, o orm.Ormer) model.PlaylistRepository {
|
2020-01-13 03:59:06 +01:00
|
|
|
r := &playlistRepository{}
|
2020-01-28 14:22:17 +01:00
|
|
|
r.ctx = ctx
|
2020-01-19 21:37:41 +01:00
|
|
|
r.ormer = o
|
2020-01-13 06:04:11 +01:00
|
|
|
r.tableName = "playlist"
|
2020-01-13 03:59:06 +01:00
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
2020-01-28 14:22:17 +01:00
|
|
|
func (r *playlistRepository) CountAll() (int64, error) {
|
|
|
|
return r.count(Select())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *playlistRepository) Exists(id string) (bool, error) {
|
|
|
|
return r.exists(Select().Where(Eq{"id": id}))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *playlistRepository) Delete(id string) error {
|
|
|
|
return r.delete(Eq{"id": id})
|
|
|
|
}
|
|
|
|
|
2020-01-15 04:22:34 +01:00
|
|
|
func (r *playlistRepository) Put(p *model.Playlist) error {
|
2020-04-11 22:45:21 +02:00
|
|
|
if p.ID == "" {
|
|
|
|
p.CreatedAt = time.Now()
|
|
|
|
}
|
|
|
|
p.UpdatedAt = time.Now()
|
2020-01-31 15:53:19 +01:00
|
|
|
pls := r.fromModel(p)
|
2020-01-31 21:35:06 +01:00
|
|
|
_, err := r.put(pls.ID, pls)
|
|
|
|
return err
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 04:22:34 +01:00
|
|
|
func (r *playlistRepository) Get(id string) (*model.Playlist, error) {
|
2020-01-28 14:22:17 +01:00
|
|
|
sel := r.newSelect().Columns("*").Where(Eq{"id": id})
|
|
|
|
var res playlist
|
|
|
|
err := r.queryOne(sel, &res)
|
|
|
|
pls := r.toModel(&res)
|
2020-01-22 00:10:29 +01:00
|
|
|
return &pls, err
|
|
|
|
}
|
|
|
|
|
2020-01-15 04:22:34 +01:00
|
|
|
func (r *playlistRepository) GetAll(options ...model.QueryOptions) (model.Playlists, error) {
|
2020-01-28 14:22:17 +01:00
|
|
|
sel := r.newSelect(options...).Columns("*")
|
|
|
|
var res []playlist
|
|
|
|
err := r.queryAll(sel, &res)
|
|
|
|
return r.toModels(res), err
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
|
|
|
|
2020-01-28 14:22:17 +01:00
|
|
|
func (r *playlistRepository) toModels(all []playlist) model.Playlists {
|
2020-01-15 04:22:34 +01:00
|
|
|
result := make(model.Playlists, len(all))
|
2020-01-13 03:59:06 +01:00
|
|
|
for i, p := range all {
|
2020-01-21 23:50:56 +01:00
|
|
|
result[i] = r.toModel(&p)
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
2020-01-28 14:22:17 +01:00
|
|
|
return result
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
|
|
|
|
2020-01-21 23:50:56 +01:00
|
|
|
func (r *playlistRepository) toModel(p *playlist) model.Playlist {
|
2020-01-21 22:35:57 +01:00
|
|
|
pls := model.Playlist{
|
2020-04-11 22:45:21 +02:00
|
|
|
ID: p.ID,
|
|
|
|
Name: p.Name,
|
|
|
|
Comment: p.Comment,
|
|
|
|
Duration: p.Duration,
|
|
|
|
Owner: p.Owner,
|
|
|
|
Public: p.Public,
|
|
|
|
CreatedAt: p.CreatedAt,
|
|
|
|
UpdatedAt: p.UpdatedAt,
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
2020-01-21 22:35:57 +01:00
|
|
|
if strings.TrimSpace(p.Tracks) != "" {
|
|
|
|
tracks := strings.Split(p.Tracks, ",")
|
|
|
|
for _, t := range tracks {
|
|
|
|
pls.Tracks = append(pls.Tracks, model.MediaFile{ID: t})
|
|
|
|
}
|
|
|
|
}
|
2020-04-11 22:45:21 +02:00
|
|
|
pls.Tracks = r.loadTracks(&pls)
|
2020-01-21 22:35:57 +01:00
|
|
|
return pls
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
|
|
|
|
2020-01-21 23:50:56 +01:00
|
|
|
func (r *playlistRepository) fromModel(p *model.Playlist) playlist {
|
2020-01-21 22:35:57 +01:00
|
|
|
pls := playlist{
|
2020-04-11 22:45:21 +02:00
|
|
|
ID: p.ID,
|
|
|
|
Name: p.Name,
|
|
|
|
Comment: p.Comment,
|
|
|
|
Owner: p.Owner,
|
|
|
|
Public: p.Public,
|
|
|
|
CreatedAt: p.CreatedAt,
|
|
|
|
UpdatedAt: p.UpdatedAt,
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
2020-04-11 22:45:21 +02:00
|
|
|
p.Tracks = r.loadTracks(p)
|
2020-01-21 22:35:57 +01:00
|
|
|
var newTracks []string
|
|
|
|
for _, t := range p.Tracks {
|
|
|
|
newTracks = append(newTracks, t.ID)
|
2020-04-11 22:45:21 +02:00
|
|
|
pls.Duration += t.Duration
|
2020-01-21 22:35:57 +01:00
|
|
|
}
|
|
|
|
pls.Tracks = strings.Join(newTracks, ",")
|
|
|
|
return pls
|
2020-01-13 03:59:06 +01:00
|
|
|
}
|
|
|
|
|
2020-04-11 22:45:21 +02:00
|
|
|
func (r *playlistRepository) loadTracks(p *model.Playlist) model.MediaFiles {
|
|
|
|
mfRepo := NewMediaFileRepository(r.ctx, r.ormer)
|
|
|
|
var ids []string
|
|
|
|
for _, t := range p.Tracks {
|
|
|
|
ids = append(ids, t.ID)
|
|
|
|
}
|
|
|
|
idsFilter := Eq{"id": ids}
|
|
|
|
tracks, err := mfRepo.GetAll(model.QueryOptions{Filters: idsFilter})
|
|
|
|
if err == nil {
|
|
|
|
return tracks
|
|
|
|
} else {
|
|
|
|
log.Error(r.ctx, "Could not load playlist's tracks", "playlistName", p.Name, "playlistId", p.ID, err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-01-15 04:22:34 +01:00
|
|
|
var _ model.PlaylistRepository = (*playlistRepository)(nil)
|