navidrome/engine/list_generator.go
2016-03-20 13:33:59 -04:00

112 lines
2.9 KiB
Go

package engine
import (
"math/rand"
"time"
"github.com/deluan/gosonic/domain"
"github.com/deluan/gosonic/utils"
)
// TODO Use Entries instead of Albums
type ListGenerator interface {
GetNewest(offset int, size int) (domain.Albums, error)
GetRecent(offset int, size int) (domain.Albums, error)
GetFrequent(offset int, size int) (domain.Albums, error)
GetHighest(offset int, size int) (domain.Albums, error)
GetRandom(offset int, size int) (domain.Albums, error)
GetStarred() (Entries, error)
GetNowPlaying() (Entries, error)
}
func NewListGenerator(alr domain.AlbumRepository, mfr domain.MediaFileRepository, npr NowPlayingRepository) ListGenerator {
return listGenerator{alr, mfr, npr}
}
type listGenerator struct {
albumRepo domain.AlbumRepository
mfRepository domain.MediaFileRepository
npRepo NowPlayingRepository
}
func (g listGenerator) query(qo domain.QueryOptions, offset int, size int) (domain.Albums, error) {
qo.Offset = offset
qo.Size = size
return g.albumRepo.GetAll(qo)
}
func (g listGenerator) GetNewest(offset int, size int) (domain.Albums, error) {
qo := domain.QueryOptions{SortBy: "CreatedAt", Desc: true, Alpha: true}
return g.query(qo, offset, size)
}
func (g listGenerator) GetRecent(offset int, size int) (domain.Albums, error) {
qo := domain.QueryOptions{SortBy: "PlayDate", Desc: true, Alpha: true}
return g.query(qo, offset, size)
}
func (g listGenerator) GetFrequent(offset int, size int) (domain.Albums, error) {
qo := domain.QueryOptions{SortBy: "PlayCount", Desc: true}
return g.query(qo, offset, size)
}
func (g listGenerator) GetHighest(offset int, size int) (domain.Albums, error) {
qo := domain.QueryOptions{SortBy: "Rating", Desc: true}
return g.query(qo, offset, size)
}
func (g listGenerator) GetRandom(offset int, size int) (domain.Albums, error) {
ids, err := g.albumRepo.GetAllIds()
if err != nil {
return nil, err
}
size = utils.MinInt(size, len(ids))
perm := rand.Perm(size)
r := make(domain.Albums, size)
for i := 0; i < size; i++ {
v := perm[i]
al, err := g.albumRepo.Get((ids)[v])
if err != nil {
return nil, err
}
r[i] = *al
}
return r, nil
}
func (g listGenerator) GetStarred() (Entries, error) {
albums, err := g.albumRepo.GetStarred(domain.QueryOptions{})
if err != nil {
return nil, err
}
entries := make(Entries, len(albums))
for i, al := range albums {
entries[i] = FromAlbum(&al)
}
return entries, nil
}
func (g listGenerator) GetNowPlaying() (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.mfRepository.Get(np.TrackId)
if err != nil {
return nil, err
}
entries[i] = FromMediaFile(mf)
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
}