From c8f8b60ec75a4cef479ad02806b743051c6ee935 Mon Sep 17 00:00:00 2001 From: brtkrbzhnv Date: Thu, 25 Jun 2015 21:43:12 +0200 Subject: [PATCH 1/9] Support for User.GetPersonalTags Added functions User.get_tagged_albums, ..._tracks and ..._artists to support User.GetPersonalTags. --- pylast/__init__.py | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 50d40c7..7f25b27 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -32,7 +32,7 @@ import warnings import re import six -__version__ = '1.2.1' +__version__ = '1.2.2' __author__ = 'Amr Hassan, hugovk' __copyright__ = "Copyright (C) 2008-2010 Amr Hassan, 2013-2015 hugovk" __license__ = "apache2" @@ -3505,6 +3505,43 @@ class User(_BaseObject, _Chartable): return doc.getElementsByTagName( "registered")[0].getAttribute("unixtime") + def get_tagged_albums(self, tag, limit=None, cacheable=True): + """Returns the albums tagged by a user.""" + + params = self._get_params() + params['tag'] = tag + params['taggingtype'] = 'album' + if limit: + params['limit'] = limit + + doc = self._request(self.ws_prefix + '.getpersonaltags', cacheable, params) + + return _extract_top_albums(doc, self.network) + + def get_tagged_artists(self, tag, limit=None): + """Returns the albums artists tagged by a user.""" + + params = self._get_params() + params['tag'] = tag + params['taggingtype'] = 'artist' + if limit: + params["limit"] = limit + + doc = self._request(self.ws_prefix + '.getpersonaltags', True, params) + + return _extract_top_artists(doc, self.network) + + def get_tagged_tracks(self, tag, limit=None, cacheable=True): + """Returns the tracks tagged by a user.""" + + params = self._get_params() + params['tag'] = tag + params['taggingtype'] = 'track' + if limit: + params['limit'] = limit + + return self._get_things("getpersonaltags", "track", Track, params, cacheable) + def get_top_albums( self, period=PERIOD_OVERALL, limit=None, cacheable=True): """Returns the top albums played by a user. From 658ed7a102667b07c9b49c254cddf7ad396c632d Mon Sep 17 00:00:00 2001 From: brtkrbzhnv Date: Thu, 25 Jun 2015 21:57:33 +0200 Subject: [PATCH 2/9] Cleanup of User.GetPersonalTags stuff --- pylast/__init__.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 7f25b27..efd8c24 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -3516,7 +3516,7 @@ class User(_BaseObject, _Chartable): doc = self._request(self.ws_prefix + '.getpersonaltags', cacheable, params) - return _extract_top_albums(doc, self.network) + return _extract_albums(doc, self.network) def get_tagged_artists(self, tag, limit=None): """Returns the albums artists tagged by a user.""" @@ -3529,7 +3529,7 @@ class User(_BaseObject, _Chartable): doc = self._request(self.ws_prefix + '.getpersonaltags', True, params) - return _extract_top_artists(doc, self.network) + return _extract_artists(doc, self.network) def get_tagged_tracks(self, tag, limit=None, cacheable=True): """Returns the tracks tagged by a user.""" @@ -3540,7 +3540,7 @@ class User(_BaseObject, _Chartable): if limit: params['limit'] = limit - return self._get_things("getpersonaltags", "track", Track, params, cacheable) + return _extract_tracks(doc, self.network) def get_top_albums( self, period=PERIOD_OVERALL, limit=None, cacheable=True): @@ -4123,7 +4123,30 @@ def _extract_top_albums(doc, network): return seq +def _extract_artists(doc, network): + seq = [] + for node in doc.getElementsByTagName("artist"): + seq.append(Artist(_extract(node, "name"), network)) + return seq + +def _extract_albums(doc, network): + seq = [] + for node in doc.getElementsByTagName("album"): + name = _extract(node, "name") + artist = _extract(node, "name", 1) + seq.append(Album(artist, name, network)) + return seq + +def _extract_tracks(doc, network): + seq = [] + for node in doc.getElementsByTagName("track"): + name = _extract(node, "name") + artist = _extract(node, "name", 1) + seq.append(Track(artist, name, network)) + return seq + + def _extract_events_from_doc(doc, network): events = [] for node in doc.getElementsByTagName("event"): From 4379e28c19d24b8d7beb1dd27755688224b8fe4f Mon Sep 17 00:00:00 2001 From: brtkrbzhnv Date: Fri, 26 Jun 2015 01:35:51 +0200 Subject: [PATCH 3/9] Fixed broken comment --- pylast/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index efd8c24..05b7de8 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -3730,7 +3730,7 @@ class AuthenticatedUser(User): def get_recommended_artists(self, limit=50, cacheable=False): """ - Returns a sequence of Event objects + Returns a sequence of Artist objects if limit==None it will return all """ From 8b321dfe748cb9e565d45f895fef28f4a92dab08 Mon Sep 17 00:00:00 2001 From: brtkrbzhnv Date: Sat, 27 Jun 2015 00:11:08 +0200 Subject: [PATCH 4/9] Added User.GetPersonalTags test cases --- tests/test_pylast.py | 46 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 1980e7a..664b118 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -1040,7 +1040,13 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(things, list) self.assertIsInstance(things[0], pylast.TopItem) self.assertIsInstance(things[0].item, expected_type) - + + def helper_only_one_thing_in_list(self, things, expected_type): + # Assert + self.assertEqual(len(things), 1) + self.assertIsInstance(things, list) + self.assertIsInstance(things[0], expected_type) + def helper_two_different_things_in_top_list(self, things, expected_type): # Assert self.assertEqual(len(things), 2) @@ -1399,7 +1405,45 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(albums, pylast.Album) + + def test_user_tagged_artists(self): + # Arrange + lastfm_user = self.network.get_user(self.username) + tags = ["artisttagola"] + artist = self.network.get_artist("Test Artist") + artist.add_tags(tags) + + # Act + artists = lastfm_user.get_tagged_artists('artisttagola', limit=1) + + # Assert + self.helper_only_one_thing_in_list(artists, pylast.Artist) + def test_user_tagged_albums(self): + # Arrange + lastfm_user = self.network.get_user(self.username) + tags = ["albumtagola"] + album = self.network.get_album("Test Artist", "Test Album") + album.add_tags(tags) + + # Act + albums = lastfm_user.get_tagged_albums('albumtagola', limit=1) + + # Assert + self.helper_only_one_thing_in_list(albums, pylast.Album) + + def test_user_tagged_tracks(self): + # Arrange + lastfm_user = self.network.get_user(self.username) + tags = ["tracktagola"] + track = self.network.get_track("Test Artist", "Test Title") + track.add_tags(tags) + # Act + tracks = lastfm_user.get_tagged_tracks('tracktagola', limit=1) + + # Assert + self.helper_only_one_thing_in_list(tracks, pylast.Track) + def test_caching(self): # Arrange user = self.network.get_user("RJ") From aa5f00bbd67821705089f16f18351f3f319c51d0 Mon Sep 17 00:00:00 2001 From: brtkrbzhnv Date: Sat, 27 Jun 2015 00:11:40 +0200 Subject: [PATCH 5/9] User.GetPersonalTags bug fix get_tagged_tracks crashed --- pylast/__init__.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 05b7de8..98888f0 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -3513,9 +3513,7 @@ class User(_BaseObject, _Chartable): params['taggingtype'] = 'album' if limit: params['limit'] = limit - doc = self._request(self.ws_prefix + '.getpersonaltags', cacheable, params) - return _extract_albums(doc, self.network) def get_tagged_artists(self, tag, limit=None): @@ -3526,9 +3524,7 @@ class User(_BaseObject, _Chartable): params['taggingtype'] = 'artist' if limit: params["limit"] = limit - doc = self._request(self.ws_prefix + '.getpersonaltags', True, params) - return _extract_artists(doc, self.network) def get_tagged_tracks(self, tag, limit=None, cacheable=True): @@ -3539,7 +3535,7 @@ class User(_BaseObject, _Chartable): params['taggingtype'] = 'track' if limit: params['limit'] = limit - + doc = self._request(self.ws_prefix + '.getpersonaltags', True, params) return _extract_tracks(doc, self.network) def get_top_albums( From 51b0f3b11a47e0363716501a691116a24833f358 Mon Sep 17 00:00:00 2001 From: brtkrbzhnv Date: Sun, 28 Jun 2015 11:17:13 +0200 Subject: [PATCH 6/9] Fixed broken comment --- pylast/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 98888f0..aea4880 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -3517,7 +3517,7 @@ class User(_BaseObject, _Chartable): return _extract_albums(doc, self.network) def get_tagged_artists(self, tag, limit=None): - """Returns the albums artists tagged by a user.""" + """Returns the artists tagged by a user.""" params = self._get_params() params['tag'] = tag @@ -4461,4 +4461,4 @@ class Scrobbler(object): if remainder: self.scrobble_many(remainder) -# End of file +# End of file \ No newline at end of file From 3240a54e323eaf82dd1b1b78b5b54c0ca860d94b Mon Sep 17 00:00:00 2001 From: hugovk Date: Fri, 24 Jul 2015 11:01:34 +0300 Subject: [PATCH 7/9] flake8 --- pylast/__init__.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index aea4880..253013b 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -3513,7 +3513,8 @@ class User(_BaseObject, _Chartable): params['taggingtype'] = 'album' if limit: params['limit'] = limit - doc = self._request(self.ws_prefix + '.getpersonaltags', cacheable, params) + doc = self._request(self.ws_prefix + '.getpersonaltags', cacheable, + params) return _extract_albums(doc, self.network) def get_tagged_artists(self, tag, limit=None): @@ -3526,7 +3527,7 @@ class User(_BaseObject, _Chartable): params["limit"] = limit doc = self._request(self.ws_prefix + '.getpersonaltags', True, params) return _extract_artists(doc, self.network) - + def get_tagged_tracks(self, tag, limit=None, cacheable=True): """Returns the tracks tagged by a user.""" @@ -4119,6 +4120,7 @@ def _extract_top_albums(doc, network): return seq + def _extract_artists(doc, network): seq = [] for node in doc.getElementsByTagName("artist"): @@ -4134,6 +4136,7 @@ def _extract_albums(doc, network): seq.append(Album(artist, name, network)) return seq + def _extract_tracks(doc, network): seq = [] for node in doc.getElementsByTagName("track"): @@ -4141,8 +4144,8 @@ def _extract_tracks(doc, network): artist = _extract(node, "name", 1) seq.append(Track(artist, name, network)) return seq - - + + def _extract_events_from_doc(doc, network): events = [] for node in doc.getElementsByTagName("event"): @@ -4461,4 +4464,4 @@ class Scrobbler(object): if remainder: self.scrobble_many(remainder) -# End of file \ No newline at end of file +# End of file From c421fd5cbd5e09d64dbbaaaba9c8863138171be5 Mon Sep 17 00:00:00 2001 From: hugovk Date: Fri, 24 Jul 2015 11:22:39 +0300 Subject: [PATCH 8/9] flake8 --- tests/test_pylast.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 664b118..7deb4db 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -1040,13 +1040,13 @@ class TestPyLast(unittest.TestCase): self.assertIsInstance(things, list) self.assertIsInstance(things[0], pylast.TopItem) self.assertIsInstance(things[0].item, expected_type) - + def helper_only_one_thing_in_list(self, things, expected_type): # Assert self.assertEqual(len(things), 1) self.assertIsInstance(things, list) self.assertIsInstance(things[0], expected_type) - + def helper_two_different_things_in_top_list(self, things, expected_type): # Assert self.assertEqual(len(things), 2) @@ -1405,17 +1405,17 @@ class TestPyLast(unittest.TestCase): # Assert self.helper_only_one_thing_in_top_list(albums, pylast.Album) - + def test_user_tagged_artists(self): # Arrange lastfm_user = self.network.get_user(self.username) tags = ["artisttagola"] artist = self.network.get_artist("Test Artist") artist.add_tags(tags) - + # Act artists = lastfm_user.get_tagged_artists('artisttagola', limit=1) - + # Assert self.helper_only_one_thing_in_list(artists, pylast.Artist) @@ -1425,10 +1425,10 @@ class TestPyLast(unittest.TestCase): tags = ["albumtagola"] album = self.network.get_album("Test Artist", "Test Album") album.add_tags(tags) - + # Act albums = lastfm_user.get_tagged_albums('albumtagola', limit=1) - + # Assert self.helper_only_one_thing_in_list(albums, pylast.Album) @@ -1440,10 +1440,10 @@ class TestPyLast(unittest.TestCase): track.add_tags(tags) # Act tracks = lastfm_user.get_tagged_tracks('tracktagola', limit=1) - + # Assert self.helper_only_one_thing_in_list(tracks, pylast.Track) - + def test_caching(self): # Arrange user = self.network.get_user("RJ") From 6264b4fecc27271af847f44c92e3eb2512c65e83 Mon Sep 17 00:00:00 2001 From: hugovk Date: Fri, 24 Jul 2015 11:26:36 +0300 Subject: [PATCH 9/9] get_tagged_tracks: Use cacheable param --- pylast/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pylast/__init__.py b/pylast/__init__.py index 253013b..6ba0eb7 100644 --- a/pylast/__init__.py +++ b/pylast/__init__.py @@ -3536,7 +3536,8 @@ class User(_BaseObject, _Chartable): params['taggingtype'] = 'track' if limit: params['limit'] = limit - doc = self._request(self.ws_prefix + '.getpersonaltags', True, params) + doc = self._request(self.ws_prefix + '.getpersonaltags', cacheable, + params) return _extract_tracks(doc, self.network) def get_top_albums(