From 80b2c2f3cfdb7d0676de802d9103424189bef4a4 Mon Sep 17 00:00:00 2001 From: Deluan Date: Sun, 20 Jun 2021 11:21:29 -0400 Subject: [PATCH] Try to register all playing music in GetNowPlaying --- core/scrobbler/scrobbler.go | 27 +++++++++++++++------------ server/subsonic/media_annotation.go | 22 +++++++++++++--------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/core/scrobbler/scrobbler.go b/core/scrobbler/scrobbler.go index c3be83498..f9890abd1 100644 --- a/core/scrobbler/scrobbler.go +++ b/core/scrobbler/scrobbler.go @@ -3,9 +3,9 @@ package scrobbler import ( "context" "sort" - "sync" "time" + "github.com/ReneKroon/ttlcache/v2" "github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/model/request" "github.com/navidrome/navidrome/utils/singleton" @@ -28,14 +28,16 @@ type Scrobbler interface { } type scrobbler struct { - ds model.DataStore + ds model.DataStore + playMap *ttlcache.Cache } -var playMap = sync.Map{} - func New(ds model.DataStore) Scrobbler { instance := singleton.Get(scrobbler{}, func() interface{} { - return &scrobbler{ds: ds} + m := ttlcache.NewCache() + m.SkipTTLExtensionOnHit(true) + _ = m.SetTTL(nowPlayingExpire) + return &scrobbler{ds: ds, playMap: m} }) return instance.(*scrobbler) } @@ -49,19 +51,20 @@ func (s *scrobbler) NowPlaying(ctx context.Context, playerId string, playerName PlayerId: playerId, PlayerName: playerName, } - playMap.Store(playerId, info) + _ = s.playMap.Set(playerId, info) return nil } func (s *scrobbler) GetNowPlaying(ctx context.Context) ([]NowPlayingInfo, error) { var res []NowPlayingInfo - playMap.Range(func(playerId, value interface{}) bool { - info := value.(NowPlayingInfo) - if time.Since(info.Start) < nowPlayingExpire { - res = append(res, info) + for _, playerId := range s.playMap.GetKeys() { + value, err := s.playMap.Get(playerId) + if err != nil { + continue } - return true - }) + info := value.(NowPlayingInfo) + res = append(res, info) + } sort.Slice(res, func(i, j int) bool { return res[i].Start.After(res[j].Start) }) diff --git a/server/subsonic/media_annotation.go b/server/subsonic/media_annotation.go index 54549e654..14514fa63 100644 --- a/server/subsonic/media_annotation.go +++ b/server/subsonic/media_annotation.go @@ -125,8 +125,6 @@ func (c *MediaAnnotationController) Scrobble(w http.ResponseWriter, r *http.Requ return nil, newError(responses.ErrorGeneric, "Wrong number of timestamps: %d, should be %d", len(times), len(ids)) } submission := utils.ParamBool(r, "submission", true) - client := utils.ParamString(r, "c") - username := utils.ParamString(r, "u") ctx := r.Context() event := &events.RefreshResource{} submissions := 0 @@ -147,8 +145,9 @@ func (c *MediaAnnotationController) Scrobble(w http.ResponseWriter, r *http.Requ } submissions++ event.With("song", mf.ID).With("album", mf.AlbumID).With("artist", mf.AlbumArtistID) - } else { - err := c.scrobblerNowPlaying(ctx, client, id, username) + } + if !submission || len(times) == 0 { + err := c.scrobblerNowPlaying(ctx, id) if err != nil { log.Error(r, "Error setting current song", "id", id, err) continue @@ -191,20 +190,25 @@ func (c *MediaAnnotationController) scrobblerRegister(ctx context.Context, track return mf, err } -func (c *MediaAnnotationController) scrobblerNowPlaying(ctx context.Context, client, trackId, username string) error { +func (c *MediaAnnotationController) scrobblerNowPlaying(ctx context.Context, trackId string) error { mf, err := c.ds.MediaFile(ctx).Get(trackId) if err != nil { return err } - - player, _ := request.PlayerFrom(ctx) if mf == nil { return fmt.Errorf(`ID "%s" not found`, trackId) } - log.Info("Now Playing", "title", mf.Title, "artist", mf.Artist, "user", username) + player, _ := request.PlayerFrom(ctx) + username, _ := request.UsernameFrom(ctx) + client, _ := request.ClientFrom(ctx) + clientId, ok := request.ClientUniqueIdFrom(ctx) + if !ok { + clientId = player.ID + } - err = c.scrobbler.NowPlaying(ctx, player.ID, client, trackId) + log.Info("Now Playing", "title", mf.Title, "artist", mf.Artist, "user", username, "player", player.Name) + err = c.scrobbler.NowPlaying(ctx, clientId, client, trackId) return err }