diff --git a/core/players.go b/core/players.go index 7956de673..2e13c2f2e 100644 --- a/core/players.go +++ b/core/players.go @@ -41,9 +41,10 @@ func (p *players) Register(ctx context.Context, id, client, userAgent, ip string log.Debug("Found matching player", "id", plr.ID, "client", client, "username", userName, "type", userAgent) } else { plr = &model.Player{ - ID: uuid.NewString(), - UserName: userName, - Client: client, + ID: uuid.NewString(), + UserName: userName, + Client: client, + ScrobbleEnabled: true, } log.Info("Registering new player", "id", plr.ID, "client", client, "username", userName, "type", userAgent) } diff --git a/core/scrobbler/play_tracker.go b/core/scrobbler/play_tracker.go index de29f04c8..c3aaff087 100644 --- a/core/scrobbler/play_tracker.go +++ b/core/scrobbler/play_tracker.go @@ -64,7 +64,10 @@ func (p *playTracker) NowPlaying(ctx context.Context, playerId string, playerNam PlayerName: playerName, } _ = p.playMap.Set(playerId, info) - p.dispatchNowPlaying(ctx, user.ID, trackId) + player, _ := request.PlayerFrom(ctx) + if player.ScrobbleEnabled { + p.dispatchNowPlaying(ctx, user.ID, trackId) + } return nil } @@ -109,6 +112,10 @@ func (p *playTracker) GetNowPlaying(ctx context.Context) ([]NowPlayingInfo, erro func (p *playTracker) Submit(ctx context.Context, submissions []Submission) error { username, _ := request.UsernameFrom(ctx) + player, _ := request.PlayerFrom(ctx) + if !player.ScrobbleEnabled { + log.Debug(ctx, "External scrobbling disabled for this player", "player", player.Name, "ip", player.IPAddress, "user", username) + } event := &events.RefreshResource{} success := 0 @@ -125,7 +132,9 @@ func (p *playTracker) Submit(ctx context.Context, submissions []Submission) erro success++ event.With("song", mf.ID).With("album", mf.AlbumID).With("artist", mf.AlbumArtistID) log.Info("Scrobbled", "title", mf.Title, "artist", mf.Artist, "user", username) - _ = p.dispatchScrobble(ctx, mf, s.Timestamp) + if player.ScrobbleEnabled { + _ = p.dispatchScrobble(ctx, mf, s.Timestamp) + } } } diff --git a/core/scrobbler/play_tracker_test.go b/core/scrobbler/play_tracker_test.go index 7cf6fbe8b..76220c424 100644 --- a/core/scrobbler/play_tracker_test.go +++ b/core/scrobbler/play_tracker_test.go @@ -29,6 +29,7 @@ var _ = Describe("PlayTracker", func() { conf.Server.DevEnableScrobble = true ctx = context.Background() ctx = request.WithUser(ctx, model.User{ID: "u-1"}) + ctx = request.WithPlayer(ctx, model.Player{ScrobbleEnabled: true}) ds = &tests.MockDataStore{} broker = GetPlayTracker(ds, events.GetBroker()) fake = &fakeScrobbler{Authorized: true} @@ -68,6 +69,14 @@ var _ = Describe("PlayTracker", func() { err := broker.NowPlaying(ctx, "player-1", "player-one", "123") + Expect(err).ToNot(HaveOccurred()) + Expect(fake.NowPlayingCalled).To(BeFalse()) + }) + It("does not send track to agent if player is not enabled to send scrobbles", func() { + ctx = request.WithPlayer(ctx, model.Player{ScrobbleEnabled: false}) + + err := broker.NowPlaying(ctx, "player-1", "player-one", "123") + Expect(err).ToNot(HaveOccurred()) Expect(fake.NowPlayingCalled).To(BeFalse()) }) @@ -136,6 +145,15 @@ var _ = Describe("PlayTracker", func() { Expect(fake.ScrobbleCalled).To(BeFalse()) }) + It("does not send track to agent player is not enabled to send scrobbles", func() { + ctx = request.WithPlayer(ctx, model.Player{ScrobbleEnabled: false}) + + err := broker.Submit(ctx, []Submission{{TrackID: "123", Timestamp: time.Now()}}) + + Expect(err).ToNot(HaveOccurred()) + Expect(fake.ScrobbleCalled).To(BeFalse()) + }) + It("increments play counts even if it cannot scrobble", func() { fake.Error = errors.New("error") diff --git a/model/player.go b/model/player.go index df96b649d..6429bc591 100644 --- a/model/player.go +++ b/model/player.go @@ -5,16 +5,17 @@ import ( ) type Player struct { - ID string `json:"id" orm:"column(id)"` - Name string `json:"name"` - UserAgent string `json:"userAgent"` - UserName string `json:"userName"` - Client string `json:"client"` - IPAddress string `json:"ipAddress"` - LastSeen time.Time `json:"lastSeen"` - TranscodingId string `json:"transcodingId"` - MaxBitRate int `json:"maxBitRate"` - ReportRealPath bool `json:"reportRealPath"` + ID string `json:"id" orm:"column(id)"` + Name string `json:"name"` + UserAgent string `json:"userAgent"` + UserName string `json:"userName"` + Client string `json:"client"` + IPAddress string `json:"ipAddress"` + LastSeen time.Time `json:"lastSeen"` + TranscodingId string `json:"transcodingId"` + MaxBitRate int `json:"maxBitRate"` + ReportRealPath bool `json:"reportRealPath"` + ScrobbleEnabled bool `json:"scrobbleEnabled"` } type Players []Player diff --git a/ui/src/i18n/en.json b/ui/src/i18n/en.json index 56e10aebf..e76657138 100644 --- a/ui/src/i18n/en.json +++ b/ui/src/i18n/en.json @@ -111,7 +111,8 @@ "client": "Client", "userName": "Username", "lastSeen": "Last Seen At", - "reportRealPath": "Report Real Path" + "reportRealPath": "Report Real Path", + "scrobbleEnabled": "Send Scrobbles to Last.fm?" } }, "transcoding": { diff --git a/ui/src/player/PlayerEdit.js b/ui/src/player/PlayerEdit.js index 1c8f8dec7..9b50f7955 100644 --- a/ui/src/player/PlayerEdit.js +++ b/ui/src/player/PlayerEdit.js @@ -47,6 +47,7 @@ const PlayerEdit = (props) => ( ]} /> +