quintodrome/engine/list_generator.go

200 lines
4.9 KiB
Go
Raw Normal View History

package engine
import (
2020-01-21 19:01:43 -09:00
"context"
"time"
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"
)
type ListGenerator interface {
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)
2020-04-17 16:52:50 -08:00
GetSongsByGenre(ctx context.Context, offset int, count int, genre string) (Entries, error)
GetAlbums(ctx context.Context, offset, size int, filter AlbumFilter) (Entries, error)
}
func NewListGenerator(ds model.DataStore, npRepo NowPlayingRepository) ListGenerator {
return &listGenerator{ds, npRepo}
}
type AlbumFilter model.QueryOptions
func ByNewest() AlbumFilter {
return AlbumFilter{Sort: "createdAt", Order: "desc"}
}
func ByRecent() AlbumFilter {
return AlbumFilter{Sort: "playDate", Order: "desc", Filters: squirrel.Gt{"play_date": time.Time{}}}
}
func ByFrequent() AlbumFilter {
return AlbumFilter{Sort: "playCount", Order: "desc", Filters: squirrel.Gt{"play_count": 0}}
}
func ByRandom() AlbumFilter {
return AlbumFilter{Sort: "random()"}
}
func ByName() AlbumFilter {
return AlbumFilter{Sort: "name"}
}
func ByArtist() AlbumFilter {
return AlbumFilter{Sort: "artist"}
}
func ByStarred() AlbumFilter {
return AlbumFilter{Sort: "starred_at", Order: "desc", Filters: squirrel.Eq{"starred": true}}
}
func ByRating() AlbumFilter {
return AlbumFilter{Sort: "Rating", Order: "desc", Filters: squirrel.Gt{"rating": 0}}
}
func ByGenre(genre string) AlbumFilter {
return AlbumFilter{
Sort: "genre asc, name asc",
Filters: squirrel.Eq{"genre": genre},
}
}
func ByYear(fromYear, toYear int) AlbumFilter {
return AlbumFilter{
Sort: "max_year, name",
Filters: squirrel.Or{
squirrel.And{
squirrel.LtOrEq{"min_year": toYear},
squirrel.GtOrEq{"max_year": toYear},
},
squirrel.And{
squirrel.LtOrEq{"min_year": fromYear},
squirrel.GtOrEq{"max_year": fromYear},
},
},
}
}
type listGenerator struct {
ds model.DataStore
npRepo NowPlayingRepository
}
2020-01-21 21:00:00 -09:00
func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions) (Entries, error) {
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
}
return FromAlbums(albums), err
2020-01-21 21:00:00 -09:00
}
2020-01-21 19:01:43 -09:00
func (g *listGenerator) GetRandomSongs(ctx context.Context, size int, genre string) (Entries, error) {
options := model.QueryOptions{Max: size}
if genre != "" {
2020-01-30 17:48:07 -09:00
options.Filters = squirrel.Eq{"genre": genre}
}
mediaFiles, err := g.ds.MediaFile(ctx).GetRandom(options)
if err != nil {
return nil, err
}
return FromMediaFiles(mediaFiles), nil
}
2020-04-17 16:52:50 -08:00
func (g *listGenerator) GetSongsByGenre(ctx context.Context, offset int, count int, genre string) (Entries, error) {
options := model.QueryOptions{Offset: offset, Max: count}
if genre != "" {
options.Filters = squirrel.Eq{"genre": genre}
}
mediaFiles, err := g.ds.MediaFile(ctx).GetAll(options)
if err != nil {
return nil, err
}
return FromMediaFiles(mediaFiles), nil
}
func (g *listGenerator) GetAlbums(ctx context.Context, offset, size int, filter AlbumFilter) (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-21 19:01:43 -09: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-21 19:01:43 -09: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-23 15:02:58 -08:00
if err != nil {
return nil, nil, nil, err
2016-03-23 15:02:58 -08: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
artists = FromArtists(ars)
albums = FromAlbums(als)
mediaFiles = FromMediaFiles(mfs)
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) {
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 06:37:19 -08: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
}