2016-03-08 19:13:36 -05:00
|
|
|
package engine
|
|
|
|
|
|
|
|
|
|
import (
|
2020-01-21 23:01:43 -05:00
|
|
|
"context"
|
2016-03-17 09:34:32 -04:00
|
|
|
"time"
|
2016-03-08 21:54:32 -05:00
|
|
|
|
2020-01-30 21:48:07 -05:00
|
|
|
"github.com/Masterminds/squirrel"
|
2020-01-23 19:44:08 -05:00
|
|
|
"github.com/deluan/navidrome/model"
|
2016-03-08 19:13:36 -05:00
|
|
|
)
|
|
|
|
|
|
2020-04-17 20:29:10 -04:00
|
|
|
type ListGenerator interface {
|
|
|
|
|
GetAllStarred(ctx context.Context) (artists Entries, albums Entries, mediaFiles Entries, err error)
|
|
|
|
|
GetNowPlaying(ctx context.Context) (Entries, error)
|
2020-04-17 21:18:04 -04:00
|
|
|
GetSongs(ctx context.Context, offset, size int, filter ListFilter) (Entries, error)
|
|
|
|
|
GetAlbums(ctx context.Context, offset, size int, filter ListFilter) (Entries, error)
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewListGenerator(ds model.DataStore, npRepo NowPlayingRepository) ListGenerator {
|
|
|
|
|
return &listGenerator{ds, npRepo}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
type ListFilter model.QueryOptions
|
2020-04-17 19:57:26 -04:00
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByNewest() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "createdAt", Order: "desc"}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByRecent() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "playDate", Order: "desc", Filters: squirrel.Gt{"play_date": time.Time{}}}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByFrequent() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "playCount", Order: "desc", Filters: squirrel.Gt{"play_count": 0}}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByRandom() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "random()"}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByName() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "name"}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByArtist() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "artist"}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByStarred() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "starred_at", Order: "desc", Filters: squirrel.Eq{"starred": true}}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByRating() ListFilter {
|
|
|
|
|
return ListFilter{Sort: "Rating", Order: "desc", Filters: squirrel.Gt{"rating": 0}}
|
2020-04-17 20:29:10 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByGenre(genre string) ListFilter {
|
|
|
|
|
return ListFilter{
|
2020-04-17 19:57:26 -04:00
|
|
|
Sort: "genre asc, name asc",
|
|
|
|
|
Filters: squirrel.Eq{"genre": genre},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func ByYear(fromYear, toYear int) ListFilter {
|
|
|
|
|
return ListFilter{
|
2020-04-17 20:29:10 -04:00
|
|
|
Sort: "max_year, name",
|
2020-04-17 19:57:26 -04:00
|
|
|
Filters: squirrel.Or{
|
|
|
|
|
squirrel.And{
|
2020-04-18 14:05:44 -04:00
|
|
|
squirrel.GtOrEq{"min_year": fromYear},
|
2020-04-17 19:57:26 -04:00
|
|
|
squirrel.LtOrEq{"min_year": toYear},
|
|
|
|
|
},
|
|
|
|
|
squirrel.And{
|
|
|
|
|
squirrel.GtOrEq{"max_year": fromYear},
|
2020-04-18 14:05:44 -04:00
|
|
|
squirrel.LtOrEq{"max_year": toYear},
|
2020-04-17 19:57:26 -04:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:27:58 -04:00
|
|
|
func SongsByGenre(genre string) ListFilter {
|
|
|
|
|
return ListFilter{
|
|
|
|
|
Sort: "genre asc, title asc",
|
|
|
|
|
Filters: squirrel.Eq{"genre": genre},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SongsByRandom(genre string, fromYear, toYear int) ListFilter {
|
2020-04-17 21:18:04 -04:00
|
|
|
options := ListFilter{
|
|
|
|
|
Sort: "random()",
|
|
|
|
|
}
|
|
|
|
|
ff := squirrel.And{}
|
|
|
|
|
if genre != "" {
|
2020-04-19 13:37:25 -04:00
|
|
|
ff = append(ff, squirrel.Eq{"genre": genre})
|
2020-04-17 21:18:04 -04:00
|
|
|
}
|
|
|
|
|
if fromYear != 0 {
|
2020-04-19 13:37:25 -04:00
|
|
|
ff = append(ff, squirrel.GtOrEq{"year": fromYear})
|
2020-04-17 21:18:04 -04:00
|
|
|
}
|
|
|
|
|
if toYear != 0 {
|
2020-04-19 13:37:25 -04:00
|
|
|
ff = append(ff, squirrel.LtOrEq{"year": toYear})
|
2020-04-17 21:18:04 -04:00
|
|
|
}
|
|
|
|
|
options.Filters = ff
|
|
|
|
|
return options
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-08 19:13:36 -05:00
|
|
|
type listGenerator struct {
|
2020-01-19 15:37:41 -05:00
|
|
|
ds model.DataStore
|
|
|
|
|
npRepo NowPlayingRepository
|
2016-03-08 19:13:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func (g *listGenerator) GetSongs(ctx context.Context, offset, size int, filter ListFilter) (Entries, error) {
|
|
|
|
|
qo := model.QueryOptions(filter)
|
|
|
|
|
qo.Offset = offset
|
|
|
|
|
qo.Max = size
|
|
|
|
|
mediaFiles, err := g.ds.MediaFile(ctx).GetAll(qo)
|
2020-04-17 20:52:50 -04:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FromMediaFiles(mediaFiles), nil
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-17 21:18:04 -04:00
|
|
|
func (g *listGenerator) GetAlbums(ctx context.Context, offset, size int, filter ListFilter) (Entries, error) {
|
2020-04-17 19:57:26 -04:00
|
|
|
qo := model.QueryOptions(filter)
|
|
|
|
|
qo.Offset = offset
|
|
|
|
|
qo.Max = size
|
|
|
|
|
albums, err := g.ds.Album(ctx).GetAll(qo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FromAlbums(albums), nil
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-21 23:01:43 -05:00
|
|
|
func (g *listGenerator) GetStarred(ctx context.Context, offset int, size int) (Entries, error) {
|
2020-01-19 22:36:15 -05:00
|
|
|
qo := model.QueryOptions{Offset: offset, Max: size, Sort: "starred_at", Order: "desc"}
|
2020-01-30 22:07:02 -05:00
|
|
|
albums, err := g.ds.Album(ctx).GetStarred(qo)
|
2016-03-14 11:35:48 -04:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-30 22:07:02 -05:00
|
|
|
return FromAlbums(albums), nil
|
2016-03-14 11:35:48 -04:00
|
|
|
}
|
2016-03-17 09:34:32 -04:00
|
|
|
|
2020-01-21 23:01:43 -05:00
|
|
|
func (g *listGenerator) GetAllStarred(ctx context.Context) (artists Entries, albums Entries, mediaFiles Entries, err error) {
|
2020-01-20 14:17:14 -05:00
|
|
|
options := model.QueryOptions{Sort: "starred_at", Order: "desc"}
|
|
|
|
|
|
2020-01-30 22:07:02 -05:00
|
|
|
ars, err := g.ds.Artist(ctx).GetStarred(options)
|
2020-01-18 20:03:52 -05:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-30 22:07:02 -05:00
|
|
|
als, err := g.ds.Album(ctx).GetStarred(options)
|
2016-03-23 19:02:58 -04:00
|
|
|
if err != nil {
|
2020-01-18 20:03:52 -05:00
|
|
|
return nil, nil, nil, err
|
2016-03-23 19:02:58 -04:00
|
|
|
}
|
|
|
|
|
|
2020-01-30 22:07:02 -05:00
|
|
|
mfs, err := g.ds.MediaFile(ctx).GetStarred(options)
|
2020-01-21 23:01:43 -05:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-30 22:07:02 -05:00
|
|
|
artists = FromArtists(ars)
|
|
|
|
|
albums = FromAlbums(als)
|
|
|
|
|
mediaFiles = FromMediaFiles(mfs)
|
2020-01-20 14:17:14 -05:00
|
|
|
|
|
|
|
|
return
|
2016-03-23 19:02:58 -04:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 23:01:43 -05:00
|
|
|
func (g *listGenerator) GetNowPlaying(ctx context.Context) (Entries, error) {
|
2016-03-17 09:34:32 -04:00
|
|
|
npInfo, err := g.npRepo.GetAll()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2016-03-23 10:06:26 -04:00
|
|
|
entries := make(Entries, len(npInfo))
|
|
|
|
|
for i, np := range npInfo {
|
2020-01-27 09:41:33 -05:00
|
|
|
mf, err := g.ds.MediaFile(ctx).Get(np.TrackID)
|
2016-03-17 09:34:32 -04:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2020-01-30 22:07:02 -05:00
|
|
|
entries[i] = FromMediaFile(mf)
|
2016-03-17 10:37:19 -04:00
|
|
|
entries[i].UserName = np.Username
|
2020-04-26 11:56:43 -04:00
|
|
|
entries[i].MinutesAgo = int(time.Since(np.Start).Minutes())
|
2016-03-17 09:34:32 -04:00
|
|
|
entries[i].PlayerId = np.PlayerId
|
|
|
|
|
entries[i].PlayerName = np.PlayerName
|
|
|
|
|
}
|
2016-03-19 22:58:20 -04:00
|
|
|
return entries, nil
|
2016-03-17 09:34:32 -04:00
|
|
|
}
|