diff --git a/api/get_album_list.go b/api/get_album_list.go index dafdcb3ae..7e419086a 100644 --- a/api/get_album_list.go +++ b/api/get_album_list.go @@ -23,6 +23,7 @@ func (c *GetAlbumListController) Prepare() { inject.ExtractAssignable(utils.Graph, &c.listGen) c.types = map[string]strategy{ + "random": func(o int, s int) (*domain.Albums, error) { return c.listGen.GetRandom(o, s) }, "newest": func(o int, s int) (*domain.Albums, error) { return c.listGen.GetNewest(o, s) }, "recent": func(o int, s int) (*domain.Albums, error) { return c.listGen.GetRecent(o, s) }, "frequent": func(o int, s int) (*domain.Albums, error) { return c.listGen.GetFrequent(o, s) }, diff --git a/domain/album.go b/domain/album.go index dd91725d1..7e32e2ab3 100644 --- a/domain/album.go +++ b/domain/album.go @@ -30,4 +30,5 @@ type AlbumRepository interface { FindByArtist(artistId string) (*Albums, error) GetAll(QueryOptions) (*Albums, error) PurgeInactive(active *Albums) error + GetAllIds() (*[]string, error) } diff --git a/engine/lists.go b/engine/list_generator.go similarity index 76% rename from engine/lists.go rename to engine/list_generator.go index bbd1306bf..917b2687b 100644 --- a/engine/lists.go +++ b/engine/list_generator.go @@ -1,6 +1,8 @@ package engine import ( + "math/rand" + "github.com/deluan/gosonic/domain" ) @@ -9,6 +11,7 @@ type ListGenerator interface { 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) } func NewListGenerator(alr domain.AlbumRepository) ListGenerator { @@ -44,3 +47,21 @@ 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 + } + r := make(domain.Albums, len(*ids)) + perm := rand.Perm(len(*ids)) + + for i, v := range perm { + al, err := g.albumRepo.Get((*ids)[v]) + if err != nil { + return nil, err + } + r[i] = *al + } + return &r, nil +} diff --git a/persistence/album_repository.go b/persistence/album_repository.go index 69bee32eb..171c4fa7e 100644 --- a/persistence/album_repository.go +++ b/persistence/album_repository.go @@ -41,8 +41,24 @@ func (r *albumRepository) GetAll(options domain.QueryOptions) (*domain.Albums, e return &as, err } +func (r *albumRepository) GetAllIds() (*[]string, error) { + idMap, err := r.getAllIds() + if err != nil { + return nil, err + } + ids := make([]string, len(idMap)) + + i := 0 + for id, _ := range idMap { + ids[i] = id + i++ + } + + return &ids, nil +} + func (r *albumRepository) PurgeInactive(active *domain.Albums) error { - currentIds, err := r.GetAllIds() + currentIds, err := r.getAllIds() if err != nil { return err } diff --git a/persistence/artist_repository.go b/persistence/artist_repository.go index c1aba8b1e..f91054ed2 100644 --- a/persistence/artist_repository.go +++ b/persistence/artist_repository.go @@ -35,7 +35,7 @@ func (r *artistRepository) GetByName(name string) (*domain.Artist, error) { } func (r *artistRepository) PurgeInactive(active *domain.Artists) error { - currentIds, err := r.GetAllIds() + currentIds, err := r.getAllIds() if err != nil { return err } diff --git a/persistence/ledis_repository.go b/persistence/ledis_repository.go index f49028147..7edd2a0b3 100644 --- a/persistence/ledis_repository.go +++ b/persistence/ledis_repository.go @@ -45,7 +45,7 @@ func (r *ledisRepository) CountAll() (int64, error) { return size, err } -func (r *ledisRepository) GetAllIds() (map[string]bool, error) { +func (r *ledisRepository) getAllIds() (map[string]bool, error) { m := make(map[string]bool) pairs, err := db().ZRange([]byte(r.table+"s:all"), 0, -1) if err != nil { diff --git a/persistence/ledis_repository_test.go b/persistence/ledis_repository_test.go index 0598c4aeb..a510e698f 100644 --- a/persistence/ledis_repository_test.go +++ b/persistence/ledis_repository_test.go @@ -155,7 +155,7 @@ func TestBaseRepository(t *testing.T) { }) }) Convey("When I call GetAllIds", func() { - ids, err := repo.GetAllIds() + ids, err := repo.getAllIds() Convey("Then It should not return any error", func() { So(err, ShouldBeNil) }) diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go index 5e6f4c408..4060a6cf2 100644 --- a/persistence/mediafile_repository.go +++ b/persistence/mediafile_repository.go @@ -44,7 +44,7 @@ func (r *mediaFileRepository) FindByAlbum(albumId string) (*domain.MediaFiles, e } func (r *mediaFileRepository) PurgeInactive(active *domain.MediaFiles) error { - currentIds, err := r.GetAllIds() + currentIds, err := r.getAllIds() if err != nil { return err }