From c8a74881d899644569dccfa562cc396f2d3ae9d4 Mon Sep 17 00:00:00 2001 From: Deluan <deluan@deluan.com> Date: Wed, 22 Jan 2020 01:00:00 -0500 Subject: [PATCH] Fix album lists, to use annotations --- engine/list_generator.go | 55 ++++++++++++++++++++-------- model/album.go | 1 + model/annotation.go | 1 + persistence/album_repository.go | 13 +++++++ persistence/annotation_repository.go | 18 +++++++++ persistence/sql_repository.go | 6 +-- 6 files changed, 75 insertions(+), 19 deletions(-) diff --git a/engine/list_generator.go b/engine/list_generator.go index 1bbddf6c1..d625fca1d 100644 --- a/engine/list_generator.go +++ b/engine/list_generator.go @@ -30,10 +30,7 @@ type listGenerator struct { npRepo NowPlayingRepository } -// TODO: Only return albums that have the Sort field != empty -func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions, offset int, size int) (Entries, error) { - qo.Offset = offset - qo.Max = size +func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions) (Entries, error) { albums, err := g.ds.Album().GetAll(qo) if err != nil { return nil, err @@ -49,34 +46,60 @@ func (g *listGenerator) query(ctx context.Context, qo model.QueryOptions, offset return FromAlbums(albums, annMap), err } +func (g *listGenerator) queryByAnnotation(ctx context.Context, qo model.QueryOptions) (Entries, error) { + annotations, err := g.ds.Annotation().GetAll(getUserID(ctx), model.AlbumItemType, qo) + if err != nil { + return nil, err + } + albumIds := make([]string, len(annotations)) + for i, ann := range annotations { + albumIds[i] = ann.ItemID + } + + albumMap, err := g.ds.Album().GetMap(albumIds) + if err != nil { + return nil, err + } + + var albums Entries + for _, ann := range annotations { + album := albumMap[ann.ItemID] + albums = append(albums, FromAlbum(&album, &ann)) + } + return albums, nil +} + func (g *listGenerator) GetNewest(ctx context.Context, offset int, size int) (Entries, error) { - qo := model.QueryOptions{Sort: "CreatedAt", Order: "desc"} - return g.query(ctx, qo, offset, size) + 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"} - return g.query(ctx, qo, offset, size) + qo := model.QueryOptions{Sort: "PlayDate", Order: "desc", Offset: offset, Max: size, + Filters: map[string]interface{}{"play_date__gt": time.Time{}}} + return g.queryByAnnotation(ctx, qo) } func (g *listGenerator) GetFrequent(ctx context.Context, offset int, size int) (Entries, error) { - qo := model.QueryOptions{Sort: "PlayCount", Order: "desc"} - return g.query(ctx, qo, offset, size) + qo := model.QueryOptions{Sort: "PlayCount", Order: "desc", Offset: offset, Max: size, + Filters: map[string]interface{}{"play_count__gt": 0}} + return g.queryByAnnotation(ctx, qo) } func (g *listGenerator) GetHighest(ctx context.Context, offset int, size int) (Entries, error) { - qo := model.QueryOptions{Sort: "Rating", Order: "desc"} - return g.query(ctx, qo, offset, size) + qo := model.QueryOptions{Sort: "Rating", Order: "desc", Offset: offset, Max: size, + Filters: map[string]interface{}{"rating__gt": 0}} + return g.queryByAnnotation(ctx, qo) } func (g *listGenerator) GetByName(ctx context.Context, offset int, size int) (Entries, error) { - qo := model.QueryOptions{Sort: "Name"} - return g.query(ctx, qo, offset, size) + 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"} - return g.query(ctx, qo, offset, size) + 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) { diff --git a/model/album.go b/model/album.go index c8862a6df..de1e0caea 100644 --- a/model/album.go +++ b/model/album.go @@ -28,6 +28,7 @@ type AlbumRepository interface { Get(id string) (*Album, error) FindByArtist(artistId string) (Albums, error) GetAll(...QueryOptions) (Albums, error) + GetMap(ids []string) (map[string]Album, error) GetRandom(...QueryOptions) (Albums, error) GetStarred(userId string, options ...QueryOptions) (Albums, error) Search(q string, offset int, size int) (Albums, error) diff --git a/model/annotation.go b/model/annotation.go index 4c2cd48f7..fef0d37a8 100644 --- a/model/annotation.go +++ b/model/annotation.go @@ -24,6 +24,7 @@ type AnnotationMap map[string]Annotation type AnnotationRepository interface { Get(userID, itemType string, itemID string) (*Annotation, error) + GetAll(userID, itemType string, options ...QueryOptions) ([]Annotation, error) GetMap(userID, itemType string, itemID []string) (AnnotationMap, error) Delete(userID, itemType string, itemID ...string) error IncPlayCount(userID, itemType string, itemID string, ts time.Time) error diff --git a/persistence/album_repository.go b/persistence/album_repository.go index de45be7b0..712e414fb 100644 --- a/persistence/album_repository.go +++ b/persistence/album_repository.go @@ -75,6 +75,19 @@ func (r *albumRepository) GetAll(options ...model.QueryOptions) (model.Albums, e return r.toAlbums(all), nil } +func (r *albumRepository) GetMap(ids []string) (map[string]model.Album, error) { + var all []album + _, err := r.newQuery().Filter("id__in", ids).All(&all) + if err != nil { + return nil, err + } + res := make(map[string]model.Album) + for _, a := range all { + res[a.ID] = model.Album(a) + } + return res, nil +} + // TODO Keep order when paginating func (r *albumRepository) GetRandom(options ...model.QueryOptions) (model.Albums, error) { sq := r.newRawQuery(options...) diff --git a/persistence/annotation_repository.go b/persistence/annotation_repository.go index 8271efda3..7954a1e9a 100644 --- a/persistence/annotation_repository.go +++ b/persistence/annotation_repository.go @@ -75,6 +75,24 @@ func (r *annotationRepository) GetMap(userID, itemType string, itemID []string) return m, nil } +func (r *annotationRepository) GetAll(userID, itemType string, options ...model.QueryOptions) ([]model.Annotation, error) { + if userID == "" { + return nil, model.ErrInvalidAuth + } + q := r.newQuery(options...).Filter("user_id", userID).Filter("item_type", itemType) + var res []annotation + _, err := q.All(&res) + if err != nil { + return nil, err + } + + all := make([]model.Annotation, len(res)) + for i, a := range res { + all[i] = model.Annotation(a) + } + return all, err +} + func (r *annotationRepository) new(userID, itemType string, itemID string) *annotation { id, _ := uuid.NewRandom() return &annotation{ diff --git a/persistence/sql_repository.go b/persistence/sql_repository.go index c88de2ef1..706596673 100644 --- a/persistence/sql_repository.go +++ b/persistence/sql_repository.go @@ -26,6 +26,9 @@ func (r *sqlRepository) newQuery(options ...model.QueryOptions) orm.QuerySeter { q = q.OrderBy(opts.Sort) } } + for field, value := range opts.Filters { + q = q.Filter(field, value) + } } return q } @@ -46,9 +49,6 @@ func (r *sqlRepository) newRawQuery(options ...model.QueryOptions) squirrel.Sele sq = sq.OrderBy(options[0].Sort) } } - for field, value := range options[0].Filters { - sq = sq.Where(squirrel.Like{field: value.(string) + "%"}) - } } return sq }