From 4c0250f9f8c4463a20a494a1d16f46b22acc517d Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 17 Apr 2020 21:18:04 -0400 Subject: [PATCH] Add fromYear/toYear params to getRandomSongs --- engine/list_generator.go | 83 +++++++++++++++++------------ server/subsonic/album_lists.go | 6 ++- server/subsonic/album_lists_test.go | 2 +- 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/engine/list_generator.go b/engine/list_generator.go index 0ffe6f3ce56..5ca1d703e96 100644 --- a/engine/list_generator.go +++ b/engine/list_generator.go @@ -11,58 +11,58 @@ import ( 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) GetSongsByGenre(ctx context.Context, offset int, count int, genre string) (Entries, error) - GetAlbums(ctx context.Context, offset, size int, filter AlbumFilter) (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 AlbumFilter model.QueryOptions +type ListFilter model.QueryOptions -func ByNewest() AlbumFilter { - return AlbumFilter{Sort: "createdAt", Order: "desc"} +func ByNewest() ListFilter { + return ListFilter{Sort: "createdAt", Order: "desc"} } -func ByRecent() AlbumFilter { - return AlbumFilter{Sort: "playDate", Order: "desc", Filters: squirrel.Gt{"play_date": time.Time{}}} +func ByRecent() ListFilter { + return ListFilter{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 ByFrequent() ListFilter { + return ListFilter{Sort: "playCount", Order: "desc", Filters: squirrel.Gt{"play_count": 0}} } -func ByRandom() AlbumFilter { - return AlbumFilter{Sort: "random()"} +func ByRandom() ListFilter { + return ListFilter{Sort: "random()"} } -func ByName() AlbumFilter { - return AlbumFilter{Sort: "name"} +func ByName() ListFilter { + return ListFilter{Sort: "name"} } -func ByArtist() AlbumFilter { - return AlbumFilter{Sort: "artist"} +func ByArtist() ListFilter { + return ListFilter{Sort: "artist"} } -func ByStarred() AlbumFilter { - return AlbumFilter{Sort: "starred_at", Order: "desc", Filters: squirrel.Eq{"starred": true}} +func ByStarred() ListFilter { + return ListFilter{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 ByRating() ListFilter { + return ListFilter{Sort: "Rating", Order: "desc", Filters: squirrel.Gt{"rating": 0}} } -func ByGenre(genre string) AlbumFilter { - return AlbumFilter{ +func ByGenre(genre string) ListFilter { + return ListFilter{ Sort: "genre asc, name asc", Filters: squirrel.Eq{"genre": genre}, } } -func ByYear(fromYear, toYear int) AlbumFilter { - return AlbumFilter{ +func ByYear(fromYear, toYear int) ListFilter { + return ListFilter{ Sort: "max_year, name", Filters: squirrel.Or{ squirrel.And{ @@ -77,6 +77,24 @@ func ByYear(fromYear, toYear int) AlbumFilter { } } +func RandomSongs(genre string, fromYear, toYear int) ListFilter { + options := ListFilter{ + Sort: "random()", + } + ff := squirrel.And{} + if genre != "" { + options.Filters = append(ff, squirrel.Eq{"genre": genre}) + } + if fromYear != 0 { + options.Filters = append(ff, squirrel.GtOrEq{"year": fromYear}) + } + if toYear != 0 { + options.Filters = append(ff, squirrel.LtOrEq{"year": toYear}) + } + options.Filters = ff + return options +} + type listGenerator struct { ds model.DataStore npRepo NowPlayingRepository @@ -94,12 +112,12 @@ func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions) (Entri return FromAlbums(albums), err } -func (g *listGenerator) GetRandomSongs(ctx context.Context, size int, genre string) (Entries, error) { - options := model.QueryOptions{Max: size} +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).GetRandom(options) + mediaFiles, err := g.ds.MediaFile(ctx).GetAll(options) if err != nil { return nil, err } @@ -107,12 +125,11 @@ func (g *listGenerator) GetRandomSongs(ctx context.Context, size int, genre stri return FromMediaFiles(mediaFiles), nil } -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) +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) if err != nil { return nil, err } @@ -120,7 +137,7 @@ func (g *listGenerator) GetSongsByGenre(ctx context.Context, offset int, count i return FromMediaFiles(mediaFiles), nil } -func (g *listGenerator) GetAlbums(ctx context.Context, offset, size int, filter AlbumFilter) (Entries, error) { +func (g *listGenerator) GetAlbums(ctx context.Context, offset, size int, filter ListFilter) (Entries, error) { qo := model.QueryOptions(filter) qo.Offset = offset qo.Max = size diff --git a/server/subsonic/album_lists.go b/server/subsonic/album_lists.go index 780e61fde4b..df9482e53f0 100644 --- a/server/subsonic/album_lists.go +++ b/server/subsonic/album_lists.go @@ -27,7 +27,7 @@ func (c *AlbumListController) getNewAlbumList(r *http.Request) (engine.Entries, return nil, err } - var filter engine.AlbumFilter + var filter engine.ListFilter switch typ { case "newest": filter = engine.ByNewest() @@ -141,8 +141,10 @@ func (c *AlbumListController) GetNowPlaying(w http.ResponseWriter, r *http.Reque func (c *AlbumListController) GetRandomSongs(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) { size := utils.MinInt(utils.ParamInt(r, "size", 10), 500) genre := utils.ParamString(r, "genre") + fromYear := utils.ParamInt(r, "fromYear", 0) + toYear := utils.ParamInt(r, "toYear", 0) - songs, err := c.listGen.GetRandomSongs(r.Context(), size, genre) + songs, err := c.listGen.GetSongs(r.Context(), 0, size, engine.RandomSongs(genre, fromYear, toYear)) if err != nil { log.Error(r, "Error retrieving random songs", "error", err) return nil, NewError(responses.ErrorGeneric, "Internal Error") diff --git a/server/subsonic/album_lists_test.go b/server/subsonic/album_lists_test.go index f29a267ef6b..788a552879f 100644 --- a/server/subsonic/album_lists_test.go +++ b/server/subsonic/album_lists_test.go @@ -18,7 +18,7 @@ type fakeListGen struct { recvSize int } -func (lg *fakeListGen) GetAlbums(ctx context.Context, offset int, size int, filter engine.AlbumFilter) (engine.Entries, error) { +func (lg *fakeListGen) GetAlbums(ctx context.Context, offset int, size int, filter engine.ListFilter) (engine.Entries, error) { if lg.err != nil { return nil, lg.err }