From 0d4f674ac7071230b1f14cf5f45dc21cad720993 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 17:28:02 +0300 Subject: [PATCH 01/13] Remove dead Last.fm methods: get_top_fans --- pylast/__init__.py | 24 ------------------------ tests/test_pylast.py | 27 +-------------------------- 2 files changed, 1 insertion(+), 50 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index fd17e99..245e1a3 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -1252,30 +1252,6 @@ class _BaseObject(object): return seq - def get_top_fans(self, limit=None, cacheable=True): - """Returns a list of the Users who played this the most. - # Parameters: - * limit int: Max elements. - # For Artist/Track - """ - - doc = self._request(self.ws_prefix + '.getTopFans', cacheable) - - seq = [] - - elements = doc.getElementsByTagName('user') - - for element in elements: - if limit and len(seq) >= limit: - break - - name = _extract(element, 'name') - weight = _number(_extract(element, 'weight')) - - seq.append(TopItem(User(name, self.network), weight)) - - return seq - def share(self, users, message=None): """ Shares this (sends out recommendations). diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 0433fb9..a2c27a6 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -487,9 +487,7 @@ class TestPyLast(unittest.TestCase): @handle_lastfm_exceptions def test_user_is_hashable(self): # Arrange - artist = self.network.get_artist("Test Artist") - user = artist.get_top_fans(limit=1)[0].item - self.assertIsInstance(user, pylast.User) + user = self.network.get_user(self.username) # Act/Assert self.helper_is_thing_hashable(user) @@ -1232,18 +1230,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_different_things_in_top_list(things, pylast.Album) - @handle_lastfm_exceptions - def test_artist_top_fans(self): - # Arrange - # Pick an artist with plenty of plays - artist = self.network.get_top_artists(limit=1)[0].item - - # Act - things = artist.get_top_fans(limit=2) - - # Assert - self.helper_two_different_things_in_top_list(things, pylast.User) - @handle_lastfm_exceptions def test_country_top_tracks(self): # Arrange @@ -1339,17 +1325,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_get_assert_charts(lastfm_user, dates[0]) - @handle_lastfm_exceptions - def test_track_top_fans(self): - # Arrange - track = self.network.get_track("The Cinematic Orchestra", "Postlude") - - # Act - fans = track.get_top_fans() - - # Assert - self.helper_at_least_one_thing_in_top_list(fans, pylast.User) - # Commented out to avoid spamming # def test_share_spam(self): # # Arrange From c303fd0139e000f10f4cdec0d3795cd066b39fd6 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 17:37:24 +0300 Subject: [PATCH 02/13] Remove dead Last.fm attributes: releasedate in album.getInfo --- pylast/__init__.py | 6 ------ tests/test_pylast.py | 12 ------------ 2 files changed, 18 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 245e1a3..da167c6 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -1718,12 +1718,6 @@ class Album(_Opus): def __init__(self, artist, title, network, username=None): super(Album, self).__init__(artist, title, network, "album", username) - def get_release_date(self): - """Returns the release date of the album.""" - - return _extract(self._request( - self.ws_prefix + ".getInfo", cacheable=True), "releasedate") - def get_cover_image(self, size=COVER_EXTRA_LARGE): """ Returns a uri to the cover image diff --git a/tests/test_pylast.py b/tests/test_pylast.py index a2c27a6..efeb960 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -1879,18 +1879,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertGreater(count, 21) - @handle_lastfm_exceptions - def test_album_rel_date(self): - # Arrange - album = pylast.Album("Test Artist", "Test Release", self.network) - - # Act - date = album.get_release_date() - - # Assert - self.skip_if_lastfm_api_broken(date) - self.assertIn("2011", date) - @handle_lastfm_exceptions def test_album_tracks(self): # Arrange From 3e097b98fc42912075c2e44f16c368e46eb1205c Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 17:49:12 +0300 Subject: [PATCH 03/13] Remove @handle_lastfm_exceptions: dead Last.fm things will be removed --- tests/test_pylast.py | 168 ------------------------------------------- 1 file changed, 168 deletions(-) diff --git a/tests/test_pylast.py b/tests/test_pylast.py index efeb960..6a7799e 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -30,22 +30,6 @@ def load_secrets(): return doc -def handle_lastfm_exceptions(f): - """Skip exceptions caused by Last.fm's broken API""" - def wrapper(*args, **kw): - try: - return f(*args, **kw) - except pylast.WSError as e: - if (str(e) == "Invalid Method - " - "No method with that name in this package"): - msg = "Ignore broken Last.fm API: " + str(e) - print(msg) - pytest.skip(msg) - else: - raise(e) - return wrapper - - @flaky(max_runs=5, min_passes=1) class TestPyLast(unittest.TestCase): @@ -73,7 +57,6 @@ class TestPyLast(unittest.TestCase): if value is None or len(value) == 0: pytest.skip("Last.fm API is broken.") - @handle_lastfm_exceptions def test_scrobble(self): # Arrange artist = "Test Artist" @@ -91,7 +74,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(str(last_scrobble.track.title), str(title)) self.assertEqual(str(last_scrobble.timestamp), str(timestamp)) - @handle_lastfm_exceptions def test_unscrobble(self): # Arrange artist = "Test Artist 2" @@ -110,7 +92,6 @@ class TestPyLast(unittest.TestCase): last_scrobble = lastfm_user.get_recent_tracks(limit=2)[0] self.assertNotEqual(str(last_scrobble.timestamp), str(timestamp)) - @handle_lastfm_exceptions def test_add_album(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -127,7 +108,6 @@ class TestPyLast(unittest.TestCase): break self.assertTrue(value) - @handle_lastfm_exceptions def test_remove_album(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -149,7 +129,6 @@ class TestPyLast(unittest.TestCase): break self.assertFalse(value) - @handle_lastfm_exceptions def test_add_artist(self): # Arrange artist = "Test Artist 2" @@ -166,7 +145,6 @@ class TestPyLast(unittest.TestCase): break self.assertTrue(value) - @handle_lastfm_exceptions def test_remove_artist(self): # Arrange # Get plenty of artists @@ -187,7 +165,6 @@ class TestPyLast(unittest.TestCase): break self.assertFalse(value) - @handle_lastfm_exceptions def test_get_venue(self): # Arrange venue_name = "Last.fm Office" @@ -200,7 +177,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertEqual(str(venue.id), "8778225") - @handle_lastfm_exceptions def test_get_user_registration(self): # Arrange username = "RJ" @@ -217,7 +193,6 @@ class TestPyLast(unittest.TestCase): # Just check date because of timezones self.assertIn(u"2002-11-20 ", registered) - @handle_lastfm_exceptions def test_get_user_unixtime_registration(self): # Arrange username = "RJ" @@ -230,7 +205,6 @@ class TestPyLast(unittest.TestCase): # Just check date because of timezones self.assertEqual(unixtime_registered, u"1037793040") - @handle_lastfm_exceptions def test_get_genderless_user(self): # Arrange # Currently test_user has no gender set: @@ -242,7 +216,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertIsNone(gender) - @handle_lastfm_exceptions def test_get_countryless_user(self): # Arrange # Currently test_user has no country set: @@ -254,7 +227,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertIsNone(country) - @handle_lastfm_exceptions def test_love(self): # Arrange artist = "Test Artist" @@ -270,7 +242,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(str(loved[0].track.artist), "Test Artist") self.assertEqual(str(loved[0].track.title), "test title") - @handle_lastfm_exceptions def test_unlove(self): # Arrange artist = pylast.Artist("Test Artist", self.network) @@ -288,7 +259,6 @@ class TestPyLast(unittest.TestCase): self.assertNotEqual(str(loved.track.artist), "Test Artist") self.assertNotEqual(str(loved.track.title), "test title") - @handle_lastfm_exceptions def test_get_100_albums(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -299,7 +269,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertGreaterEqual(len(albums), 0) - @handle_lastfm_exceptions def test_get_limitless_albums(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -310,7 +279,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertGreaterEqual(len(albums), 0) - @handle_lastfm_exceptions def test_user_equals_none(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -321,7 +289,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertFalse(value) - @handle_lastfm_exceptions def test_user_not_equal_to_none(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -332,7 +299,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertTrue(value) - @handle_lastfm_exceptions def test_now_playing_user_with_no_scrobbles(self): # Arrange # Currently test-account has no scrobbles: @@ -344,7 +310,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertIsNone(current_track) - @handle_lastfm_exceptions def test_love_limits(self): # Arrange # Currently test-account has at least 23 loved tracks: @@ -356,7 +321,6 @@ class TestPyLast(unittest.TestCase): self.assertGreaterEqual(len(user.get_loved_tracks(limit=None)), 23) self.assertGreaterEqual(len(user.get_loved_tracks(limit=0)), 23) - @handle_lastfm_exceptions def test_update_now_playing(self): # Arrange artist = "Test Artist" @@ -375,7 +339,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(str(current_track.title), "test title") self.assertEqual(str(current_track.artist), "Test Artist") - @handle_lastfm_exceptions def test_album_tags_are_topitems(self): # Arrange albums = self.network.get_user('RJ').get_top_albums() @@ -398,7 +361,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(thing) self.assertEqual(len(things), 1) - @handle_lastfm_exceptions def test_album_is_hashable(self): # Arrange album = self.network.get_album("Test Artist", "Test Album") @@ -406,7 +368,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(album) - @handle_lastfm_exceptions def test_artist_is_hashable(self): # Arrange test_artist = self.network.get_artist("Test Artist") @@ -416,7 +377,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(artist) - @handle_lastfm_exceptions def test_country_is_hashable(self): # Arrange country = self.network.get_country("Italy") @@ -424,7 +384,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(country) - @handle_lastfm_exceptions def test_metro_is_hashable(self): # Arrange metro = self.network.get_metro("Helsinki", "Finland") @@ -432,7 +391,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(metro) - @handle_lastfm_exceptions def test_event_is_hashable(self): # Arrange user = self.network.get_user("RJ") @@ -441,7 +399,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(event) - @handle_lastfm_exceptions def test_group_is_hashable(self): # Arrange group = self.network.get_group("Audioscrobbler Beta") @@ -449,7 +406,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(group) - @handle_lastfm_exceptions def test_library_is_hashable(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -457,7 +413,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(library) - @handle_lastfm_exceptions def test_playlist_is_hashable(self): # Arrange playlist = pylast.Playlist( @@ -466,7 +421,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(playlist) - @handle_lastfm_exceptions def test_tag_is_hashable(self): # Arrange tag = self.network.get_top_tags(limit=1)[0] @@ -474,7 +428,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(tag) - @handle_lastfm_exceptions def test_track_is_hashable(self): # Arrange artist = self.network.get_artist("Test Artist") @@ -484,7 +437,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(track) - @handle_lastfm_exceptions def test_user_is_hashable(self): # Arrange user = self.network.get_user(self.username) @@ -492,7 +444,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(user) - @handle_lastfm_exceptions def test_venue_is_hashable(self): # Arrange venue_id = "8778225" # Last.fm office @@ -501,7 +452,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(venue) - @handle_lastfm_exceptions def test_xspf_is_hashable(self): # Arrange xspf = pylast.XSPF( @@ -510,7 +460,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(xspf) - @handle_lastfm_exceptions def test_invalid_xml(self): # Arrange # Currently causes PCDATA invalid Char value 25 @@ -525,7 +474,6 @@ class TestPyLast(unittest.TestCase): self.skip_if_lastfm_api_broken(total) self.assertGreaterEqual(int(total), 0) - @handle_lastfm_exceptions def test_user_play_count_in_track_info(self): # Arrange artist = "Test Artist" @@ -540,7 +488,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertGreaterEqual(count, 0) - @handle_lastfm_exceptions def test_user_loved_in_track_info(self): # Arrange artist = "Test Artist" @@ -557,7 +504,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(loved, bool) self.assertNotIsInstance(loved, str) - @handle_lastfm_exceptions def test_album_in_recent_tracks(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -569,7 +515,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertTrue(hasattr(track, 'album')) - @handle_lastfm_exceptions def test_album_in_artist_tracks(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -580,7 +525,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertTrue(hasattr(track, 'album')) - @handle_lastfm_exceptions def test_enable_rate_limiting(self): # Arrange self.assertFalse(self.network.is_rate_limited()) @@ -598,7 +542,6 @@ class TestPyLast(unittest.TestCase): self.assertTrue(self.network.is_rate_limited()) self.assertGreaterEqual(now - then, 0.2) - @handle_lastfm_exceptions def test_disable_rate_limiting(self): # Arrange self.network.enable_rate_limit() @@ -649,7 +592,6 @@ class TestPyLast(unittest.TestCase): for event in events[:2]: # checking first two should be enough self.assertIsInstance(event.get_headliner(), pylast.Artist) - @handle_lastfm_exceptions def test_artist_upcoming_events_returns_valid_ids(self): # Arrange artist = pylast.Artist("Test Artist", self.network) @@ -657,7 +599,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_upcoming_events_have_valid_ids(artist) - @handle_lastfm_exceptions def test_user_past_events_returns_valid_ids(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -665,7 +606,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_past_events_have_valid_ids(lastfm_user) - @handle_lastfm_exceptions def test_user_recommended_events_returns_valid_ids(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -676,7 +616,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_assert_events_have_valid_ids(events) - @handle_lastfm_exceptions def test_user_upcoming_events_returns_valid_ids(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -684,7 +623,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_upcoming_events_have_valid_ids(lastfm_user) - @handle_lastfm_exceptions def test_venue_past_events_returns_valid_ids(self): # Arrange venue_id = "8778225" # Last.fm office @@ -693,7 +631,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_past_events_have_valid_ids(venue) - @handle_lastfm_exceptions def test_venue_upcoming_events_returns_valid_ids(self): # Arrange venue_id = "8778225" # Last.fm office @@ -702,7 +639,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_upcoming_events_have_valid_ids(venue) - @handle_lastfm_exceptions def test_pickle(self): # Arrange import pickle @@ -719,7 +655,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertEqual(lastfm_user, loaded_user) - @handle_lastfm_exceptions def test_bio_published_date(self): # Arrange artist = pylast.Artist("Test Artist", self.network) @@ -731,7 +666,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(bio) self.assertGreaterEqual(len(bio), 1) - @handle_lastfm_exceptions def test_bio_content(self): # Arrange artist = pylast.Artist("Test Artist", self.network) @@ -743,7 +677,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(bio) self.assertGreaterEqual(len(bio), 1) - @handle_lastfm_exceptions def test_bio_summary(self): # Arrange artist = pylast.Artist("Test Artist", self.network) @@ -755,7 +688,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(bio) self.assertGreaterEqual(len(bio), 1) - @handle_lastfm_exceptions def test_album_wiki_content(self): # Arrange album = pylast.Album("Test Artist", "Test Album", self.network) @@ -767,7 +699,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(wiki) self.assertGreaterEqual(len(wiki), 1) - @handle_lastfm_exceptions def test_album_wiki_published_date(self): # Arrange album = pylast.Album("Test Artist", "Test Album", self.network) @@ -779,7 +710,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(wiki) self.assertGreaterEqual(len(wiki), 1) - @handle_lastfm_exceptions def test_album_wiki_summary(self): # Arrange album = pylast.Album("Test Artist", "Test Album", self.network) @@ -791,7 +721,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(wiki) self.assertGreaterEqual(len(wiki), 1) - @handle_lastfm_exceptions def test_track_wiki_content(self): # Arrange track = pylast.Track("Test Artist", "test title", self.network) @@ -803,7 +732,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(wiki) self.assertGreaterEqual(len(wiki), 1) - @handle_lastfm_exceptions def test_track_wiki_summary(self): # Arrange track = pylast.Track("Test Artist", "test title", self.network) @@ -815,7 +743,6 @@ class TestPyLast(unittest.TestCase): self.assertIsNotNone(wiki) self.assertGreaterEqual(len(wiki), 1) - @handle_lastfm_exceptions def test_lastfm_network_name(self): # Act name = str(self.network) @@ -847,7 +774,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_validate_results(result1, result2, result3) - @handle_lastfm_exceptions def test_cacheable_artist_get_shouts(self): # Arrange artist = self.network.get_artist("Test Artist") @@ -855,7 +781,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_validate_cacheable(artist, "get_shouts") - @handle_lastfm_exceptions def test_cacheable_event_get_shouts(self): # Arrange user = self.network.get_user("RJ") @@ -864,7 +789,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_validate_cacheable(event, "get_shouts") - @handle_lastfm_exceptions def test_cacheable_track_get_shouts(self): # Arrange track = self.network.get_top_tracks()[0].item @@ -872,7 +796,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_validate_cacheable(track, "get_shouts") - @handle_lastfm_exceptions def test_cacheable_group_get_members(self): # Arrange group = self.network.get_group("Audioscrobbler Beta") @@ -880,7 +803,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_validate_cacheable(group, "get_members") - @handle_lastfm_exceptions def test_cacheable_library(self): # Arrange library = pylast.Library(self.username, self.network) @@ -890,7 +812,6 @@ class TestPyLast(unittest.TestCase): self.helper_validate_cacheable(library, "get_artists") self.helper_validate_cacheable(library, "get_tracks") - @handle_lastfm_exceptions def test_cacheable_user_artist_tracks(self): # Arrange lastfm_user = self.network.get_authenticated_user() @@ -903,7 +824,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_validate_results(result1, result2, result3) - @handle_lastfm_exceptions def test_cacheable_user(self): # Arrange lastfm_user = self.network.get_authenticated_user() @@ -918,7 +838,6 @@ class TestPyLast(unittest.TestCase): self.helper_validate_cacheable(lastfm_user, "get_recommended_events") self.helper_validate_cacheable(lastfm_user, "get_shouts") - @handle_lastfm_exceptions def test_geo_get_events_in_location(self): # Arrange # Act @@ -932,7 +851,6 @@ class TestPyLast(unittest.TestCase): self.assertIn(event.get_venue().location['city'], ["London", "Camden"]) - @handle_lastfm_exceptions def test_geo_get_events_in_latlong(self): # Arrange # Act @@ -945,7 +863,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(event, pylast.Event) self.assertEqual(event.get_venue().location['city'], "Manchester") - @handle_lastfm_exceptions def test_geo_get_events_festival(self): # Arrange # Act @@ -965,7 +882,6 @@ class TestPyLast(unittest.TestCase): (start, end) = dates[0] self.assertLess(start, end) - @handle_lastfm_exceptions def test_get_metro_weekly_chart_dates(self): # Arrange # Act @@ -991,39 +907,32 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(chart[0], pylast.TopItem) self.assertIsInstance(chart[0].item, expected_type) - @handle_lastfm_exceptions def test_get_metro_artist_chart(self): # Arrange/Act/Assert self.helper_geo_chart("get_artist_chart") - @handle_lastfm_exceptions def test_get_metro_hype_artist_chart(self): # Arrange/Act/Assert self.helper_geo_chart("get_hype_artist_chart") - @handle_lastfm_exceptions def test_get_metro_unique_artist_chart(self): # Arrange/Act/Assert self.helper_geo_chart("get_unique_artist_chart") - @handle_lastfm_exceptions def test_get_metro_track_chart(self): # Arrange/Act/Assert self.helper_geo_chart("get_track_chart", expected_type=pylast.Track) - @handle_lastfm_exceptions def test_get_metro_hype_track_chart(self): # Arrange/Act/Assert self.helper_geo_chart( "get_hype_track_chart", expected_type=pylast.Track) - @handle_lastfm_exceptions def test_get_metro_unique_track_chart(self): # Arrange/Act/Assert self.helper_geo_chart( "get_unique_track_chart", expected_type=pylast.Track) - @handle_lastfm_exceptions def test_geo_get_metros(self): # Arrange # Act @@ -1034,7 +943,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(metros[0], pylast.Metro) self.assertEqual(metros[0].get_country(), "Poland") - @handle_lastfm_exceptions def test_geo_get_top_artists(self): # Arrange # Act @@ -1046,7 +954,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(artists[0], pylast.TopItem) self.assertIsInstance(artists[0].item, pylast.Artist) - @handle_lastfm_exceptions def test_geo_get_top_tracks(self): # Arrange # Act @@ -1058,7 +965,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(tracks[0], pylast.TopItem) self.assertIsInstance(tracks[0].item, pylast.Track) - @handle_lastfm_exceptions def test_metro_class(self): # Arrange # Act @@ -1073,7 +979,6 @@ class TestPyLast(unittest.TestCase): metro, pylast.Metro("Wellington", "New Zealand", self.network)) - @handle_lastfm_exceptions def test_get_album_play_links(self): # Arrange album1 = self.network.get_album("Portishead", "Dummy") @@ -1089,7 +994,6 @@ class TestPyLast(unittest.TestCase): self.assertIn("spotify:album:", links[0]) self.assertIn("spotify:album:", links[1]) - @handle_lastfm_exceptions def test_get_artist_play_links(self): # Arrange artists = ["Portishead", "Radiohead"] @@ -1102,7 +1006,6 @@ class TestPyLast(unittest.TestCase): self.assertIn("spotify:artist:", links[0]) self.assertIn("spotify:artist:", links[1]) - @handle_lastfm_exceptions def test_get_track_play_links(self): # Arrange track1 = self.network.get_track(artist="Portishead", title="Mysterons") @@ -1158,7 +1061,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(thing1, expected_type) self.assertIsInstance(thing2, expected_type) - @handle_lastfm_exceptions def test_user_get_top_tags_with_limit(self): # Arrange user = self.network.get_user("RJ") @@ -1170,7 +1072,6 @@ class TestPyLast(unittest.TestCase): self.skip_if_lastfm_api_broken(tags) self.helper_only_one_thing_in_top_list(tags, pylast.Tag) - @handle_lastfm_exceptions def test_network_get_top_artists_with_limit(self): # Arrange # Act @@ -1179,7 +1080,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(artists, pylast.Artist) - @handle_lastfm_exceptions def test_network_get_top_tags_with_limit(self): # Arrange # Act @@ -1188,7 +1088,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(tags, pylast.Tag) - @handle_lastfm_exceptions def test_network_get_top_tags_with_no_limit(self): # Arrange # Act @@ -1197,7 +1096,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_at_least_one_thing_in_top_list(tags, pylast.Tag) - @handle_lastfm_exceptions def test_network_get_top_tracks_with_limit(self): # Arrange # Act @@ -1206,7 +1104,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(tracks, pylast.Track) - @handle_lastfm_exceptions def test_artist_top_tracks(self): # Arrange # Pick an artist with plenty of plays @@ -1218,7 +1115,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_different_things_in_top_list(things, pylast.Track) - @handle_lastfm_exceptions def test_artist_top_albums(self): # Arrange # Pick an artist with plenty of plays @@ -1230,7 +1126,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_different_things_in_top_list(things, pylast.Album) - @handle_lastfm_exceptions def test_country_top_tracks(self): # Arrange country = self.network.get_country("Croatia") @@ -1241,7 +1136,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_different_things_in_top_list(things, pylast.Track) - @handle_lastfm_exceptions def test_country_network_top_tracks(self): # Arrange # Act @@ -1250,7 +1144,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_different_things_in_top_list(things, pylast.Track) - @handle_lastfm_exceptions def test_tag_top_tracks(self): # Arrange tag = self.network.get_tag("blues") @@ -1261,7 +1154,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_different_things_in_top_list(things, pylast.Track) - @handle_lastfm_exceptions def test_user_top_tracks(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -1295,7 +1187,6 @@ class TestPyLast(unittest.TestCase): self.helper_assert_chart(album_chart, pylast.Album) self.helper_assert_chart(track_chart, pylast.Track) - @handle_lastfm_exceptions def test_group_charts(self): # Arrange group = self.network.get_group("mnml") @@ -1305,7 +1196,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_get_assert_charts(group, dates[-2]) - @handle_lastfm_exceptions def test_tag_charts(self): # Arrange tag = self.network.get_tag("rock") @@ -1315,7 +1205,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_get_assert_charts(tag, dates[-2]) - @handle_lastfm_exceptions def test_user_charts(self): # Arrange lastfm_user = self.network.get_user("RJ") @@ -1344,7 +1233,6 @@ class TestPyLast(unittest.TestCase): # album/artist/event/track/user - @handle_lastfm_exceptions def test_album_shouts(self): # Arrange # Pick an artist with plenty of plays @@ -1357,7 +1245,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_things_in_list(shouts, pylast.Shout) - @handle_lastfm_exceptions def test_artist_shouts(self): # Arrange # Pick an artist with plenty of plays @@ -1369,7 +1256,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_things_in_list(shouts, pylast.Shout) - @handle_lastfm_exceptions def test_event_shouts(self): # Arrange event_id = 3478520 # Glasto 2014 @@ -1381,7 +1267,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_things_in_list(shouts, pylast.Shout) - @handle_lastfm_exceptions def test_track_shouts(self): # Arrange track = self.network.get_track("The Cinematic Orchestra", "Postlude") @@ -1392,7 +1277,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_things_in_list(shouts, pylast.Shout) - @handle_lastfm_exceptions def test_user_shouts(self): # Arrange user = self.network.get_user("RJ") @@ -1403,7 +1287,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_two_things_in_list(shouts, pylast.Shout) - @handle_lastfm_exceptions def test_album_data(self): # Arrange thing = self.network.get_album("Test Artist", "Test Album") @@ -1425,7 +1308,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual( "https://www.last.fm/music/test%2bartist/test%2balbum", url) - @handle_lastfm_exceptions def test_track_data(self): # Arrange thing = self.network.get_track("Test Artist", "test title") @@ -1448,7 +1330,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual( "https://www.last.fm/fr/music/test%2bartist/_/test%2btitle", url) - @handle_lastfm_exceptions def test_tag_top_artists(self): # Arrange tag = self.network.get_tag("blues") @@ -1459,7 +1340,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(artists, pylast.Artist) - @handle_lastfm_exceptions def test_country_top_artists(self): # Arrange country = self.network.get_country("Ukraine") @@ -1470,7 +1350,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(artists, pylast.Artist) - @handle_lastfm_exceptions def test_user_top_artists(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -1481,7 +1360,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(artists, pylast.Artist) - @handle_lastfm_exceptions def test_tag_top_albums(self): # Arrange tag = self.network.get_tag("blues") @@ -1492,7 +1370,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(albums, pylast.Album) - @handle_lastfm_exceptions def test_user_top_albums(self): # Arrange user = self.network.get_user("RJ") @@ -1503,7 +1380,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(albums, pylast.Album) - @handle_lastfm_exceptions def test_user_tagged_artists(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -1517,7 +1393,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_list(artists, pylast.Artist) - @handle_lastfm_exceptions def test_user_tagged_albums(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -1531,7 +1406,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_list(albums, pylast.Album) - @handle_lastfm_exceptions def test_user_tagged_tracks(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -1545,7 +1419,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_list(tracks, pylast.Track) - @handle_lastfm_exceptions def test_user_subscriber(self): # Arrange subscriber = self.network.get_user("RJ") @@ -1559,7 +1432,6 @@ class TestPyLast(unittest.TestCase): self.assertTrue(subscriber_is_subscriber) self.assertFalse(non_subscriber_is_subscriber) - @handle_lastfm_exceptions def test_user_get_image(self): # Arrange user = self.network.get_user("RJ") @@ -1570,7 +1442,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertTrue(url.startswith("https://")) - @handle_lastfm_exceptions def test_user_get_library(self): # Arrange user = self.network.get_user(self.username) @@ -1581,7 +1452,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertIsInstance(library, pylast.Library) - @handle_lastfm_exceptions def test_caching(self): # Arrange user = self.network.get_user("RJ") @@ -1597,7 +1467,6 @@ class TestPyLast(unittest.TestCase): self.network.disable_caching() self.assertFalse(self.network.is_caching_enabled()) - @handle_lastfm_exceptions def test_create_playlist(self): # Arrange title = "Test playlist" @@ -1613,7 +1482,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(playlist.get_description(), "Testing") self.assertEqual(playlist.get_user(), lastfm_user) - @handle_lastfm_exceptions def test_empty_playlist_unstreamable(self): # Arrange title = "Empty playlist" @@ -1627,7 +1495,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(playlist.get_duration(), 0) self.assertFalse(playlist.is_streamable()) - @handle_lastfm_exceptions def test_big_playlist_is_streamable(self): # Arrange # Find a big playlist on Last.fm, eg "top 100 classick rock songs" @@ -1648,7 +1515,6 @@ class TestPyLast(unittest.TestCase): self.assertGreater(playlist.get_duration(), 0) self.assertTrue(playlist.is_streamable()) - @handle_lastfm_exceptions def test_add_track_to_playlist(self): # Arrange title = "One track playlist" @@ -1664,7 +1530,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(len(playlist.get_tracks()), 1) self.assertTrue(playlist.has_track(track)) - @handle_lastfm_exceptions def test_album_mbid(self): # Arrange mbid = "a6a265bf-9f81-4055-8224-f7ac0aa6b937" @@ -1678,7 +1543,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(album.title.lower(), "test") self.assertEqual(album_mbid, mbid) - @handle_lastfm_exceptions def test_artist_mbid(self): # Arrange mbid = "7e84f845-ac16-41fe-9ff8-df12eb32af55" @@ -1690,7 +1554,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(artist, pylast.Artist) self.assertEqual(artist.name, "MusicBrainz Test Artist") - @handle_lastfm_exceptions def test_track_mbid(self): # Arrange mbid = "ebc037b1-cc9c-44f2-a21f-83c219f0e1e0" @@ -1704,7 +1567,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(track.title, "first") self.assertEqual(track_mbid, mbid) - @handle_lastfm_exceptions def test_artist_listener_count(self): # Arrange artist = self.network.get_artist("Test Artist") @@ -1716,7 +1578,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(count, int) self.assertGreater(count, 0) - @handle_lastfm_exceptions def test_event_attendees(self): # Arrange user = self.network.get_user("RJ") @@ -1729,7 +1590,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(users, list) self.assertIsInstance(users[0], pylast.User) - @handle_lastfm_exceptions def test_tag_artist(self): # Arrange artist = self.network.get_artist("Test Artist") @@ -1748,7 +1608,6 @@ class TestPyLast(unittest.TestCase): break self.assertTrue(found) - @handle_lastfm_exceptions def test_remove_tag_of_type_text(self): # Arrange tag = "testing" # text @@ -1767,7 +1626,6 @@ class TestPyLast(unittest.TestCase): break self.assertFalse(found) - @handle_lastfm_exceptions def test_remove_tag_of_type_tag(self): # Arrange tag = pylast.Tag("testing", self.network) # Tag @@ -1786,7 +1644,6 @@ class TestPyLast(unittest.TestCase): break self.assertFalse(found) - @handle_lastfm_exceptions def test_remove_tags(self): # Arrange tags = ["removetag1", "removetag2"] @@ -1810,7 +1667,6 @@ class TestPyLast(unittest.TestCase): self.assertFalse(found1) self.assertFalse(found2) - @handle_lastfm_exceptions def test_set_tags(self): # Arrange tags = ["sometag1", "sometag2"] @@ -1835,7 +1691,6 @@ class TestPyLast(unittest.TestCase): self.assertTrue(found1) self.assertTrue(found2) - @handle_lastfm_exceptions def test_tracks_notequal(self): # Arrange track1 = pylast.Track("Test Artist", "test title", self.network) @@ -1845,7 +1700,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertNotEqual(track1, track2) - @handle_lastfm_exceptions def test_track_id(self): # Arrange track = pylast.Track("Test Artist", "test title", self.network) @@ -1857,7 +1711,6 @@ class TestPyLast(unittest.TestCase): self.skip_if_lastfm_api_broken(id) self.assertEqual(id, "14053327") - @handle_lastfm_exceptions def test_track_title_prop_caps(self): # Arrange track = pylast.Track("test artist", "test title", self.network) @@ -1868,7 +1721,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertEqual(title, "test title") - @handle_lastfm_exceptions def test_track_listener_count(self): # Arrange track = pylast.Track("test artist", "test title", self.network) @@ -1879,7 +1731,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertGreater(count, 21) - @handle_lastfm_exceptions def test_album_tracks(self): # Arrange album = pylast.Album("Test Artist", "Test Release", self.network) @@ -1894,7 +1745,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(len(tracks), 4) self.assertTrue(url.startswith("https://www.last.fm/music/test")) - @handle_lastfm_exceptions def test_tags(self): # Arrange tag1 = self.network.get_tag("blues") @@ -1915,7 +1765,6 @@ class TestPyLast(unittest.TestCase): self.assertTrue(tag1 != tag2) self.assertEqual(url, "https://www.last.fm/tag/blues") - @handle_lastfm_exceptions def test_tags_similar(self): # Arrange tag = self.network.get_tag("blues") @@ -1932,7 +1781,6 @@ class TestPyLast(unittest.TestCase): break self.assertTrue(found) - @handle_lastfm_exceptions def test_artists(self): # Arrange artist1 = self.network.get_artist("Radiohead") @@ -1956,7 +1804,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(mbid, "a74b1b7f-71a5-4011-9441-d0b5e4122711") self.assertIsInstance(streamable, bool) - @handle_lastfm_exceptions def test_events(self): # Arrange event_id_1 = 3162700 # Glasto 2013 @@ -1991,7 +1838,6 @@ class TestPyLast(unittest.TestCase): self.assertGreater(review_count, 0) self.assertGreater(attendance_count, 100) - @handle_lastfm_exceptions def test_countries(self): # Arrange country1 = pylast.Country("Italy", self.network) @@ -2010,7 +1856,6 @@ class TestPyLast(unittest.TestCase): self.assertTrue(country1 != country2) self.assertEqual(url, "https://www.last.fm/place/italy") - @handle_lastfm_exceptions def test_track_eq_none_is_false(self): # Arrange track1 = None @@ -2019,7 +1864,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertFalse(track1 == track2) - @handle_lastfm_exceptions def test_track_ne_none_is_true(self): # Arrange track1 = None @@ -2028,7 +1872,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertTrue(track1 != track2) - @handle_lastfm_exceptions def test_artist_eq_none_is_false(self): # Arrange artist1 = None @@ -2037,7 +1880,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertFalse(artist1 == artist2) - @handle_lastfm_exceptions def test_artist_ne_none_is_true(self): # Arrange artist1 = None @@ -2046,7 +1888,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertTrue(artist1 != artist2) - @handle_lastfm_exceptions def test_album_eq_none_is_false(self): # Arrange album1 = None @@ -2055,7 +1896,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertFalse(album1 == album2) - @handle_lastfm_exceptions def test_album_ne_none_is_true(self): # Arrange album1 = None @@ -2064,7 +1904,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertTrue(album1 != album2) - @handle_lastfm_exceptions def test_event_eq_none_is_false(self): # Arrange event1 = None @@ -2074,7 +1913,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertFalse(event1 == event2) - @handle_lastfm_exceptions def test_event_ne_none_is_true(self): # Arrange event1 = None @@ -2084,7 +1922,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertTrue(event1 != event2) - @handle_lastfm_exceptions def test_band_members(self): # Arrange artist = pylast.Artist("The Beatles", self.network) @@ -2096,7 +1933,6 @@ class TestPyLast(unittest.TestCase): self.skip_if_lastfm_api_broken(band_members) self.assertGreaterEqual(len(band_members), 4) - @handle_lastfm_exceptions def test_no_band_members(self): # Arrange artist = pylast.Artist("John Lennon", self.network) @@ -2107,7 +1943,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertIsNone(band_members) - @handle_lastfm_exceptions def test_get_recent_tracks_from_to(self): # Arrange lastfm_user = self.network.get_user("RJ") @@ -2128,7 +1963,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(str(tracks[0].track.artist), "Johnny Cash") self.assertEqual(str(tracks[0].track.title), "Ring of Fire") - @handle_lastfm_exceptions def test_artist_get_correction(self): # Arrange artist = pylast.Artist("guns and roses", self.network) @@ -2139,7 +1973,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertEqual(corrected_artist_name, "Guns N' Roses") - @handle_lastfm_exceptions def test_track_get_correction(self): # Arrange track = pylast.Track("Guns N' Roses", "mrbrownstone", self.network) @@ -2150,7 +1983,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertEqual(corrected_track_name, "Mr. Brownstone") - @handle_lastfm_exceptions def test_track_with_no_mbid(self): # Arrange track = pylast.Track("Static-X", "Set It Off", self.network) From f419c39ef04f5d53bdd945586ceb0cef160161ec Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 18:03:00 +0300 Subject: [PATCH 04/13] Remove dead Last.fm library methods --- pylast/__init__.py | 122 ------------------------------------------- tests/test_pylast.py | 111 --------------------------------------- 2 files changed, 233 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index da167c6..46a61b5 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -2433,86 +2433,8 @@ class Library(_BaseObject): def get_user(self): """Returns the user who owns this library.""" - return self.user - def add_album(self, album): - """Add an album to this library.""" - - params = self._get_params() - params["artist"] = album.get_artist().get_name() - params["album"] = album.get_name() - - self._request("library.addAlbum", False, params) - - def remove_album(self, album): - """Remove an album from this library.""" - - params = self._get_params() - params["artist"] = album.get_artist().get_name() - params["album"] = album.get_name() - - self._request(self.ws_prefix + ".removeAlbum", False, params) - - def add_artist(self, artist): - """Add an artist to this library.""" - - params = self._get_params() - if type(artist) == str: - params["artist"] = artist - else: - params["artist"] = artist.get_name() - - self._request(self.ws_prefix + ".addArtist", False, params) - - def remove_artist(self, artist): - """Remove an artist from this library.""" - - params = self._get_params() - if type(artist) == str: - params["artist"] = artist - else: - params["artist"] = artist.get_name() - - self._request(self.ws_prefix + ".removeArtist", False, params) - - def add_track(self, track): - """Add a track to this library.""" - - params = self._get_params() - params["track"] = track.get_title() - - self._request(self.ws_prefix + ".addTrack", False, params) - - def get_albums(self, artist=None, limit=50, cacheable=True): - """ - Returns a sequence of Album objects - If no artist is specified, it will return all, sorted by decreasing - play count. - If limit==None it will return all (may take a while) - """ - - params = self._get_params() - if artist: - params["artist"] = artist - - seq = [] - for node in _collect_nodes( - limit, - self, - self.ws_prefix + ".getAlbums", - cacheable, - params): - name = _extract(node, "name") - artist = _extract(node, "name", 1) - playcount = _number(_extract(node, "playcount")) - tagcount = _number(_extract(node, "tagcount")) - - seq.append(LibraryItem( - Album(artist, name, self.network), playcount, tagcount)) - - return seq - def get_artists(self, limit=50, cacheable=True): """ Returns a sequence of Album objects @@ -2535,50 +2457,6 @@ class Library(_BaseObject): return seq - def get_tracks(self, artist=None, album=None, limit=50, cacheable=True): - """ - Returns a sequence of Album objects - If limit==None it will return all (may take a while) - """ - - params = self._get_params() - if artist: - params["artist"] = artist - if album: - params["album"] = album - - seq = [] - for node in _collect_nodes( - limit, - self, - self.ws_prefix + ".getTracks", - cacheable, - params): - name = _extract(node, "name") - artist = _extract(node, "name", 1) - playcount = _number(_extract(node, "playcount")) - tagcount = _number(_extract(node, "tagcount")) - - seq.append(LibraryItem( - Track(artist, name, self.network), playcount, tagcount)) - - return seq - - def remove_scrobble(self, artist, title, timestamp): - """Remove a scrobble from a user's Last.fm library. Parameters: - artist (Required) : The artist that composed the track - title (Required) : The name of the track - timestamp (Required) : The unix timestamp of the scrobble - that you wish to remove - """ - - params = self._get_params() - params["artist"] = artist - params["track"] = title - params["timestamp"] = timestamp - - self._request(self.ws_prefix + ".removeScrobble", False, params) - class Playlist(_BaseObject): """A Last.fm user playlist.""" diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 6a7799e..e5e415e 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -74,97 +74,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(str(last_scrobble.track.title), str(title)) self.assertEqual(str(last_scrobble.timestamp), str(timestamp)) - def test_unscrobble(self): - # Arrange - artist = "Test Artist 2" - title = "Test Title 2" - timestamp = self.unix_timestamp() - library = pylast.Library(user=self.username, network=self.network) - self.network.scrobble(artist=artist, title=title, timestamp=timestamp) - lastfm_user = self.network.get_user(self.username) - - # Act - library.remove_scrobble( - artist=artist, title=title, timestamp=timestamp) - - # Assert - # limit=2 to ignore now-playing: - last_scrobble = lastfm_user.get_recent_tracks(limit=2)[0] - self.assertNotEqual(str(last_scrobble.timestamp), str(timestamp)) - - def test_add_album(self): - # Arrange - library = pylast.Library(user=self.username, network=self.network) - album = self.network.get_album("Test Artist", "Test Album") - - # Act - library.add_album(album) - - # Assert - my_albums = library.get_albums() - for my_album in my_albums: - value = (album == my_album[0]) - if value: - break - self.assertTrue(value) - - def test_remove_album(self): - # Arrange - library = pylast.Library(user=self.username, network=self.network) - # Pick an artist with plenty of albums - artist = self.network.get_top_artists(limit=1)[0].item - albums = artist.get_top_albums() - # Pick a random one to avoid problems running concurrent tests - album = choice(albums)[0] - library.add_album(album) - - # Act - library.remove_album(album) - - # Assert - my_albums = library.get_albums() - for my_album in my_albums: - value = (album == my_album[0]) - if value: - break - self.assertFalse(value) - - def test_add_artist(self): - # Arrange - artist = "Test Artist 2" - library = pylast.Library(user=self.username, network=self.network) - - # Act - library.add_artist(artist) - - # Assert - artists = library.get_artists() - for artist in artists: - value = (str(artist[0]) == "Test Artist 2") - if value: - break - self.assertTrue(value) - - def test_remove_artist(self): - # Arrange - # Get plenty of artists - artists = self.network.get_top_artists() - # Pick a random one to avoid problems running concurrent tests - my_artist = choice(artists).item - library = pylast.Library(user=self.username, network=self.network) - library.add_artist(my_artist) - - # Act - library.remove_artist(my_artist) - - # Assert - artists = library.get_artists() - for artist in artists: - value = (artist[0] == my_artist) - if value: - break - self.assertFalse(value) - def test_get_venue(self): # Arrange venue_name = "Last.fm Office" @@ -259,26 +168,6 @@ class TestPyLast(unittest.TestCase): self.assertNotEqual(str(loved.track.artist), "Test Artist") self.assertNotEqual(str(loved.track.title), "test title") - def test_get_100_albums(self): - # Arrange - library = pylast.Library(user=self.username, network=self.network) - - # Act - albums = library.get_albums(limit=100) - - # Assert - self.assertGreaterEqual(len(albums), 0) - - def test_get_limitless_albums(self): - # Arrange - library = pylast.Library(user=self.username, network=self.network) - - # Act - albums = library.get_albums(limit=None) - - # Assert - self.assertGreaterEqual(len(albums), 0) - def test_user_equals_none(self): # Arrange lastfm_user = self.network.get_user(self.username) From 56e193d14903225964bedb88da959b20a2614019 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 18:11:48 +0300 Subject: [PATCH 05/13] Remove dead Last.fm playlist methods --- pylast/__init__.py | 219 ------------------------------------------- tests/test_pylast.py | 80 ---------------- 2 files changed, 299 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 46a61b5..f1b5880 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -296,24 +296,6 @@ class _Network(object): self.last_call_time = now - def create_new_playlist(self, title, description): - """ - Creates a playlist for the authenticated user and returns it - title: The title of the new playlist. - description: The description of the new playlist. - """ - - params = {} - params['title'] = title - params['description'] = description - - doc = _Request(self, 'playlist.create', params).execute(False) - - e_id = doc.getElementsByTagName("id")[0].firstChild.data - user = doc.getElementsByTagName('playlists')[0].getAttribute('user') - - return Playlist(user, e_id, self) - def get_top_artists(self, limit=None, cacheable=True): """Returns the most played artists as a sequence of TopItem objects.""" @@ -815,7 +797,6 @@ class LastFMNetwork(_Network): "artist": "music/%(artist)s", "event": "event/%(id)s", "country": "place/%(country_name)s", - "playlist": "user/%(user)s/library/playlists/%(appendix)s", "tag": "tag/%(name)s", "track": "music/%(artist)s/_/%(title)s", "group": "group/%(name)s", @@ -880,7 +861,6 @@ class LibreFMNetwork(_Network): "artist": "artist/%(artist)s", "event": "event/%(id)s", "country": "place/%(country_name)s", - "playlist": "user/%(user)s/library/playlists/%(appendix)s", "tag": "tag/%(name)s", "track": "music/%(artist)s/_/%(title)s", "group": "group/%(name)s", @@ -2458,148 +2438,6 @@ class Library(_BaseObject): return seq -class Playlist(_BaseObject): - """A Last.fm user playlist.""" - - id = None - user = None - - __hash__ = _BaseObject.__hash__ - - def __init__(self, user, playlist_id, network): - _BaseObject.__init__(self, network, "playlist") - - if isinstance(user, User): - self.user = user - else: - self.user = User(user, self.network) - - self.id = playlist_id - - @_string_output - def __str__(self): - return repr(self.user) + "'s playlist # " + repr(self.id) - - def _get_info_node(self): - """ - Returns the node from user.getPlaylists where this playlist's info is. - """ - - doc = self._request("user.getPlaylists", True) - - for node in doc.getElementsByTagName("playlist"): - if _extract(node, "id") == str(self.get_id()): - return node - - def _get_params(self): - return {'user': self.user.get_name(), 'playlistID': self.get_id()} - - def get_id(self): - """Returns the playlist ID.""" - - return self.id - - def get_user(self): - """Returns the owner user of this playlist.""" - - return self.user - - def get_tracks(self): - """Returns a list of the tracks on this user playlist.""" - - uri = _unicode('lastfm://playlist/%s') % self.get_id() - - return XSPF(uri, self.network).get_tracks() - - def add_track(self, track): - """Adds a Track to this Playlist.""" - - params = self._get_params() - params['artist'] = track.get_artist().get_name() - params['track'] = track.get_title() - - self._request('playlist.addTrack', False, params) - - def get_title(self): - """Returns the title of this playlist.""" - - return _extract(self._get_info_node(), "title") - - def get_creation_date(self): - """Returns the creation date of this playlist.""" - - return _extract(self._get_info_node(), "date") - - def get_size(self): - """Returns the number of tracks in this playlist.""" - - return _number(_extract(self._get_info_node(), "size")) - - def get_description(self): - """Returns the description of this playlist.""" - - return _extract(self._get_info_node(), "description") - - def get_duration(self): - """Returns the duration of this playlist in milliseconds.""" - - return _number(_extract(self._get_info_node(), "duration")) - - def is_streamable(self): - """ - Returns True if the playlist is streamable. - For a playlist to be streamable, it needs at least 45 tracks by 15 - different artists.""" - - if _extract(self._get_info_node(), "streamable") == '1': - return True - else: - return False - - def has_track(self, track): - """Checks to see if track is already in the playlist. - * track: Any Track object. - """ - - return track in self.get_tracks() - - def get_cover_image(self, size=COVER_EXTRA_LARGE): - """ - Returns a uri to the cover image - size can be one of: - COVER_MEGA - COVER_EXTRA_LARGE - COVER_LARGE - COVER_MEDIUM - COVER_SMALL - """ - - return _extract(self._get_info_node(), "image")[size] - - def get_url(self, domain_name=DOMAIN_ENGLISH): - """Returns the url of the playlist on the network. - * domain_name: The network's language domain. Possible values: - o DOMAIN_ENGLISH - o DOMAIN_GERMAN - o DOMAIN_SPANISH - o DOMAIN_FRENCH - o DOMAIN_ITALIAN - o DOMAIN_POLISH - o DOMAIN_PORTUGUESE - o DOMAIN_SWEDISH - o DOMAIN_TURKISH - o DOMAIN_RUSSIAN - o DOMAIN_JAPANESE - o DOMAIN_CHINESE - """ - - english_url = _extract(self._get_info_node(), "url") - appendix = english_url[english_url.rfind("/") + 1:] - - return self.network._get_url(domain_name, "playlist") % { - 'appendix': appendix, "user": self.get_user().get_name()} - - class Tag(_BaseObject, _Chartable): """A Last.fm object tag.""" @@ -2895,51 +2733,6 @@ class Group(_BaseObject, _Chartable): return users -class XSPF(_BaseObject): - "A Last.fm XSPF playlist.""" - - uri = None - - __hash__ = _BaseObject.__hash__ - - def __init__(self, uri, network): - _BaseObject.__init__(self, network, None) - - self.uri = uri - - def _get_params(self): - return {'playlistURL': self.get_uri()} - - @_string_output - def __str__(self): - return self.get_uri() - - def __eq__(self, other): - return self.get_uri() == other.get_uri() - - def __ne__(self, other): - return self.get_uri() != other.get_uri() - - def get_uri(self): - """Returns the Last.fm playlist URI. """ - - return self.uri - - def get_tracks(self): - """Returns the tracks on this playlist.""" - - doc = self._request('playlist.fetch', True) - - seq = [] - for node in doc.getElementsByTagName('track'): - title = _extract(node, 'title') - artist = _extract(node, 'creator') - - seq.append(Track(artist, title, self.network)) - - return seq - - class User(_BaseObject, _Chartable): """A Last.fm user.""" @@ -3101,18 +2894,6 @@ class User(_BaseObject, _Chartable): return seq - def get_playlists(self): - """Returns a list of Playlists that this user owns.""" - - doc = self._request(self.ws_prefix + ".getPlaylists", True) - - playlists = [] - for playlist_id in _extract_all(doc, "id"): - playlists.append( - Playlist(self.get_name(), playlist_id, self.network)) - - return playlists - def get_now_playing(self): """ Returns the currently playing track, or None if nothing is playing. diff --git a/tests/test_pylast.py b/tests/test_pylast.py index e5e415e..1739bd9 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -5,7 +5,6 @@ Integration (not unit) tests for pylast.py from flaky import flaky import os import pytest -from random import choice import time import unittest @@ -302,14 +301,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(library) - def test_playlist_is_hashable(self): - # Arrange - playlist = pylast.Playlist( - user="RJ", playlist_id="1k1qp_doglist", network=self.network) - - # Act/Assert - self.helper_is_thing_hashable(playlist) - def test_tag_is_hashable(self): # Arrange tag = self.network.get_top_tags(limit=1)[0] @@ -341,14 +332,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(venue) - def test_xspf_is_hashable(self): - # Arrange - xspf = pylast.XSPF( - uri="lastfm://playlist/1k1qp_doglist", network=self.network) - - # Act/Assert - self.helper_is_thing_hashable(xspf) - def test_invalid_xml(self): # Arrange # Currently causes PCDATA invalid Char value 25 @@ -1356,69 +1339,6 @@ class TestPyLast(unittest.TestCase): self.network.disable_caching() self.assertFalse(self.network.is_caching_enabled()) - def test_create_playlist(self): - # Arrange - title = "Test playlist" - description = "Testing" - lastfm_user = self.network.get_user(self.username) - - # Act - playlist = self.network.create_new_playlist(title, description) - - # Assert - self.assertIsInstance(playlist, pylast.Playlist) - self.assertEqual(playlist.get_title(), "Test playlist") - self.assertEqual(playlist.get_description(), "Testing") - self.assertEqual(playlist.get_user(), lastfm_user) - - def test_empty_playlist_unstreamable(self): - # Arrange - title = "Empty playlist" - description = "Unstreamable" - - # Act - playlist = self.network.create_new_playlist(title, description) - - # Assert - self.assertEqual(playlist.get_size(), 0) - self.assertEqual(playlist.get_duration(), 0) - self.assertFalse(playlist.is_streamable()) - - def test_big_playlist_is_streamable(self): - # Arrange - # Find a big playlist on Last.fm, eg "top 100 classick rock songs" - user = "kaxior" - id = 10417943 - playlist = pylast.Playlist(user, id, self.network) - self.assertEqual( - playlist.get_url(), - "https://www.last.fm/user/kaxior/library/" - "playlists/67ajb_top_100_classick_rock_songs") - - # Act - # Nothing - - # Assert - self.assertIsInstance(playlist, pylast.Playlist) - self.assertGreaterEqual(playlist.get_size(), 45) - self.assertGreater(playlist.get_duration(), 0) - self.assertTrue(playlist.is_streamable()) - - def test_add_track_to_playlist(self): - # Arrange - title = "One track playlist" - description = "Testing" - playlist = self.network.create_new_playlist(title, description) - track = pylast.Track("Test Artist", "test title", self.network) - - # Act - playlist.add_track(track) - - # Assert - self.assertEqual(playlist.get_size(), 1) - self.assertEqual(len(playlist.get_tracks()), 1) - self.assertTrue(playlist.has_track(track)) - def test_album_mbid(self): # Arrange mbid = "a6a265bf-9f81-4055-8224-f7ac0aa6b937" From 6d738d3f431a6113f100e23e97c50007793ab466 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 18:24:13 +0300 Subject: [PATCH 06/13] Remove dead Last.fm artist/shout methods --- pylast/__init__.py | 92 ---------------------------- tests/test_pylast.py | 141 ------------------------------------------- 2 files changed, 233 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index f1b5880..f0436d1 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -708,39 +708,6 @@ class _Network(object): if remaining_tracks: self.scrobble_many(remaining_tracks) - def get_play_links(self, link_type, things, cacheable=True): - method = link_type + ".getPlaylinks" - params = {} - - for i, thing in enumerate(things): - if link_type == "artist": - params['artist[' + str(i) + ']'] = thing - elif link_type == "album": - params['artist[' + str(i) + ']'] = thing.artist - params['album[' + str(i) + ']'] = thing.title - elif link_type == "track": - params['artist[' + str(i) + ']'] = thing.artist - params['track[' + str(i) + ']'] = thing.title - - doc = _Request(self, method, params).execute(cacheable) - - seq = [] - - for node in doc.getElementsByTagName("externalids"): - spotify = _extract(node, "spotify") - seq.append(spotify) - - return seq - - def get_artist_play_links(self, artists, cacheable=True): - return self.get_play_links("artist", artists, cacheable) - - def get_album_play_links(self, albums, cacheable=True): - return self.get_play_links("album", albums, cacheable) - - def get_track_play_links(self, tracks, cacheable=True): - return self.get_play_links("track", tracks, cacheable) - class LastFMNetwork(_Network): @@ -1169,8 +1136,6 @@ ImageSizes = collections.namedtuple( Image = collections.namedtuple( "Image", [ "title", "url", "dateadded", "format", "owner", "sizes", "votes"]) -Shout = collections.namedtuple( - "Shout", ["body", "author", "date"]) def _string_output(func): @@ -1301,26 +1266,6 @@ class _BaseObject(object): return _extract(node, section) - def get_shouts(self, limit=50, cacheable=False): - """ - Returns a sequence of Shout objects - """ - - shouts = [] - for node in _collect_nodes( - limit, - self, - self.ws_prefix + ".getShouts", - cacheable): - shouts.append( - Shout( - _extract(node, "body"), - User(_extract(node, "author"), self.network), - _extract(node, "date") - ) - ) - return shouts - class _Chartable(object): """Common functions for classes with charts.""" @@ -1887,13 +1832,6 @@ class Artist(_BaseObject, _Taggable): """Returns the content of the artist's biography.""" return self.get_bio("content", language) - def get_upcoming_events(self): - """Returns a list of the upcoming Events for this artist.""" - - doc = self._request(self.ws_prefix + '.getEvents', True) - - return _extract_events_from_doc(doc, self.network) - def get_similar(self, limit=None): """Returns the similar artists on the network.""" @@ -1954,16 +1892,6 @@ class Artist(_BaseObject, _Taggable): return self.network._get_url( domain_name, "artist") % {'artist': artist} - def shout(self, message): - """ - Post a shout - """ - - params = self._get_params() - params["message"] = message - - self._request("artist.Shout", False, params) - def get_band_members(self): """Returns a list of band members or None if unknown.""" @@ -2137,16 +2065,6 @@ class Event(_BaseObject): return self.network._get_url( domain_name, "event") % {'id': self.get_id()} - def shout(self, message): - """ - Post a shout - """ - - params = self._get_params() - params["message"] = message - - self._request("event.Shout", False, params) - class Country(_BaseObject): """A country at Last.fm.""" @@ -3232,16 +3150,6 @@ class User(_BaseObject, _Chartable): return Library(self, self.network) - def shout(self, message): - """ - Post a shout - """ - - params = self._get_params() - params["message"] = message - - self._request(self.ws_prefix + ".Shout", False, params) - class AuthenticatedUser(User): def __init__(self, network): diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 1739bd9..717c1be 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -464,13 +464,6 @@ class TestPyLast(unittest.TestCase): for event in events[:2]: # checking first two should be enough self.assertIsInstance(event.get_headliner(), pylast.Artist) - def test_artist_upcoming_events_returns_valid_ids(self): - # Arrange - artist = pylast.Artist("Test Artist", self.network) - - # Act/Assert - self.helper_upcoming_events_have_valid_ids(artist) - def test_user_past_events_returns_valid_ids(self): # Arrange lastfm_user = self.network.get_user(self.username) @@ -646,28 +639,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_validate_results(result1, result2, result3) - def test_cacheable_artist_get_shouts(self): - # Arrange - artist = self.network.get_artist("Test Artist") - - # Act/Assert - self.helper_validate_cacheable(artist, "get_shouts") - - def test_cacheable_event_get_shouts(self): - # Arrange - user = self.network.get_user("RJ") - event = user.get_past_events(limit=1)[0] - - # Act/Assert - self.helper_validate_cacheable(event, "get_shouts") - - def test_cacheable_track_get_shouts(self): - # Arrange - track = self.network.get_top_tracks()[0].item - - # Act/Assert - self.helper_validate_cacheable(track, "get_shouts") - def test_cacheable_group_get_members(self): # Arrange group = self.network.get_group("Audioscrobbler Beta") @@ -708,7 +679,6 @@ class TestPyLast(unittest.TestCase): self.helper_validate_cacheable(lastfm_user, "get_recent_tracks") self.helper_validate_cacheable(lastfm_user, "get_recommended_artists") self.helper_validate_cacheable(lastfm_user, "get_recommended_events") - self.helper_validate_cacheable(lastfm_user, "get_shouts") def test_geo_get_events_in_location(self): # Arrange @@ -851,48 +821,6 @@ class TestPyLast(unittest.TestCase): metro, pylast.Metro("Wellington", "New Zealand", self.network)) - def test_get_album_play_links(self): - # Arrange - album1 = self.network.get_album("Portishead", "Dummy") - album2 = self.network.get_album("Radiohead", "OK Computer") - albums = [album1, album2] - - # Act - links = self.network.get_album_play_links(albums) - - # Assert - self.assertIsInstance(links, list) - self.assertEqual(len(links), 2) - self.assertIn("spotify:album:", links[0]) - self.assertIn("spotify:album:", links[1]) - - def test_get_artist_play_links(self): - # Arrange - artists = ["Portishead", "Radiohead"] - # Act - links = self.network.get_artist_play_links(artists) - - # Assert - self.assertIsInstance(links, list) - self.assertEqual(len(links), 2) - self.assertIn("spotify:artist:", links[0]) - self.assertIn("spotify:artist:", links[1]) - - def test_get_track_play_links(self): - # Arrange - track1 = self.network.get_track(artist="Portishead", title="Mysterons") - track2 = self.network.get_track(artist="Radiohead", title="Creep") - tracks = [track1, track2] - - # Act - links = self.network.get_track_play_links(tracks) - - # Assert - self.assertIsInstance(links, list) - self.assertEqual(len(links), 2) - self.assertIn("spotify:track:", links[0]) - self.assertIn("spotify:track:", links[1]) - def helper_at_least_one_thing_in_top_list(self, things, expected_type): # Assert self.assertGreater(len(things), 1) @@ -1105,60 +1033,6 @@ class TestPyLast(unittest.TestCase): # album/artist/event/track/user - def test_album_shouts(self): - # Arrange - # Pick an artist with plenty of plays - artist = self.network.get_top_artists(limit=1)[0].item - album = artist.get_top_albums(limit=1)[0].item - - # Act - shouts = album.get_shouts(limit=2) - - # Assert - self.helper_two_things_in_list(shouts, pylast.Shout) - - def test_artist_shouts(self): - # Arrange - # Pick an artist with plenty of plays - artist = self.network.get_top_artists(limit=1)[0].item - - # Act - shouts = artist.get_shouts(limit=2) - - # Assert - self.helper_two_things_in_list(shouts, pylast.Shout) - - def test_event_shouts(self): - # Arrange - event_id = 3478520 # Glasto 2014 - event = pylast.Event(event_id, self.network) - - # Act - shouts = event.get_shouts(limit=2) - - # Assert - self.helper_two_things_in_list(shouts, pylast.Shout) - - def test_track_shouts(self): - # Arrange - track = self.network.get_track("The Cinematic Orchestra", "Postlude") - - # Act - shouts = track.get_shouts(limit=2) - - # Assert - self.helper_two_things_in_list(shouts, pylast.Shout) - - def test_user_shouts(self): - # Arrange - user = self.network.get_user("RJ") - - # Act - shouts = user.get_shouts(limit=2) - - # Assert - self.helper_two_things_in_list(shouts, pylast.Shout) - def test_album_data(self): # Arrange thing = self.network.get_album("Test Artist", "Test Album") @@ -1324,21 +1198,6 @@ class TestPyLast(unittest.TestCase): # Assert self.assertIsInstance(library, pylast.Library) - def test_caching(self): - # Arrange - user = self.network.get_user("RJ") - - # Act - self.network.enable_caching() - shouts1 = user.get_shouts(limit=1, cacheable=True) - shouts2 = user.get_shouts(limit=1, cacheable=True) - - # Assert - self.assertTrue(self.network.is_caching_enabled()) - self.assertEqual(shouts1, shouts2) - self.network.disable_caching() - self.assertFalse(self.network.is_caching_enabled()) - def test_album_mbid(self): # Arrange mbid = "a6a265bf-9f81-4055-8224-f7ac0aa6b937" From 454c519fd9b1494c51606f826057b72dd8b8de70 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 18:29:12 +0300 Subject: [PATCH 07/13] Remove dead Last.fm group methods --- pylast/__init__.py | 86 ++------------------------------------------ tests/test_pylast.py | 23 ------------ 2 files changed, 3 insertions(+), 106 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index f0436d1..fe9b0bf 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -241,13 +241,6 @@ class _Network(object): return Metro(metro_name, country_name, self) - def get_group(self, name): - """ - Returns a Group object - """ - - return Group(name, self) - def get_user(self, username): """ Returns a user object @@ -766,7 +759,6 @@ class LastFMNetwork(_Network): "country": "place/%(country_name)s", "tag": "tag/%(name)s", "track": "music/%(artist)s/_/%(title)s", - "group": "group/%(name)s", "user": "user/%(name)s", } ) @@ -830,7 +822,6 @@ class LibreFMNetwork(_Network): "country": "place/%(country_name)s", "tag": "tag/%(name)s", "track": "music/%(artist)s/_/%(title)s", - "group": "group/%(name)s", "user": "user/%(name)s", } ) @@ -1288,7 +1279,7 @@ class _Chartable(object): """ Returns the weekly album charts for the week starting from the from_date value to the to_date value. - Only for Group or User. + Only for User. """ return self.get_weekly_charts("album", from_date, to_date) @@ -1296,7 +1287,7 @@ class _Chartable(object): """ Returns the weekly artist charts for the week starting from the from_date value to the to_date value. - Only for Group, Tag or User. + Only for Tag or User. """ return self.get_weekly_charts("artist", from_date, to_date) @@ -1304,7 +1295,7 @@ class _Chartable(object): """ Returns the weekly track charts for the week starting from the from_date value to the to_date value. - Only for Group or User. + Only for User. """ return self.get_weekly_charts("track", from_date, to_date) @@ -2580,77 +2571,6 @@ class Track(_Opus): 'artist': artist, 'title': title} -class Group(_BaseObject, _Chartable): - """A Last.fm group.""" - - name = None - - __hash__ = _BaseObject.__hash__ - - def __init__(self, name, network): - _BaseObject.__init__(self, network, 'group') - _Chartable.__init__(self, 'group') - - self.name = name - - def __repr__(self): - return "pylast.Group(%s, %s)" % (repr(self.name), repr(self.network)) - - @_string_output - def __str__(self): - return self.get_name() - - def __eq__(self, other): - return self.get_name().lower() == other.get_name().lower() - - def __ne__(self, other): - return self.get_name() != other.get_name() - - def _get_params(self): - return {self.ws_prefix: self.get_name()} - - def get_name(self): - """Returns the group name. """ - return self.name - - def get_url(self, domain_name=DOMAIN_ENGLISH): - """Returns the url of the group page on the network. - * domain_name: The network's language domain. Possible values: - o DOMAIN_ENGLISH - o DOMAIN_GERMAN - o DOMAIN_SPANISH - o DOMAIN_FRENCH - o DOMAIN_ITALIAN - o DOMAIN_POLISH - o DOMAIN_PORTUGUESE - o DOMAIN_SWEDISH - o DOMAIN_TURKISH - o DOMAIN_RUSSIAN - o DOMAIN_JAPANESE - o DOMAIN_CHINESE - """ - - name = _url_safe(self.get_name()) - - return self.network._get_url(domain_name, "group") % {'name': name} - - def get_members(self, limit=50, cacheable=False): - """ - Returns a sequence of User objects - if limit==None it will return all - """ - - nodes = _collect_nodes( - limit, self, self.ws_prefix + ".getMembers", cacheable) - - users = [] - - for node in nodes: - users.append(User(_extract(node, "name"), self.network)) - - return users - - class User(_BaseObject, _Chartable): """A Last.fm user.""" diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 717c1be..0146174 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -287,13 +287,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(event) - def test_group_is_hashable(self): - # Arrange - group = self.network.get_group("Audioscrobbler Beta") - - # Act/Assert - self.helper_is_thing_hashable(group) - def test_library_is_hashable(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -639,13 +632,6 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_validate_results(result1, result2, result3) - def test_cacheable_group_get_members(self): - # Arrange - group = self.network.get_group("Audioscrobbler Beta") - - # Act/Assert - self.helper_validate_cacheable(group, "get_members") - def test_cacheable_library(self): # Arrange library = pylast.Library(self.username, self.network) @@ -987,15 +973,6 @@ class TestPyLast(unittest.TestCase): self.helper_assert_chart(album_chart, pylast.Album) self.helper_assert_chart(track_chart, pylast.Track) - def test_group_charts(self): - # Arrange - group = self.network.get_group("mnml") - dates = group.get_weekly_chart_dates() - self.helper_dates_valid(dates) - - # Act/Assert - self.helper_get_assert_charts(group, dates[-2]) - def test_tag_charts(self): # Arrange tag = self.network.get_tag("rock") From 61216f73c0b95dc4ac7760db8ab75a01f62b7108 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 25 Sep 2017 18:36:02 +0300 Subject: [PATCH 08/13] Remove dead Last.fm artist/user methods --- tests/test_pylast.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 0146174..7cfbb6c 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -637,9 +637,7 @@ class TestPyLast(unittest.TestCase): library = pylast.Library(self.username, self.network) # Act/Assert - self.helper_validate_cacheable(library, "get_albums") self.helper_validate_cacheable(library, "get_artists") - self.helper_validate_cacheable(library, "get_tracks") def test_cacheable_user_artist_tracks(self): # Arrange @@ -660,11 +658,7 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_validate_cacheable(lastfm_user, "get_friends") self.helper_validate_cacheable(lastfm_user, "get_loved_tracks") - self.helper_validate_cacheable(lastfm_user, "get_neighbours") - self.helper_validate_cacheable(lastfm_user, "get_past_events") self.helper_validate_cacheable(lastfm_user, "get_recent_tracks") - self.helper_validate_cacheable(lastfm_user, "get_recommended_artists") - self.helper_validate_cacheable(lastfm_user, "get_recommended_events") def test_geo_get_events_in_location(self): # Arrange From 230439f52f1d539144252d1d81848880405c17e8 Mon Sep 17 00:00:00 2001 From: hugovk Date: Tue, 26 Sep 2017 08:38:32 +0300 Subject: [PATCH 09/13] Remove dead Last.fm event/venu methods --- pylast/__init__.py | 367 +------------------------------------------ tests/test_pylast.py | 194 +---------------------- 2 files changed, 3 insertions(+), 558 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index fe9b0bf..f31be7b 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -67,10 +67,6 @@ STATUS_INVALID_SIGNATURE = 13 STATUS_TOKEN_UNAUTHORIZED = 14 STATUS_TOKEN_EXPIRED = 15 -EVENT_ATTENDING = '0' -EVENT_MAYBE_ATTENDING = '1' -EVENT_NOT_ATTENDING = '2' - PERIOD_OVERALL = 'overall' PERIOD_7DAYS = '7day' PERIOD_1MONTH = '1month' @@ -336,50 +332,6 @@ class _Network(object): return seq - def get_geo_events( - self, longitude=None, latitude=None, location=None, distance=None, - tag=None, festivalsonly=None, limit=None, cacheable=True): - """ - Returns all events in a specific location by country or city name. - Parameters: - longitude (Optional) : Specifies a longitude value to retrieve events - for (service returns nearby events by default) - latitude (Optional) : Specifies a latitude value to retrieve events for - (service returns nearby events by default) - location (Optional) : Specifies a location to retrieve events for - (service returns nearby events by default) - distance (Optional) : Find events within a specified radius - (in kilometres) - tag (Optional) : Specifies a tag to filter by. - festivalsonly[0|1] (Optional) : Whether only festivals should be - returned, or all events. - limit (Optional) : The number of results to fetch per page. - Defaults to 10. - """ - - params = {} - - if longitude: - params["long"] = longitude - if latitude: - params["lat"] = latitude - if location: - params["location"] = location - if limit: - params["limit"] = limit - if distance: - params["distance"] = distance - if tag: - params["tag"] = tag - if festivalsonly: - params["festivalsonly"] = 1 - elif not festivalsonly: - params["festivalsonly"] = 0 - - doc = _Request(self, "geo.getEvents", params).execute(cacheable) - - return _extract_events_from_doc(doc, self) - def get_metro_weekly_chart_dates(self, cacheable=True): """ Returns a list of From and To tuples for the available metro charts. @@ -554,14 +506,6 @@ class _Network(object): return TrackSearch(artist_name, track_name, self) - def search_for_venue(self, venue_name, country_name): - """Searches of a venue by its name and its country. Set country_name to - an empty string if not available. - Returns a VenueSearch object. - Use get_next_page() to retrieve sequences of results.""" - - return VenueSearch(venue_name, country_name, self) - def get_track_by_mbid(self, mbid): """Looks up a track by its MusicBrainz ID""" @@ -755,7 +699,6 @@ class LastFMNetwork(_Network): urls={ "album": "music/%(artist)s/%(album)s", "artist": "music/%(artist)s", - "event": "event/%(id)s", "country": "place/%(country_name)s", "tag": "tag/%(name)s", "track": "music/%(artist)s/_/%(title)s", @@ -818,7 +761,6 @@ class LibreFMNetwork(_Network): urls={ "album": "artist/%(artist)s/album/%(album)s", "artist": "artist/%(artist)s", - "event": "event/%(id)s", "country": "place/%(country_name)s", "tag": "tag/%(name)s", "track": "music/%(artist)s/_/%(title)s", @@ -1195,7 +1137,7 @@ class _BaseObject(object): * users [User|str,]: A list that can contain usernames, emails, User objects, or all of them. * message str: A message to include in the recommendation message. - Only for Artist/Event/Track. + Only for Artist/Track. """ # Last.fm currently accepts a max of 10 recipient at a time @@ -1895,168 +1837,6 @@ class Artist(_BaseObject, _Taggable): return names -class Event(_BaseObject): - """An event.""" - - id = None - - __hash__ = _BaseObject.__hash__ - - def __init__(self, event_id, network): - _BaseObject.__init__(self, network, 'event') - - self.id = event_id - - def __repr__(self): - return "pylast.Event(%s, %s)" % (repr(self.id), repr(self.network)) - - @_string_output - def __str__(self): - return "Event #" + str(self.get_id()) - - def __eq__(self, other): - if type(self) is type(other): - return self.get_id() == other.get_id() - else: - return False - - def __ne__(self, other): - return not self.__eq__(other) - - def _get_params(self): - return {'event': self.get_id()} - - def attend(self, attending_status): - """Sets the attending status. - * attending_status: The attending status. Possible values: - o EVENT_ATTENDING - o EVENT_MAYBE_ATTENDING - o EVENT_NOT_ATTENDING - """ - - params = self._get_params() - params['status'] = attending_status - - self._request('event.attend', False, params) - - def get_attendees(self): - """ - Get a list of attendees for an event - """ - - doc = self._request("event.getAttendees", False) - - users = [] - for name in _extract_all(doc, "name"): - users.append(User(name, self.network)) - - return users - - def get_id(self): - """Returns the id of the event on the network. """ - - return self.id - - def get_title(self): - """Returns the title of the event. """ - - doc = self._request("event.getInfo", True) - - return _extract(doc, "title") - - def get_headliner(self): - """Returns the headliner of the event. """ - - doc = self._request("event.getInfo", True) - - return Artist(_extract(doc, "headliner"), self.network) - - def get_artists(self): - """Returns a list of the participating Artists. """ - - doc = self._request("event.getInfo", True) - names = _extract_all(doc, "artist") - - artists = [] - for name in names: - artists.append(Artist(name, self.network)) - - return artists - - def get_venue(self): - """Returns the venue where the event is held.""" - - doc = self._request("event.getInfo", True) - - v = doc.getElementsByTagName("venue")[0] - venue_id = _number(_extract(v, "id")) - - return Venue(venue_id, self.network, venue_element=v) - - def get_start_date(self): - """Returns the date when the event starts.""" - - doc = self._request("event.getInfo", True) - - return _extract(doc, "startDate") - - def get_description(self): - """Returns the description of the event. """ - - doc = self._request("event.getInfo", True) - - return _extract(doc, "description") - - def get_cover_image(self, size=COVER_MEGA): - """ - Returns a uri to the cover image - size can be one of: - COVER_MEGA - COVER_EXTRA_LARGE - COVER_LARGE - COVER_MEDIUM - COVER_SMALL - """ - - doc = self._request("event.getInfo", True) - - return _extract_all(doc, "image")[size] - - def get_attendance_count(self): - """Returns the number of attending people. """ - - doc = self._request("event.getInfo", True) - - return _number(_extract(doc, "attendance")) - - def get_review_count(self): - """Returns the number of available reviews for this event. """ - - doc = self._request("event.getInfo", True) - - return _number(_extract(doc, "reviews")) - - def get_url(self, domain_name=DOMAIN_ENGLISH): - """Returns the url of the event page on the network. - * domain_name: The network's language domain. Possible values: - o DOMAIN_ENGLISH - o DOMAIN_GERMAN - o DOMAIN_SPANISH - o DOMAIN_FRENCH - o DOMAIN_ITALIAN - o DOMAIN_POLISH - o DOMAIN_PORTUGUESE - o DOMAIN_SWEDISH - o DOMAIN_TURKISH - o DOMAIN_RUSSIAN - o DOMAIN_JAPANESE - o DOMAIN_CHINESE - """ - - return self.network._get_url( - domain_name, "event") % {'id': self.get_id()} - - class Country(_BaseObject): """A country at Last.fm.""" @@ -2110,7 +1890,7 @@ class Country(_BaseObject): "getTopTracks", "track", Track, params, cacheable) def get_url(self, domain_name=DOMAIN_ENGLISH): - """Returns the url of the event page on the network. + """Returns the url of the country page on the network. * domain_name: The network's language domain. Possible values: o DOMAIN_ENGLISH o DOMAIN_GERMAN @@ -2615,13 +2395,6 @@ class User(_BaseObject, _Chartable): return self.name - def get_upcoming_events(self): - """Returns all the upcoming events for this user.""" - - doc = self._request(self.ws_prefix + '.getEvents', True) - - return _extract_events_from_doc(doc, self.network) - def get_artist_tracks(self, artist, cacheable=False): """ Get a list of tracks by a given artist scrobbled by this user, @@ -2716,22 +2489,6 @@ class User(_BaseObject, _Chartable): return seq - def get_past_events(self, limit=50, cacheable=False): - """ - Returns a sequence of Event objects - if limit==None it will return all - """ - - seq = [] - for node in _collect_nodes( - limit, - self, - self.ws_prefix + ".getPastEvents", - cacheable): - seq.append(Event(_extract(node, "id"), self.network)) - - return seq - def get_now_playing(self): """ Returns the currently playing track, or None if nothing is playing. @@ -3086,19 +2843,6 @@ class AuthenticatedUser(User): self.name = _extract(doc, "name") return self.name - def get_recommended_events(self, limit=50, cacheable=False): - """ - Returns a sequence of Event objects - if limit==None it will return all - """ - - seq = [] - for node in _collect_nodes( - limit, self, "user.getRecommendedEvents", cacheable): - seq.append(Event(_extract(node, "id"), self.network)) - - return seq - def get_recommended_artists(self, limit=50, cacheable=False): """ Returns a sequence of Artist objects @@ -3247,106 +2991,6 @@ class TrackSearch(_Search): return seq -class VenueSearch(_Search): - """ - Search for a venue by its name. If you don't want to narrow the results - down by specifying a country, set it to empty string. - """ - - def __init__(self, venue_name, country_name, network): - - _Search.__init__( - self, - "venue", - {"venue": venue_name, "country": country_name}, - network) - - def get_next_page(self): - """Returns the next page of results as a sequence of Track objects.""" - - master_node = self._retrieve_next_page() - - seq = [] - for node in master_node.getElementsByTagName("venue"): - seq.append(Venue(_extract(node, "id"), self.network)) - - return seq - - -class Venue(_BaseObject): - """A venue where events are held.""" - - # TODO: waiting for a venue.getInfo web service to use. - # TODO: As an intermediate use case, can pass the venue DOM element when - # using Event.get_venue() to populate the venue info, if the venue.getInfo - # API call becomes available this workaround should be removed - - id = None - info = None - name = None - location = None - url = None - - __hash__ = _BaseObject.__hash__ - - def __init__(self, netword_id, network, venue_element=None): - _BaseObject.__init__(self, network, "venue") - - self.id = _number(netword_id) - if venue_element is not None: - self.info = _extract_element_tree(venue_element) - self.name = self.info.get('name') - self.url = self.info.get('url') - self.location = self.info.get('location') - - def __repr__(self): - return "pylast.Venue(%s, %s)" % (repr(self.id), repr(self.network)) - - @_string_output - def __str__(self): - return "Venue #" + str(self.id) - - def __eq__(self, other): - return self.get_id() == other.get_id() - - def _get_params(self): - return {self.ws_prefix: self.get_id()} - - def get_id(self): - """Returns the id of the venue.""" - - return self.id - - def get_name(self): - """Returns the name of the venue.""" - - return self.name - - def get_url(self): - """Returns the URL of the venue page.""" - - return self.url - - def get_location(self): - """Returns the location of the venue (dictionary).""" - - return self.location - - def get_upcoming_events(self): - """Returns the upcoming events in this venue.""" - - doc = self._request(self.ws_prefix + ".getEvents", True) - - return _extract_events_from_doc(doc, self.network) - - def get_past_events(self): - """Returns the past events held in this venue.""" - - doc = self._request(self.ws_prefix + ".getEvents", True) - - return _extract_events_from_doc(doc, self.network) - - def md5(text): """Returns the md5 hash of a string.""" @@ -3534,13 +3178,6 @@ def _extract_tracks(doc, network): return seq -def _extract_events_from_doc(doc, network): - events = [] - for node in doc.getElementsByTagName("event"): - events.append(Event(_extract(node, "id"), network)) - return events - - def _url_safe(text): """Does all kinds of tricks on a text to make it safe to use in a url.""" diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 7cfbb6c..21671ff 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -73,18 +73,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(str(last_scrobble.track.title), str(title)) self.assertEqual(str(last_scrobble.timestamp), str(timestamp)) - def test_get_venue(self): - # Arrange - venue_name = "Last.fm Office" - country_name = "United Kingdom" - - # Act - venue_search = self.network.search_for_venue(venue_name, country_name) - venue = venue_search.get_next_page()[0] - - # Assert - self.assertEqual(str(venue.id), "8778225") - def test_get_user_registration(self): # Arrange username = "RJ" @@ -279,14 +267,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(metro) - def test_event_is_hashable(self): - # Arrange - user = self.network.get_user("RJ") - event = user.get_past_events(limit=1)[0] - - # Act/Assert - self.helper_is_thing_hashable(event) - def test_library_is_hashable(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -317,14 +297,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(user) - def test_venue_is_hashable(self): - # Arrange - venue_id = "8778225" # Last.fm office - venue = pylast.Venue(venue_id, self.network) - - # Act/Assert - self.helper_is_thing_hashable(venue) - def test_invalid_xml(self): # Arrange # Currently causes PCDATA invalid Char value 25 @@ -436,67 +408,6 @@ class TestPyLast(unittest.TestCase): # # Assert # self.assertGreaterEqual(len(tracks), 0) - def helper_past_events_have_valid_ids(self, thing): - # Act - events = thing.get_past_events() - - # Assert - self.helper_assert_events_have_valid_ids(events) - - def helper_upcoming_events_have_valid_ids(self, thing): - # Act - events = thing.get_upcoming_events() - - # Assert - self.helper_assert_events_have_valid_ids(events) - - def helper_assert_events_have_valid_ids(self, events): - # Assert - # If fails, add past/future event for user/Test Artist: - self.assertGreaterEqual(len(events), 1) - for event in events[:2]: # checking first two should be enough - self.assertIsInstance(event.get_headliner(), pylast.Artist) - - def test_user_past_events_returns_valid_ids(self): - # Arrange - lastfm_user = self.network.get_user(self.username) - - # Act/Assert - self.helper_past_events_have_valid_ids(lastfm_user) - - def test_user_recommended_events_returns_valid_ids(self): - # Arrange - lastfm_user = self.network.get_user(self.username) - - # Act - events = lastfm_user.get_upcoming_events() - - # Assert - self.helper_assert_events_have_valid_ids(events) - - def test_user_upcoming_events_returns_valid_ids(self): - # Arrange - lastfm_user = self.network.get_user(self.username) - - # Act/Assert - self.helper_upcoming_events_have_valid_ids(lastfm_user) - - def test_venue_past_events_returns_valid_ids(self): - # Arrange - venue_id = "8778225" # Last.fm office - venue = pylast.Venue(venue_id, self.network) - - # Act/Assert - self.helper_past_events_have_valid_ids(venue) - - def test_venue_upcoming_events_returns_valid_ids(self): - # Arrange - venue_id = "8778225" # Last.fm office - venue = pylast.Venue(venue_id, self.network) - - # Act/Assert - self.helper_upcoming_events_have_valid_ids(venue) - def test_pickle(self): # Arrange import pickle @@ -660,43 +571,6 @@ class TestPyLast(unittest.TestCase): self.helper_validate_cacheable(lastfm_user, "get_loved_tracks") self.helper_validate_cacheable(lastfm_user, "get_recent_tracks") - def test_geo_get_events_in_location(self): - # Arrange - # Act - events = self.network.get_geo_events( - location="London", tag="blues", limit=1) - - # Assert - self.assertEqual(len(events), 1) - event = events[0] - self.assertIsInstance(event, pylast.Event) - self.assertIn(event.get_venue().location['city'], - ["London", "Camden"]) - - def test_geo_get_events_in_latlong(self): - # Arrange - # Act - events = self.network.get_geo_events( - latitude=53.466667, longitude=-2.233333, distance=5, limit=1) - - # Assert - self.assertEqual(len(events), 1) - event = events[0] - self.assertIsInstance(event, pylast.Event) - self.assertEqual(event.get_venue().location['city'], "Manchester") - - def test_geo_get_events_festival(self): - # Arrange - # Act - events = self.network.get_geo_events( - location="Reading", festivalsonly=True, limit=1) - - # Assert - self.assertEqual(len(events), 1) - event = events[0] - self.assertIsInstance(event, pylast.Event) - self.assertEqual(event.get_venue().location['city'], "Reading") - def helper_dates_valid(self, dates): # Assert self.assertGreaterEqual(len(dates), 1) @@ -992,17 +866,15 @@ class TestPyLast(unittest.TestCase): # spam_message = "Dig the krazee sound!" # artist = self.network.get_top_artists(limit=1)[0].item # track = artist.get_top_tracks(limit=1)[0].item - # event = artist.get_upcoming_events()[0] # # Act # artist.share(users_to_spam, spam_message) # track.share(users_to_spam, spam_message) - # event.share(users_to_spam, spam_message) # Assert # Check inbox for spam! - # album/artist/event/track/user + # album/artist/track/user def test_album_data(self): # Arrange @@ -1217,18 +1089,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(count, int) self.assertGreater(count, 0) - def test_event_attendees(self): - # Arrange - user = self.network.get_user("RJ") - event = user.get_past_events(limit=1)[0] - - # Act - users = event.get_attendees() - - # Assert - self.assertIsInstance(users, list) - self.assertIsInstance(users[0], pylast.User) - def test_tag_artist(self): # Arrange artist = self.network.get_artist("Test Artist") @@ -1443,40 +1303,6 @@ class TestPyLast(unittest.TestCase): self.assertEqual(mbid, "a74b1b7f-71a5-4011-9441-d0b5e4122711") self.assertIsInstance(streamable, bool) - def test_events(self): - # Arrange - event_id_1 = 3162700 # Glasto 2013 - event_id_2 = 3478520 # Glasto 2014 - event1 = pylast.Event(event_id_1, self.network) - event2 = pylast.Event(event_id_2, self.network) - - # Act - text = str(event1) - rep = repr(event1) - title = event1.get_title() - artists = event1.get_artists() - start = event1.get_start_date() - description = event1.get_description() - review_count = event1.get_review_count() - attendance_count = event1.get_attendance_count() - - # Assert - self.assertIn("3162700", rep) - self.assertIn("pylast.Event", rep) - self.assertEqual(text, "Event #3162700") - self.assertTrue(event1 != event2) - self.assertIn("Glastonbury", title) - found = False - for artist in artists: - if artist.name == "The Rolling Stones": - found = True - break - self.assertTrue(found) - self.assertIn("Wed, 26 Jun 2013", start) - self.assertIn("astonishing bundle", description) - self.assertGreater(review_count, 0) - self.assertGreater(attendance_count, 100) - def test_countries(self): # Arrange country1 = pylast.Country("Italy", self.network) @@ -1543,24 +1369,6 @@ class TestPyLast(unittest.TestCase): # Act / Assert self.assertTrue(album1 != album2) - def test_event_eq_none_is_false(self): - # Arrange - event1 = None - event_id = 3478520 # Glasto 2014 - event2 = pylast.Event(event_id, self.network) - - # Act / Assert - self.assertFalse(event1 == event2) - - def test_event_ne_none_is_true(self): - # Arrange - event1 = None - event_id = 3478520 # Glasto 2014 - event2 = pylast.Event(event_id, self.network) - - # Act / Assert - self.assertTrue(event1 != event2) - def test_band_members(self): # Arrange artist = pylast.Artist("The Beatles", self.network) From 27ba0dd6b3dbe79a2b77c8e4a0302c1767782100 Mon Sep 17 00:00:00 2001 From: hugovk Date: Tue, 26 Sep 2017 08:58:37 +0300 Subject: [PATCH 10/13] Remove dead Last.fm metro methods --- pylast/__init__.py | 210 ------------------------------------------- tests/test_pylast.py | 82 ----------------- 2 files changed, 292 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index f31be7b..67e1533 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -230,13 +230,6 @@ class _Network(object): return Country(country_name, self) - def get_metro(self, metro_name, country_name): - """ - Returns a metro object - """ - - return Metro(metro_name, country_name, self) - def get_user(self, username): """ Returns a user object @@ -332,46 +325,6 @@ class _Network(object): return seq - def get_metro_weekly_chart_dates(self, cacheable=True): - """ - Returns a list of From and To tuples for the available metro charts. - """ - - doc = _Request(self, "geo.getMetroWeeklyChartlist").execute(cacheable) - - seq = [] - for node in doc.getElementsByTagName("chart"): - seq.append((node.getAttribute("from"), node.getAttribute("to"))) - - return seq - - def get_metros(self, country=None, cacheable=True): - """ - Get a list of valid countries and metros for use in the other - webservices. - Parameters: - country (Optional) : Optionally restrict the results to those Metros - from a particular country, as defined by the ISO 3166-1 country - names standard. - """ - params = {} - - if country: - params["country"] = country - - doc = _Request(self, "geo.getMetros", params).execute(cacheable) - - metros = doc.getElementsByTagName("metro") - seq = [] - - for metro in metros: - name = _extract(metro, "name") - country = _extract(metro, "country") - - seq.append(Metro(name, country, self)) - - return seq - def get_geo_top_artists(self, country, limit=None, cacheable=True): """Get the most popular artists on Last.fm by country. Parameters: @@ -1912,169 +1865,6 @@ class Country(_BaseObject): domain_name, "country") % {'country_name': country_name} -class Metro(_BaseObject): - """A metro at Last.fm.""" - - name = None - country = None - - __hash__ = _BaseObject.__hash__ - - def __init__(self, name, country, network): - _BaseObject.__init__(self, network, None) - - self.name = name - self.country = country - - def __repr__(self): - return "pylast.Metro(%s, %s, %s)" % ( - repr(self.name), repr(self.country), repr(self.network)) - - @_string_output - def __str__(self): - return self.get_name() + ", " + self.get_country() - - def __eq__(self, other): - return (self.get_name().lower() == other.get_name().lower() and - self.get_country().lower() == other.get_country().lower()) - - def __ne__(self, other): - return (self.get_name() != other.get_name() or - self.get_country().lower() != other.get_country().lower()) - - def _get_params(self): - return {'metro': self.get_name(), 'country': self.get_country()} - - def get_name(self): - """Returns the metro name.""" - - return self.name - - def get_country(self): - """Returns the metro country.""" - - return self.country - - def _get_chart( - self, method, tag="artist", limit=None, from_date=None, - to_date=None, cacheable=True): - """Internal helper for getting geo charts.""" - params = self._get_params() - if limit: - params["limit"] = limit - if from_date and to_date: - params["from"] = from_date - params["to"] = to_date - - doc = self._request(method, cacheable, params) - - seq = [] - for node in doc.getElementsByTagName(tag): - if tag == "artist": - item = Artist(_extract(node, "name"), self.network) - elif tag == "track": - title = _extract(node, "name") - artist = _extract_element_tree(node).get('artist')['name'] - item = Track(artist, title, self.network) - else: - return None - weight = _number(_extract(node, "listeners")) - seq.append(TopItem(item, weight)) - - return seq - - def get_artist_chart( - self, tag="artist", limit=None, from_date=None, to_date=None, - cacheable=True): - """Get a chart of artists for a metro. - Parameters: - from_date (Optional) : Beginning timestamp of the weekly range - requested - to_date (Optional) : Ending timestamp of the weekly range requested - limit (Optional) : The number of results to fetch per page. - Defaults to 50. - """ - return self._get_chart( - "geo.getMetroArtistChart", tag=tag, limit=limit, - from_date=from_date, to_date=to_date, cacheable=cacheable) - - def get_hype_artist_chart( - self, tag="artist", limit=None, from_date=None, to_date=None, - cacheable=True): - """Get a chart of hyped (up and coming) artists for a metro. - Parameters: - from_date (Optional) : Beginning timestamp of the weekly range - requested - to_date (Optional) : Ending timestamp of the weekly range requested - limit (Optional) : The number of results to fetch per page. - Defaults to 50. - """ - return self._get_chart( - "geo.getMetroHypeArtistChart", tag=tag, limit=limit, - from_date=from_date, to_date=to_date, cacheable=cacheable) - - def get_unique_artist_chart( - self, tag="artist", limit=None, from_date=None, to_date=None, - cacheable=True): - """Get a chart of the artists which make that metro unique. - Parameters: - from_date (Optional) : Beginning timestamp of the weekly range - requested - to_date (Optional) : Ending timestamp of the weekly range requested - limit (Optional) : The number of results to fetch per page. - Defaults to 50. - """ - return self._get_chart( - "geo.getMetroUniqueArtistChart", tag=tag, limit=limit, - from_date=from_date, to_date=to_date, cacheable=cacheable) - - def get_track_chart( - self, tag="track", limit=None, from_date=None, to_date=None, - cacheable=True): - """Get a chart of tracks for a metro. - Parameters: - from_date (Optional) : Beginning timestamp of the weekly range - requested - to_date (Optional) : Ending timestamp of the weekly range requested - limit (Optional) : The number of results to fetch per page. - Defaults to 50. - """ - return self._get_chart( - "geo.getMetroTrackChart", tag=tag, limit=limit, - from_date=from_date, to_date=to_date, cacheable=cacheable) - - def get_hype_track_chart( - self, tag="track", limit=None, from_date=None, to_date=None, - cacheable=True): - """Get a chart of tracks for a metro. - Parameters: - from_date (Optional) : Beginning timestamp of the weekly range - requested - to_date (Optional) : Ending timestamp of the weekly range requested - limit (Optional) : The number of results to fetch per page. - Defaults to 50. - """ - return self._get_chart( - "geo.getMetroHypeTrackChart", tag=tag, - limit=limit, from_date=from_date, to_date=to_date, - cacheable=cacheable) - - def get_unique_track_chart( - self, tag="track", limit=None, from_date=None, to_date=None, - cacheable=True): - """Get a chart of tracks for a metro. - Parameters: - from_date (Optional) : Beginning timestamp of the weekly range - requested - to_date (Optional) : Ending timestamp of the weekly range requested - limit (Optional) : The number of results to fetch per page. - Defaults to 50. - """ - return self._get_chart( - "geo.getMetroUniqueTrackChart", tag=tag, limit=limit, - from_date=from_date, to_date=to_date, cacheable=cacheable) - - class Library(_BaseObject): """A user's Last.fm library.""" diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 21671ff..0281631 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -260,13 +260,6 @@ class TestPyLast(unittest.TestCase): # Act/Assert self.helper_is_thing_hashable(country) - def test_metro_is_hashable(self): - # Arrange - metro = self.network.get_metro("Helsinki", "Finland") - - # Act/Assert - self.helper_is_thing_hashable(metro) - def test_library_is_hashable(self): # Arrange library = pylast.Library(user=self.username, network=self.network) @@ -578,67 +571,6 @@ class TestPyLast(unittest.TestCase): (start, end) = dates[0] self.assertLess(start, end) - def test_get_metro_weekly_chart_dates(self): - # Arrange - # Act - dates = self.network.get_metro_weekly_chart_dates() - - # Assert - self.helper_dates_valid(dates) - - def helper_geo_chart(self, function_name, expected_type=pylast.Artist): - # Arrange - metro = self.network.get_metro("Madrid", "Spain") - dates = self.network.get_metro_weekly_chart_dates() - (from_date, to_date) = dates[0] - - # get metro.function_name() - func = getattr(metro, function_name, None) - - # Act - chart = func(from_date=from_date, to_date=to_date, limit=1) - - # Assert - self.assertEqual(len(chart), 1) - self.assertIsInstance(chart[0], pylast.TopItem) - self.assertIsInstance(chart[0].item, expected_type) - - def test_get_metro_artist_chart(self): - # Arrange/Act/Assert - self.helper_geo_chart("get_artist_chart") - - def test_get_metro_hype_artist_chart(self): - # Arrange/Act/Assert - self.helper_geo_chart("get_hype_artist_chart") - - def test_get_metro_unique_artist_chart(self): - # Arrange/Act/Assert - self.helper_geo_chart("get_unique_artist_chart") - - def test_get_metro_track_chart(self): - # Arrange/Act/Assert - self.helper_geo_chart("get_track_chart", expected_type=pylast.Track) - - def test_get_metro_hype_track_chart(self): - # Arrange/Act/Assert - self.helper_geo_chart( - "get_hype_track_chart", expected_type=pylast.Track) - - def test_get_metro_unique_track_chart(self): - # Arrange/Act/Assert - self.helper_geo_chart( - "get_unique_track_chart", expected_type=pylast.Track) - - def test_geo_get_metros(self): - # Arrange - # Act - metros = self.network.get_metros(country="Poland") - - # Assert - self.assertGreaterEqual(len(metros), 1) - self.assertIsInstance(metros[0], pylast.Metro) - self.assertEqual(metros[0].get_country(), "Poland") - def test_geo_get_top_artists(self): # Arrange # Act @@ -661,20 +593,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(tracks[0], pylast.TopItem) self.assertIsInstance(tracks[0].item, pylast.Track) - def test_metro_class(self): - # Arrange - # Act - metro = self.network.get_metro("Bergen", "Norway") - - # Assert - self.assertEqual(metro.get_name(), "Bergen") - self.assertEqual(metro.get_country(), "Norway") - self.assertEqual(str(metro), "Bergen, Norway") - self.assertEqual(metro, pylast.Metro("Bergen", "Norway", self.network)) - self.assertNotEqual( - metro, - pylast.Metro("Wellington", "New Zealand", self.network)) - def helper_at_least_one_thing_in_top_list(self, things, expected_type): # Assert self.assertGreater(len(things), 1) From ec68660014d4ef9935f53a9b8331850d79b3e7bb Mon Sep 17 00:00:00 2001 From: hugovk Date: Tue, 26 Sep 2017 09:08:40 +0300 Subject: [PATCH 11/13] Remove dead Last.fm chart test --- tests/test_pylast.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 0281631..ff92784 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -759,15 +759,6 @@ class TestPyLast(unittest.TestCase): self.helper_assert_chart(album_chart, pylast.Album) self.helper_assert_chart(track_chart, pylast.Track) - def test_tag_charts(self): - # Arrange - tag = self.network.get_tag("rock") - dates = tag.get_weekly_chart_dates() - self.helper_dates_valid(dates) - - # Act/Assert - self.helper_get_assert_charts(tag, dates[-2]) - def test_user_charts(self): # Arrange lastfm_user = self.network.get_user("RJ") From 0eac6e9ae20127712cd0ba17080760c501b058ef Mon Sep 17 00:00:00 2001 From: hugovk Date: Tue, 26 Sep 2017 09:14:24 +0300 Subject: [PATCH 12/13] Remove redundant functions --- pylast/__init__.py | 31 ------------------------------- tests/test_pylast.py | 9 --------- 2 files changed, 40 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 67e1533..333768b 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -2873,37 +2873,6 @@ def _extract(node, name, index=0): return None -def _extract_element_tree(node): - """Extract an element tree into a multi-level dictionary - - NB: If any elements have text nodes as well as nested - elements this will ignore the text nodes""" - - def _recurse_build_tree(rootNode, targetDict): - """Recursively build a multi-level dict""" - - def _has_child_elements(rootNode): - """Check if an element has any nested (child) elements""" - - for node in rootNode.childNodes: - if node.nodeType == node.ELEMENT_NODE: - return True - return False - - for node in rootNode.childNodes: - if node.nodeType == node.ELEMENT_NODE: - if _has_child_elements(node): - targetDict[node.tagName] = {} - _recurse_build_tree(node, targetDict[node.tagName]) - else: - val = None if node.firstChild is None else \ - _unescape_htmlentity(node.firstChild.data.strip()) - targetDict[node.tagName] = val - return targetDict - - return _recurse_build_tree(node, {}) - - def _extract_all(node, name, limit_count=None): """Extracts all the values from the xml string. returning a list.""" diff --git a/tests/test_pylast.py b/tests/test_pylast.py index ff92784..91c51d6 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -624,15 +624,6 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(thing2.item, expected_type) self.assertNotEqual(thing1, thing2) - def helper_two_things_in_list(self, things, expected_type): - # Assert - self.assertEqual(len(things), 2) - self.assertIsInstance(things, list) - thing1 = things[0] - thing2 = things[1] - self.assertIsInstance(thing1, expected_type) - self.assertIsInstance(thing2, expected_type) - def test_user_get_top_tags_with_limit(self): # Arrange user = self.network.get_user("RJ") From a8522fded3c6a6904b9b9c93e6578c3751229a38 Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 26 Sep 2017 11:04:02 +0300 Subject: [PATCH 13/13] Bring back test_caching on another method --- tests/test_pylast.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 91c51d6..6b069b8 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -941,6 +941,21 @@ class TestPyLast(unittest.TestCase): # Assert self.assertIsInstance(library, pylast.Library) + def test_caching(self): + # Arrange + user = self.network.get_user("RJ") + + # Act + self.network.enable_caching() + tags1 = user.get_top_tags(limit=1, cacheable=True) + tags2 = user.get_top_tags(limit=1, cacheable=True) + + # Assert + self.assertTrue(self.network.is_caching_enabled()) + self.assertEqual(tags1, tags2) + self.network.disable_caching() + self.assertFalse(self.network.is_caching_enabled()) + def test_album_mbid(self): # Arrange mbid = "a6a265bf-9f81-4055-8224-f7ac0aa6b937"