2016-03-08 15:13:36 -09:00
|
|
|
package engine
|
|
|
|
|
|
|
|
|
|
import (
|
2020-01-21 19:01:43 -09:00
|
|
|
"context"
|
2016-03-17 05:34:32 -08:00
|
|
|
"time"
|
2016-03-08 17:54:32 -09:00
|
|
|
|
2020-01-30 17:48:07 -09:00
|
|
|
"github.com/Masterminds/squirrel"
|
2020-01-23 15:44:08 -09:00
|
|
|
"github.com/deluan/navidrome/model"
|
2016-03-08 15:13:36 -09:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type ListGenerator interface {
|
2020-01-21 19:01:43 -09:00
|
|
|
GetNewest(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetRecent(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetFrequent(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetHighest(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetRandom(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetByName(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetByArtist(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetStarred(ctx context.Context, offset int, size int) (Entries, error)
|
|
|
|
|
GetAllStarred(ctx context.Context) (artists Entries, albums Entries, mediaFiles Entries, err error)
|
|
|
|
|
GetNowPlaying(ctx context.Context) (Entries, error)
|
|
|
|
|
GetRandomSongs(ctx context.Context, size int, genre string) (Entries, error)
|
2016-03-08 15:13:36 -09:00
|
|
|
}
|
|
|
|
|
|
2020-01-19 11:37:41 -09:00
|
|
|
func NewListGenerator(ds model.DataStore, npRepo NowPlayingRepository) ListGenerator {
|
|
|
|
|
return &listGenerator{ds, npRepo}
|
2016-03-08 15:13:36 -09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type listGenerator struct {
|
2020-01-19 11:37:41 -09:00
|
|
|
ds model.DataStore
|
|
|
|
|
npRepo NowPlayingRepository
|
2016-03-08 15:13:36 -09:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 21:00:00 -09:00
|
|
|
func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions) (Entries, error) {
|
2020-01-27 05:41:33 -09:00
|
|
|
albums, err := g.ds.Album(ctx).GetAll(qo)
|
2020-01-21 19:01:43 -09:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
albumIds := make([]string, len(albums))
|
|
|
|
|
for i, al := range albums {
|
|
|
|
|
albumIds[i] = al.ID
|
|
|
|
|
}
|
2020-01-30 18:07:02 -09:00
|
|
|
return FromAlbums(albums), err
|
2020-01-21 21:00:00 -09:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetNewest(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-21 21:00:00 -09:00
|
|
|
qo := model.QueryOptions{Sort: "CreatedAt", Order: "desc", Offset: offset, Max: size}
|
|
|
|
|
return g.query(ctx, qo)
|
2016-03-08 15:13:36 -09:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetRecent(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-21 21:00:00 -09:00
|
|
|
qo := model.QueryOptions{Sort: "PlayDate", Order: "desc", Offset: offset, Max: size,
|
2020-01-30 17:48:07 -09:00
|
|
|
Filters: squirrel.Gt{"play_date": time.Time{}}}
|
2020-01-30 18:07:02 -09:00
|
|
|
return g.query(ctx, qo)
|
2016-03-08 15:13:36 -09:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetFrequent(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-21 21:00:00 -09:00
|
|
|
qo := model.QueryOptions{Sort: "PlayCount", Order: "desc", Offset: offset, Max: size,
|
2020-01-30 17:48:07 -09:00
|
|
|
Filters: squirrel.Gt{"play_count": 0}}
|
2020-01-30 18:07:02 -09:00
|
|
|
return g.query(ctx, qo)
|
2016-03-08 15:13:36 -09:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetHighest(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-21 21:00:00 -09:00
|
|
|
qo := model.QueryOptions{Sort: "Rating", Order: "desc", Offset: offset, Max: size,
|
2020-01-30 18:07:02 -09:00
|
|
|
Filters: squirrel.Gt{"rating": 0}}
|
|
|
|
|
return g.query(ctx, qo)
|
2016-03-08 15:13:36 -09:00
|
|
|
}
|
2016-03-08 17:54:32 -09:00
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetByName(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-21 21:00:00 -09:00
|
|
|
qo := model.QueryOptions{Sort: "Name", Offset: offset, Max: size}
|
|
|
|
|
return g.query(ctx, qo)
|
2016-03-21 13:37:12 -08:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetByArtist(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-21 21:00:00 -09:00
|
|
|
qo := model.QueryOptions{Sort: "Artist", Offset: offset, Max: size}
|
|
|
|
|
return g.query(ctx, qo)
|
2016-03-21 13:37:12 -08:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetRandom(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-27 05:41:33 -09:00
|
|
|
albums, err := g.ds.Album(ctx).GetRandom(model.QueryOptions{Max: size, Offset: offset})
|
2016-03-08 17:54:32 -09:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2020-01-21 04:49:43 -09:00
|
|
|
|
2020-01-30 18:07:02 -09:00
|
|
|
return FromAlbums(albums), nil
|
2016-03-08 17:54:32 -09:00
|
|
|
}
|
2016-03-14 07:35:48 -08:00
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetRandomSongs(ctx context.Context, size int, genre string) (Entries, error) {
|
2020-01-21 04:49:43 -09:00
|
|
|
options := model.QueryOptions{Max: size}
|
|
|
|
|
if genre != "" {
|
2020-01-30 17:48:07 -09:00
|
|
|
options.Filters = squirrel.Eq{"genre": genre}
|
2020-01-21 04:49:43 -09:00
|
|
|
}
|
2020-01-27 05:41:33 -09:00
|
|
|
mediaFiles, err := g.ds.MediaFile(ctx).GetRandom(options)
|
2016-03-28 20:01:27 -08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2020-01-21 04:49:43 -09:00
|
|
|
|
2020-01-30 18:07:02 -09:00
|
|
|
return FromMediaFiles(mediaFiles), nil
|
2016-03-28 20:01:27 -08:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetStarred(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-19 18:36:15 -09:00
|
|
|
qo := model.QueryOptions{Offset: offset, Max: size, Sort: "starred_at", Order: "desc"}
|
2020-01-30 18:07:02 -09:00
|
|
|
albums, err := g.ds.Album(ctx).GetStarred(qo)
|
2016-03-14 07:35:48 -08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-30 18:07:02 -09:00
|
|
|
return FromAlbums(albums), nil
|
2016-03-14 07:35:48 -08:00
|
|
|
}
|
2016-03-17 05:34:32 -08:00
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetAllStarred(ctx context.Context) (artists Entries, albums Entries, mediaFiles Entries, err error) {
|
2020-01-20 10:17:14 -09:00
|
|
|
options := model.QueryOptions{Sort: "starred_at", Order: "desc"}
|
|
|
|
|
|
2020-01-30 18:07:02 -09:00
|
|
|
ars, err := g.ds.Artist(ctx).GetStarred(options)
|
2020-01-18 16:03:52 -09:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-30 18:07:02 -09:00
|
|
|
als, err := g.ds.Album(ctx).GetStarred(options)
|
2016-03-23 15:02:58 -08:00
|
|
|
if err != nil {
|
2020-01-18 16:03:52 -09:00
|
|
|
return nil, nil, nil, err
|
2016-03-23 15:02:58 -08:00
|
|
|
}
|
|
|
|
|
|
2020-01-30 18:07:02 -09:00
|
|
|
mfs, err := g.ds.MediaFile(ctx).GetStarred(options)
|
2020-01-21 19:01:43 -09:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var mfIds []string
|
|
|
|
|
for _, mf := range mfs {
|
|
|
|
|
mfIds = append(mfIds, mf.ID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var artistIds []string
|
|
|
|
|
for _, ar := range ars {
|
|
|
|
|
artistIds = append(artistIds, ar.ID)
|
|
|
|
|
}
|
2016-03-23 15:02:58 -08:00
|
|
|
|
2020-01-30 18:07:02 -09:00
|
|
|
artists = FromArtists(ars)
|
|
|
|
|
albums = FromAlbums(als)
|
|
|
|
|
mediaFiles = FromMediaFiles(mfs)
|
2020-01-20 10:17:14 -09:00
|
|
|
|
|
|
|
|
return
|
2016-03-23 15:02:58 -08:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:01:43 -09:00
|
|
|
func (g *listGenerator) GetNowPlaying(ctx context.Context) (Entries, error) {
|
2016-03-17 05:34:32 -08:00
|
|
|
npInfo, err := g.npRepo.GetAll()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2016-03-23 06:06:26 -08:00
|
|
|
entries := make(Entries, len(npInfo))
|
|
|
|
|
for i, np := range npInfo {
|
2020-01-27 05:41:33 -09:00
|
|
|
mf, err := g.ds.MediaFile(ctx).Get(np.TrackID)
|
2016-03-17 05:34:32 -08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2020-01-30 18:07:02 -09:00
|
|
|
entries[i] = FromMediaFile(mf)
|
2016-03-17 06:37:19 -08:00
|
|
|
entries[i].UserName = np.Username
|
2016-03-17 05:34:32 -08:00
|
|
|
entries[i].MinutesAgo = int(time.Now().Sub(np.Start).Minutes())
|
|
|
|
|
entries[i].PlayerId = np.PlayerId
|
|
|
|
|
entries[i].PlayerName = np.PlayerName
|
|
|
|
|
|
|
|
|
|
}
|
2016-03-19 18:58:20 -08:00
|
|
|
return entries, nil
|
2016-03-17 05:34:32 -08:00
|
|
|
}
|