diff --git a/README.rst b/README.rst index 1ce85a8..792ddbc 100644 --- a/README.rst +++ b/README.rst @@ -41,12 +41,14 @@ found at ``~/.config/mopidy/mopidy.conf``:: [scrobbler] username = alice password = secret + backend_blacklist = list The following configuration values are available: - ``scrobbler/enabled``: If the scrobbler extension should be enabled or not. - ``scrobbler/username``: Your Last.fm username. - ``scrobbler/password``: Your Last.fm password. +- ``scrobbler/backend_blacklist``: List of uri schemes to not scrobble - eg spotify Project resources diff --git a/mopidy_scrobbler/__init__.py b/mopidy_scrobbler/__init__.py index 8785496..2d03828 100644 --- a/mopidy_scrobbler/__init__.py +++ b/mopidy_scrobbler/__init__.py @@ -22,6 +22,7 @@ def get_config_schema(self): schema = super(Extension, self).get_config_schema() schema['username'] = config.String() schema['password'] = config.Secret() + schema['backend_blacklist'] = config.List(optional=True) return schema def setup(self, registry): diff --git a/mopidy_scrobbler/ext.conf b/mopidy_scrobbler/ext.conf index 4fded92..706ff70 100644 --- a/mopidy_scrobbler/ext.conf +++ b/mopidy_scrobbler/ext.conf @@ -2,3 +2,4 @@ enabled = true username = password = +backend_blacklist = \ No newline at end of file diff --git a/mopidy_scrobbler/frontend.py b/mopidy_scrobbler/frontend.py index 2abcb0e..34ada07 100644 --- a/mopidy_scrobbler/frontend.py +++ b/mopidy_scrobbler/frontend.py @@ -30,6 +30,14 @@ def __init__(self, config, core): self.lastfm = None self.last_start_time = None + def check_uri_scheme(self, uri): + uri_scheme = uri.split(':')[0] + if uri_scheme in self.config['scrobbler']['backend_blacklist']: + logger.info('Not scrobbling track from %s', uri_scheme) + return True + else: + return False + def on_start(self): try: self.lastfm = pylast.LastFMNetwork( @@ -43,6 +51,8 @@ def on_start(self): def track_playback_started(self, tl_track): track = tl_track.track + if self.check_uri_scheme(track.uri): + return artists = ', '.join(sorted([a.name for a in track.artists])) duration = track.length and track.length // 1000 or 0 self.last_start_time = int(time.time()) @@ -60,6 +70,8 @@ def track_playback_started(self, tl_track): def track_playback_ended(self, tl_track, time_position): track = tl_track.track + if self.check_uri_scheme(track.uri): + return artists = ', '.join(sorted([a.name for a in track.artists])) duration = track.length and track.length // 1000 or 0 time_position = time_position // 1000 diff --git a/tests/test_extension.py b/tests/test_extension.py index 756881a..ff610e3 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -16,6 +16,7 @@ def test_get_default_config(self): self.assertIn('enabled = true', config) self.assertIn('username =', config) self.assertIn('password =', config) + self.assertIn('backend_blacklist', config) def test_get_config_schema(self): ext = Extension() @@ -24,6 +25,7 @@ def test_get_config_schema(self): self.assertIn('username', schema) self.assertIn('password', schema) + self.assertIn('backend_blacklist', schema) def test_setup(self): ext = Extension() diff --git a/tests/test_frontend.py b/tests/test_frontend.py index 6600ccd..3b6e0a9 100644 --- a/tests/test_frontend.py +++ b/tests/test_frontend.py @@ -17,6 +17,7 @@ def setUp(self): 'scrobbler': { 'username': 'alice', 'password': 'secret', + 'backend_blacklist': ['spotify'] } } self.frontend = frontend_lib.ScrobblerFrontend( @@ -48,6 +49,7 @@ def test_track_playback_started_updates_now_playing(self, pylast_mock): artists = [models.Artist(name='ABC'), models.Artist(name='XYZ')] album = models.Album(name='The Collection') track = models.Track( + uri='local:track:1234567890', name='One Two Three', artists=artists, album=album, @@ -68,7 +70,7 @@ def test_track_playback_started_updates_now_playing(self, pylast_mock): def test_track_playback_started_has_default_values(self, pylast_mock): self.frontend.lastfm = mock.Mock(spec=pylast.LastFMNetwork) - track = models.Track() + track = models.Track(uri='local:track:1234567890') tl_track = models.TlTrack(track=track, tlid=17) self.frontend.track_playback_started(tl_track) @@ -86,7 +88,7 @@ def test_track_playback_started_catches_pylast_error(self, pylast_mock): pylast_mock.NetworkError = pylast.NetworkError self.frontend.lastfm.update_now_playing.side_effect = ( pylast.NetworkError(None, 'foo')) - track = models.Track() + track = models.Track(uri='local:track:1234567890') tl_track = models.TlTrack(track=track, tlid=17) self.frontend.track_playback_started(tl_track) @@ -97,6 +99,7 @@ def test_track_playback_ended_scrobbles_played_track(self, pylast_mock): artists = [models.Artist(name='ABC'), models.Artist(name='XYZ')] album = models.Album(name='The Collection') track = models.Track( + uri='local:track:1234567890', name='One Two Three', artists=artists, album=album, @@ -119,7 +122,7 @@ def test_track_playback_ended_scrobbles_played_track(self, pylast_mock): def test_track_playback_ended_has_default_values(self, pylast_mock): self.frontend.last_start_time = 123 self.frontend.lastfm = mock.Mock(spec=pylast.LastFMNetwork) - track = models.Track(length=180432) + track = models.Track(length=180432, uri='local:track:1234567890') tl_track = models.TlTrack(track=track, tlid=17) self.frontend.track_playback_ended(tl_track, 150000) @@ -135,7 +138,7 @@ def test_track_playback_ended_has_default_values(self, pylast_mock): def test_does_not_scrobble_tracks_shorter_than_30_sec(self, pylast_mock): self.frontend.lastfm = mock.Mock(spec=pylast.LastFMNetwork) - track = models.Track(length=20432) + track = models.Track(length=20432, uri='local:track:1234567890') tl_track = models.TlTrack(track=track, tlid=17) self.frontend.track_playback_ended(tl_track, 20432) @@ -144,7 +147,7 @@ def test_does_not_scrobble_tracks_shorter_than_30_sec(self, pylast_mock): def test_does_not_scrobble_if_played_less_than_half(self, pylast_mock): self.frontend.lastfm = mock.Mock(spec=pylast.LastFMNetwork) - track = models.Track(length=180432) + track = models.Track(length=180432, uri='local:track:1234567890') tl_track = models.TlTrack(track=track, tlid=17) self.frontend.track_playback_ended(tl_track, 60432) @@ -153,13 +156,22 @@ def test_does_not_scrobble_if_played_less_than_half(self, pylast_mock): def test_does_scrobble_if_played_not_half_but_240_sec(self, pylast_mock): self.frontend.lastfm = mock.Mock(spec=pylast.LastFMNetwork) - track = models.Track(length=880432) + track = models.Track(length=880432, uri='local:track:1234567890') tl_track = models.TlTrack(track=track, tlid=17) self.frontend.track_playback_ended(tl_track, 241432) self.assertEqual(self.frontend.lastfm.scrobble.call_count, 1) + def test_does_not_scrobble_if_uri_scheme_filtered(self, pylast_mock): + self.frontend.lastfm = mock.Mock(spec=pylast.LastFMNetwork) + track = models.Track(length=880432, uri='spotify:track:1234567890') + tl_track = models.TlTrack(track=track, tlid=17) + + self.frontend.track_playback_ended(tl_track, 241432) + + self.assertEqual(self.frontend.lastfm.scrobble.call_count, 0) + def test_track_playback_ended_catches_pylast_error(self, pylast_mock): self.frontend.lastfm = mock.Mock(spec=pylast.LastFMNetwork) pylast_mock.NetworkError = pylast.NetworkError