Skip to content

Commit

Permalink
Fix AlbumPlayCountMode. Closes #2984
Browse files Browse the repository at this point in the history
  • Loading branch information
deluan committed May 2, 2024
1 parent 2c06a42 commit a8955f2
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 13 deletions.
8 changes: 3 additions & 5 deletions persistence/album_repository.go
Expand Up @@ -10,7 +10,6 @@ import (
. "github.com/Masterminds/squirrel"
"github.com/deluan/rest"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model"
"github.com/pocketbase/dbx"
Expand All @@ -23,13 +22,12 @@ type albumRepository struct {

type dbAlbum struct {
*model.Album `structs:",flatten"`
Discs string `structs:"-" json:"discs"`
Discs string `structs:"-" json:"discs"`
PlayCount float64 `structs:"-" json:"play_count"`
}

func (a *dbAlbum) PostScan() error {
if conf.Server.AlbumPlayCountMode == consts.AlbumPlayCountModeNormalized && a.Album.SongCount != 0 {
a.Album.PlayCount = int64(math.Round(float64(a.Album.PlayCount) / float64(a.Album.SongCount)))
}
a.Album.PlayCount = int64(math.Round(a.PlayCount))
if a.Discs != "" {
return json.Unmarshal([]byte(a.Discs), &a.Album.Discs)
}
Expand Down
28 changes: 22 additions & 6 deletions persistence/album_repository_test.go
Expand Up @@ -2,8 +2,10 @@ package persistence

import (
"context"
"time"

"github.com/fatih/structs"
"github.com/google/uuid"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/log"
Expand Down Expand Up @@ -96,9 +98,16 @@ var _ = Describe("AlbumRepository", func() {
DescribeTable("normalizes play count when AlbumPlayCountMode is absolute",
func(songCount, playCount, expected int) {
conf.Server.AlbumPlayCountMode = consts.AlbumPlayCountModeAbsolute
dba := dbAlbum{Album: &model.Album{ID: "1", Name: "name", SongCount: songCount, Annotations: model.Annotations{PlayCount: int64(playCount)}}}
Expect(dba.PostScan()).To(Succeed())
Expect(dba.Album.PlayCount).To(Equal(int64(expected)))

id := uuid.NewString()
Expect(repo.Put(&model.Album{ID: id, Name: "name", SongCount: songCount})).To(Succeed())
for i := 0; i < playCount; i++ {
Expect(repo.IncPlayCount(id, time.Now())).To(Succeed())
}

album, err := repo.Get(id)
Expect(err).ToNot(HaveOccurred())
Expect(album.PlayCount).To(Equal(int64(expected)))
},
Entry("1 song, 0 plays", 1, 0, 0),
Entry("1 song, 4 plays", 1, 4, 4),
Expand All @@ -112,9 +121,16 @@ var _ = Describe("AlbumRepository", func() {
DescribeTable("normalizes play count when AlbumPlayCountMode is normalized",
func(songCount, playCount, expected int) {
conf.Server.AlbumPlayCountMode = consts.AlbumPlayCountModeNormalized
dba := dbAlbum{Album: &model.Album{ID: "1", Name: "name", SongCount: songCount, Annotations: model.Annotations{PlayCount: int64(playCount)}}}
Expect(dba.PostScan()).To(Succeed())
Expect(dba.Album.PlayCount).To(Equal(int64(expected)))

id := uuid.NewString()
Expect(repo.Put(&model.Album{ID: id, Name: "name", SongCount: songCount})).To(Succeed())
for i := 0; i < playCount; i++ {
Expect(repo.IncPlayCount(id, time.Now())).To(Succeed())
}

album, err := repo.Get(id)
Expect(err).ToNot(HaveOccurred())
Expect(album.PlayCount).To(Equal(int64(expected)))
},
Entry("1 song, 0 plays", 1, 0, 0),
Entry("1 song, 4 plays", 1, 4, 4),
Expand Down
12 changes: 10 additions & 2 deletions persistence/sql_annotations.go
Expand Up @@ -7,25 +7,33 @@ import (

. "github.com/Masterminds/squirrel"
"github.com/google/uuid"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model"
)

const annotationTable = "annotation"

func (r sqlRepository) newSelectWithAnnotation(idField string, options ...model.QueryOptions) SelectBuilder {
return r.newSelect(options...).
query := r.newSelect(options...).
LeftJoin("annotation on ("+
"annotation.item_id = "+idField+
" AND annotation.item_type = '"+r.tableName+"'"+
" AND annotation.user_id = '"+userId(r.ctx)+"')").
Columns(
"coalesce(starred, 0) as starred",
"coalesce(rating, 0) as rating",
"coalesce(play_count, 0) as play_count",
"starred_at",
"play_date",
)
if conf.Server.AlbumPlayCountMode == consts.AlbumPlayCountModeNormalized && r.tableName == "album" {
query = query.Columns("coalesce(round(cast(play_count as float) / coalesce(song_count, 1), 1), 0) as play_count")
} else {
query = query.Columns("coalesce(play_count, 0) as play_count")
}

return query
}

func (r sqlRepository) annId(itemID ...string) And {
Expand Down

0 comments on commit a8955f2

Please sign in to comment.