Register PlayCount/Date in the DB, if DevUseFolderScanner is true

This commit is contained in:
Deluan 2020-01-18 20:59:20 -05:00
parent 3c66da0b17
commit 938a92eded
8 changed files with 39 additions and 6 deletions

View file

@ -33,6 +33,7 @@ type listGenerator struct {
npRepo NowPlayingRepository npRepo NowPlayingRepository
} }
// TODO: Only return albums that have the SortBy field != empty
func (g *listGenerator) query(qo model.QueryOptions, offset int, size int) (Entries, error) { func (g *listGenerator) query(qo model.QueryOptions, offset int, size int) (Entries, error) {
qo.Offset = offset qo.Offset = offset
qo.Size = size qo.Size = size

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/cloudsonic/sonic-server/conf"
"github.com/cloudsonic/sonic-server/itunesbridge" "github.com/cloudsonic/sonic-server/itunesbridge"
"github.com/cloudsonic/sonic-server/log" "github.com/cloudsonic/sonic-server/log"
"github.com/cloudsonic/sonic-server/model" "github.com/cloudsonic/sonic-server/model"
@ -21,13 +22,14 @@ type Scrobbler interface {
NowPlaying(ctx context.Context, playerId int, playerName, trackId, username string) (*model.MediaFile, error) NowPlaying(ctx context.Context, playerId int, playerName, trackId, username string) (*model.MediaFile, error)
} }
func NewScrobbler(itunes itunesbridge.ItunesControl, mr model.MediaFileRepository, npr NowPlayingRepository) Scrobbler { func NewScrobbler(itunes itunesbridge.ItunesControl, mr model.MediaFileRepository, alr model.AlbumRepository, npr NowPlayingRepository) Scrobbler {
return &scrobbler{itunes, mr, npr} return &scrobbler{itunes: itunes, mfRepo: mr, alRepo: alr, npRepo: npr}
} }
type scrobbler struct { type scrobbler struct {
itunes itunesbridge.ItunesControl itunes itunesbridge.ItunesControl
mfRepo model.MediaFileRepository mfRepo model.MediaFileRepository
alRepo model.AlbumRepository
npRepo NowPlayingRepository npRepo NowPlayingRepository
} }
@ -71,6 +73,16 @@ func (s *scrobbler) detectSkipped(ctx context.Context, playerId int, trackId str
func (s *scrobbler) Register(ctx context.Context, playerId int, trackId string, playTime time.Time) (*model.MediaFile, error) { func (s *scrobbler) Register(ctx context.Context, playerId int, trackId string, playTime time.Time) (*model.MediaFile, error) {
s.detectSkipped(ctx, playerId, trackId) s.detectSkipped(ctx, playerId, trackId)
if conf.Sonic.DevUseFileScanner {
mf, err := s.mfRepo.Get(trackId)
if err != nil {
err = s.mfRepo.MarkAsPlayed(trackId, playTime)
return nil, err
}
err = s.alRepo.MarkAsPlayed(mf.AlbumID, playTime)
return mf, err
}
mf, err := s.mfRepo.Get(trackId) mf, err := s.mfRepo.Get(trackId)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -17,10 +17,11 @@ func TestScrobbler(t *testing.T) {
Init(t, false) Init(t, false)
mfRepo := persistence.CreateMockMediaFileRepo() mfRepo := persistence.CreateMockMediaFileRepo()
alRepo := persistence.CreateMockAlbumRepo()
npRepo := engine.CreateMockNowPlayingRepo() npRepo := engine.CreateMockNowPlayingRepo()
itCtrl := &mockItunesControl{} itCtrl := &mockItunesControl{}
scrobbler := engine.NewScrobbler(itCtrl, mfRepo, npRepo) scrobbler := engine.NewScrobbler(itCtrl, mfRepo, alRepo, npRepo)
Convey("Given a DB with one song", t, func() { Convey("Given a DB with one song", t, func() {
mfRepo.SetData(`[{"ID":"2","Title":"Hands Of Time"}]`, 1) mfRepo.SetData(`[{"ID":"2","Title":"Hands Of Time"}]`, 1)
@ -89,10 +90,11 @@ func TestSkipping(t *testing.T) {
Init(t, false) Init(t, false)
mfRepo := persistence.CreateMockMediaFileRepo() mfRepo := persistence.CreateMockMediaFileRepo()
alRepo := persistence.CreateMockAlbumRepo()
npRepo := engine.CreateMockNowPlayingRepo() npRepo := engine.CreateMockNowPlayingRepo()
itCtrl := &mockItunesControl{} itCtrl := &mockItunesControl{}
scrobbler := engine.NewScrobbler(itCtrl, mfRepo, npRepo) scrobbler := engine.NewScrobbler(itCtrl, mfRepo, alRepo, npRepo)
Convey("Given a DB with three songs", t, func() { Convey("Given a DB with three songs", t, func() {
mfRepo.SetData(`[{"ID":"1","Title":"Femme Fatale"},{"ID":"2","Title":"Here She Comes Now"},{"ID":"3","Title":"Lady Godiva's Operation"}]`, 3) mfRepo.SetData(`[{"ID":"1","Title":"Femme Fatale"},{"ID":"2","Title":"Here She Comes Now"},{"ID":"3","Title":"Lady Godiva's Operation"}]`, 3)

View file

@ -36,8 +36,9 @@ type AlbumRepository interface {
PurgeInactive(active Albums) error PurgeInactive(active Albums) error
GetAllIds() ([]string, error) GetAllIds() ([]string, error)
GetStarred(...QueryOptions) (Albums, error) GetStarred(...QueryOptions) (Albums, error)
SetStar(star bool, ids ...string) error
Search(q string, offset int, size int) (Albums, error) Search(q string, offset int, size int) (Albums, error)
Refresh(ids ...string) error Refresh(ids ...string) error
PurgeEmpty() error PurgeEmpty() error
SetStar(star bool, ids ...string) error
MarkAsPlayed(id string, playDate time.Time) error
} }

View file

@ -54,4 +54,5 @@ type MediaFileRepository interface {
DeleteByPath(path string) error DeleteByPath(path string) error
SetStar(star bool, ids ...string) error SetStar(star bool, ids ...string) error
SetRating(rating int, ids ...string) error SetRating(rating int, ids ...string) error
MarkAsPlayed(id string, playTime time.Time) error
} }

View file

@ -190,6 +190,14 @@ func (r *albumRepository) SetStar(starred bool, ids ...string) error {
return err return err
} }
func (r *albumRepository) MarkAsPlayed(id string, playDate time.Time) error {
_, err := r.newQuery(Db()).Filter("id", id).Update(orm.Params{
"play_count": orm.ColValue(orm.ColAdd, 1),
"play_date": playDate,
})
return err
}
func (r *albumRepository) Search(q string, offset int, size int) (model.Albums, error) { func (r *albumRepository) Search(q string, offset int, size int) (model.Albums, error) {
if len(q) <= 2 { if len(q) <= 2 {
return nil, nil return nil, nil

View file

@ -158,6 +158,14 @@ func (r *mediaFileRepository) SetRating(rating int, ids ...string) error {
return err return err
} }
func (r *mediaFileRepository) MarkAsPlayed(id string, playDate time.Time) error {
_, err := r.newQuery(Db()).Filter("id", id).Update(orm.Params{
"play_count": orm.ColValue(orm.ColAdd, 1),
"play_date": playDate,
})
return err
}
func (r *mediaFileRepository) PurgeInactive(activeList model.MediaFiles) error { func (r *mediaFileRepository) PurgeInactive(activeList model.MediaFiles) error {
return withTx(func(o orm.Ormer) error { return withTx(func(o orm.Ormer) error {
_, err := r.purgeInactive(o, activeList, func(item interface{}) string { _, err := r.purgeInactive(o, activeList, func(item interface{}) string {

View file

@ -48,7 +48,7 @@ func CreateSubsonicAPIRouter() *api.Router {
playlistRepository := persistence.NewPlaylistRepository() playlistRepository := persistence.NewPlaylistRepository()
playlists := engine.NewPlaylists(itunesControl, playlistRepository, mediaFileRepository) playlists := engine.NewPlaylists(itunesControl, playlistRepository, mediaFileRepository)
ratings := engine.NewRatings(itunesControl, mediaFileRepository, albumRepository, artistRepository) ratings := engine.NewRatings(itunesControl, mediaFileRepository, albumRepository, artistRepository)
scrobbler := engine.NewScrobbler(itunesControl, mediaFileRepository, nowPlayingRepository) scrobbler := engine.NewScrobbler(itunesControl, mediaFileRepository, albumRepository, nowPlayingRepository)
search := engine.NewSearch(artistRepository, albumRepository, mediaFileRepository) search := engine.NewSearch(artistRepository, albumRepository, mediaFileRepository)
router := api.NewRouter(browser, cover, listGenerator, playlists, ratings, scrobbler, search) router := api.NewRouter(browser, cover, listGenerator, playlists, ratings, scrobbler, search)
return router return router