navidrome/engine/list_generator.go

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

210 lines
4.9 KiB
Go
Raw Normal View History

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