Refactor list_generator to use new filters

This commit is contained in:
Deluan 2020-04-17 20:29:10 -04:00 committed by Deluan Quintão
parent 95f658336c
commit a698e434fd
3 changed files with 64 additions and 103 deletions

View File

@ -8,8 +8,51 @@ import (
"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)
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",
@ -19,7 +62,7 @@ func ByGenre(genre string) AlbumFilter {
func ByYear(fromYear, toYear int) AlbumFilter {
return AlbumFilter{
Sort: "max_year",
Sort: "max_year, name",
Filters: squirrel.Or{
squirrel.And{
squirrel.LtOrEq{"min_year": toYear},
@ -33,25 +76,6 @@ func ByYear(fromYear, toYear int) AlbumFilter {
}
}
type ListGenerator interface {
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)
GetAlbums(ctx context.Context, offset, size int, filter AlbumFilter) (Entries, error)
}
func NewListGenerator(ds model.DataStore, npRepo NowPlayingRepository) ListGenerator {
return &listGenerator{ds, npRepo}
}
type listGenerator struct {
ds model.DataStore
npRepo NowPlayingRepository
@ -69,48 +93,6 @@ func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions) (Entri
return FromAlbums(albums), err
}
func (g *listGenerator) GetNewest(ctx context.Context, offset int, size int) (Entries, error) {
qo := model.QueryOptions{Sort: "CreatedAt", Order: "desc", Offset: offset, Max: size}
return g.query(ctx, qo)
}
func (g *listGenerator) GetRecent(ctx context.Context, offset int, size int) (Entries, error) {
qo := model.QueryOptions{Sort: "PlayDate", Order: "desc", Offset: offset, Max: size,
Filters: squirrel.Gt{"play_date": time.Time{}}}
return g.query(ctx, qo)
}
func (g *listGenerator) GetFrequent(ctx context.Context, offset int, size int) (Entries, error) {
qo := model.QueryOptions{Sort: "PlayCount", Order: "desc", Offset: offset, Max: size,
Filters: squirrel.Gt{"play_count": 0}}
return g.query(ctx, qo)
}
func (g *listGenerator) GetHighest(ctx context.Context, offset int, size int) (Entries, error) {
qo := model.QueryOptions{Sort: "Rating", Order: "desc", Offset: offset, Max: size,
Filters: squirrel.Gt{"rating": 0}}
return g.query(ctx, qo)
}
func (g *listGenerator) GetByName(ctx context.Context, offset int, size int) (Entries, error) {
qo := model.QueryOptions{Sort: "Name", Offset: offset, Max: size}
return g.query(ctx, qo)
}
func (g *listGenerator) GetByArtist(ctx context.Context, offset int, size int) (Entries, error) {
qo := model.QueryOptions{Sort: "Artist", Offset: offset, Max: size}
return g.query(ctx, qo)
}
func (g *listGenerator) GetRandom(ctx context.Context, offset int, size int) (Entries, error) {
albums, err := g.ds.Album(ctx).GetRandom(model.QueryOptions{Max: size, Offset: offset})
if err != nil {
return nil, err
}
return FromAlbums(albums), nil
}
func (g *listGenerator) GetRandomSongs(ctx context.Context, size int, genre string) (Entries, error) {
options := model.QueryOptions{Max: size}
if genre != "" {

View File

@ -1,7 +1,6 @@
package subsonic
import (
"context"
"errors"
"net/http"
@ -12,53 +11,16 @@ import (
)
type AlbumListController struct {
listGen engine.ListGenerator
listFunctions map[string]strategy
listGen engine.ListGenerator
}
func NewAlbumListController(listGen engine.ListGenerator) *AlbumListController {
c := &AlbumListController{
listGen: listGen,
}
c.listFunctions = map[string]strategy{
"random": c.listGen.GetRandom,
"newest": c.listGen.GetNewest,
"recent": c.listGen.GetRecent,
"frequent": c.listGen.GetFrequent,
"highest": c.listGen.GetHighest,
"alphabeticalByName": c.listGen.GetByName,
"alphabeticalByArtist": c.listGen.GetByArtist,
"starred": c.listGen.GetStarred,
}
return c
}
type strategy func(ctx context.Context, offset int, size int) (engine.Entries, error)
func (c *AlbumListController) getAlbumList(r *http.Request) (engine.Entries, error) {
typ, err := RequiredParamString(r, "type", "Required string parameter 'type' is not present")
if err != nil {
return nil, err
}
listFunc, found := c.listFunctions[typ]
if !found {
log.Error(r, "albumList type not implemented", "type", typ)
return nil, errors.New("Not implemented!")
}
offset := utils.ParamInt(r, "offset", 0)
size := utils.MinInt(utils.ParamInt(r, "size", 10), 500)
albums, err := listFunc(r.Context(), offset, size)
if err != nil {
log.Error(r, "Error retrieving albums", "error", err)
return nil, errors.New("Internal Error")
}
return albums, nil
}
func (c *AlbumListController) getNewAlbumList(r *http.Request) (engine.Entries, error) {
typ, err := RequiredParamString(r, "type", "Required string parameter 'type' is not present")
if err != nil {
@ -67,12 +29,29 @@ func (c *AlbumListController) getNewAlbumList(r *http.Request) (engine.Entries,
var filter engine.AlbumFilter
switch typ {
case "newest":
filter = engine.ByNewest()
case "recent":
filter = engine.ByRecent()
case "random":
filter = engine.ByRandom()
case "alphabeticalByName":
filter = engine.ByName()
case "alphabeticalByArtist":
filter = engine.ByArtist()
case "frequent":
filter = engine.ByFrequent()
case "starred":
filter = engine.ByStarred()
case "highest":
filter = engine.ByRating()
case "byGenre":
filter = engine.ByGenre(utils.ParamString(r, "genre"))
case "byYear":
filter = engine.ByYear(utils.ParamInt(r, "fromYear", 0), utils.ParamInt(r, "toYear", 0))
default:
return c.getAlbumList(r)
log.Error(r, "albumList type not implemented", "type", typ)
return nil, errors.New("Not implemented!")
}
offset := utils.ParamInt(r, "offset", 0)

View File

@ -18,7 +18,7 @@ type fakeListGen struct {
recvSize int
}
func (lg *fakeListGen) GetNewest(ctx context.Context, offset int, size int) (engine.Entries, error) {
func (lg *fakeListGen) GetAlbums(ctx context.Context, offset int, size int, filter engine.AlbumFilter) (engine.Entries, error) {
if lg.err != nil {
return nil, lg.err
}