Refactor list_generator to use new filters
This commit is contained in:
+44
-62
@@ -8,8 +8,51 @@ import (
|
|||||||
"github.com/deluan/navidrome/model"
|
"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
|
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 {
|
func ByGenre(genre string) AlbumFilter {
|
||||||
return AlbumFilter{
|
return AlbumFilter{
|
||||||
Sort: "genre asc, name asc",
|
Sort: "genre asc, name asc",
|
||||||
@@ -19,7 +62,7 @@ func ByGenre(genre string) AlbumFilter {
|
|||||||
|
|
||||||
func ByYear(fromYear, toYear int) AlbumFilter {
|
func ByYear(fromYear, toYear int) AlbumFilter {
|
||||||
return AlbumFilter{
|
return AlbumFilter{
|
||||||
Sort: "max_year",
|
Sort: "max_year, name",
|
||||||
Filters: squirrel.Or{
|
Filters: squirrel.Or{
|
||||||
squirrel.And{
|
squirrel.And{
|
||||||
squirrel.LtOrEq{"min_year": toYear},
|
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 {
|
type listGenerator struct {
|
||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
npRepo NowPlayingRepository
|
npRepo NowPlayingRepository
|
||||||
@@ -69,48 +93,6 @@ func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions) (Entri
|
|||||||
return FromAlbums(albums), err
|
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) {
|
func (g *listGenerator) GetRandomSongs(ctx context.Context, size int, genre string) (Entries, error) {
|
||||||
options := model.QueryOptions{Max: size}
|
options := model.QueryOptions{Max: size}
|
||||||
if genre != "" {
|
if genre != "" {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package subsonic
|
package subsonic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@@ -13,52 +12,15 @@ import (
|
|||||||
|
|
||||||
type AlbumListController struct {
|
type AlbumListController struct {
|
||||||
listGen engine.ListGenerator
|
listGen engine.ListGenerator
|
||||||
listFunctions map[string]strategy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlbumListController(listGen engine.ListGenerator) *AlbumListController {
|
func NewAlbumListController(listGen engine.ListGenerator) *AlbumListController {
|
||||||
c := &AlbumListController{
|
c := &AlbumListController{
|
||||||
listGen: listGen,
|
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
|
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) {
|
func (c *AlbumListController) getNewAlbumList(r *http.Request) (engine.Entries, error) {
|
||||||
typ, err := RequiredParamString(r, "type", "Required string parameter 'type' is not present")
|
typ, err := RequiredParamString(r, "type", "Required string parameter 'type' is not present")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -67,12 +29,29 @@ func (c *AlbumListController) getNewAlbumList(r *http.Request) (engine.Entries,
|
|||||||
|
|
||||||
var filter engine.AlbumFilter
|
var filter engine.AlbumFilter
|
||||||
switch typ {
|
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":
|
case "byGenre":
|
||||||
filter = engine.ByGenre(utils.ParamString(r, "genre"))
|
filter = engine.ByGenre(utils.ParamString(r, "genre"))
|
||||||
case "byYear":
|
case "byYear":
|
||||||
filter = engine.ByYear(utils.ParamInt(r, "fromYear", 0), utils.ParamInt(r, "toYear", 0))
|
filter = engine.ByYear(utils.ParamInt(r, "fromYear", 0), utils.ParamInt(r, "toYear", 0))
|
||||||
default:
|
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)
|
offset := utils.ParamInt(r, "offset", 0)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ type fakeListGen struct {
|
|||||||
recvSize int
|
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 {
|
if lg.err != nil {
|
||||||
return nil, lg.err
|
return nil, lg.err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user