Merge pull request #299 from pylast/deprecate-User.get_artist_tracks

Deprecate User.get_artist_tracks, add user.getTrackScrobbles
This commit is contained in:
Hugo 2019-03-07 09:07:59 +02:00 committed by GitHub
commit c95e39b624
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 10 deletions

View file

@ -10,6 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Extract username from session via new * Extract username from session via new
`SessionKeyGenerator.get_web_auth_session_key_username` ([#290]) `SessionKeyGenerator.get_web_auth_session_key_username` ([#290])
* `User.get_track_scrobbles` ([#298])
### Deprecated
* `User.get_artist_tracks`. Use `User.get_track_scrobbles` as a partial replacement.
([#298])
## [3.0.0] - 2019-01-01 ## [3.0.0] - 2019-01-01
### Added ### Added
@ -31,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[Unreleased]: https://github.com/pylast/pylast/compare/v3.0.0...HEAD [Unreleased]: https://github.com/pylast/pylast/compare/v3.0.0...HEAD
[3.0.0]: https://github.com/pylast/pylast/compare/2.4.0...3.0.0 [3.0.0]: https://github.com/pylast/pylast/compare/2.4.0...3.0.0
[2.4.0]: https://github.com/pylast/pylast/compare/2.3.0...2.4.0 [2.4.0]: https://github.com/pylast/pylast/compare/2.3.0...2.4.0
[#298]: https://github.com/pylast/pylast/issues/298
[#290]: https://github.com/pylast/pylast/pull/290 [#290]: https://github.com/pylast/pylast/pull/290
[#265]: https://github.com/pylast/pylast/issues/265 [#265]: https://github.com/pylast/pylast/issues/265
[#273]: https://github.com/pylast/pylast/issues/273 [#273]: https://github.com/pylast/pylast/issues/273

View file

@ -20,18 +20,19 @@
# #
# https://github.com/pylast/pylast # https://github.com/pylast/pylast
from xml.dom import minidom, Node
import collections import collections
import hashlib import hashlib
import html.entities
import logging import logging
import shelve import shelve
import ssl import ssl
import sys import sys
import tempfile import tempfile
import time import time
import warnings
import xml.dom import xml.dom
import html.entities
from http.client import HTTPSConnection from http.client import HTTPSConnection
from xml.dom import Node, minidom
from . import version from . import version
@ -2236,6 +2237,14 @@ class User(_BaseObject, _Chartable):
# Not implemented: # Not implemented:
# "Can be limited to specific timeranges, defaults to all time." # "Can be limited to specific timeranges, defaults to all time."
warnings.warn(
"User.get_artist_tracks is deprecated and will be removed in a future "
"version. User.get_track_scrobbles is a partial replacement. "
"See https://github.com/pylast/pylast/issues/298",
DeprecationWarning,
stacklevel=2,
)
params = self._get_params() params = self._get_params()
params["artist"] = artist params["artist"] = artist
@ -2525,6 +2534,32 @@ class User(_BaseObject, _Chartable):
return self._get_things("getTopTracks", "track", Track, params, cacheable) return self._get_things("getTopTracks", "track", Track, params, cacheable)
def get_track_scrobbles(self, artist, track, cacheable=False):
"""
Get a list of this user's scrobbles of this artist's track,
including scrobble time.
"""
params = self._get_params()
params["artist"] = artist
params["track"] = track
seq = []
for track in _collect_nodes(
None, self, self.ws_prefix + ".getTrackScrobbles", cacheable, params
):
title = _extract(track, "name")
artist = _extract(track, "artist")
date = _extract(track, "date")
album = _extract(track, "album")
timestamp = track.getElementsByTagName("date")[0].getAttribute("uts")
seq.append(
PlayedTrack(Track(artist, title, self.network), album, date, timestamp)
)
return seq
def get_image(self, size=SIZE_EXTRA_LARGE): def get_image(self, size=SIZE_EXTRA_LARGE):
""" """
Returns the user's avatar Returns the user's avatar

View file

@ -3,6 +3,7 @@
Integration (not unit) tests for pylast.py Integration (not unit) tests for pylast.py
""" """
import unittest import unittest
import warnings
import pylast import pylast
@ -12,10 +13,10 @@ from .test_pylast import TestPyLastWithLastFm
class TestPyLastAlbum(TestPyLastWithLastFm): class TestPyLastAlbum(TestPyLastWithLastFm):
def test_album_tags_are_topitems(self): def test_album_tags_are_topitems(self):
# Arrange # Arrange
albums = self.network.get_user("RJ").get_top_albums() album = self.network.get_album("Test Artist", "Test Album")
# Act # Act
tags = albums[0].item.get_top_tags(limit=1) tags = album.get_top_tags(limit=1)
# Assert # Assert
self.assertGreater(len(tags), 0) self.assertGreater(len(tags), 0)
@ -44,6 +45,8 @@ class TestPyLastAlbum(TestPyLastWithLastFm):
lastfm_user = self.network.get_user(self.username) lastfm_user = self.network.get_user(self.username)
# Act # Act
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning)
track = lastfm_user.get_artist_tracks(artist="Test Artist")[0] track = lastfm_user.get_artist_tracks(artist="Test Artist")[0]
# Assert # Assert

View file

@ -20,15 +20,14 @@ class TestPyLastNetwork(TestPyLastWithLastFm):
lastfm_user = self.network.get_user(self.username) lastfm_user = self.network.get_user(self.username)
# Act # Act
self.network.scrobble(artist=artist, title="test title 2", timestamp=timestamp)
self.network.scrobble(artist=artist, title=title, timestamp=timestamp) self.network.scrobble(artist=artist, title=title, timestamp=timestamp)
time.sleep(1) # Delay, for Last.fm latency. TODO Can this be removed later?
# Assert # Assert
# limit=2 to ignore now-playing: # limit=2 to ignore now-playing:
last_scrobble = lastfm_user.get_recent_tracks(limit=2)[0] last_scrobble = lastfm_user.get_recent_tracks(limit=2)[0]
self.assertEqual(str(last_scrobble.track.artist).lower(), artist) self.assertEqual(str(last_scrobble.track.artist).lower(), artist)
self.assertEqual(str(last_scrobble.track.title).lower(), title) self.assertEqual(str(last_scrobble.track.title).lower(), title)
self.assertEqual(str(last_scrobble.timestamp), str(timestamp))
def test_update_now_playing(self): def test_update_now_playing(self):
# Arrange # Arrange

View file

@ -4,6 +4,7 @@ Integration (not unit) tests for pylast.py
""" """
import os import os
import unittest import unittest
import warnings
import pylast import pylast
@ -186,6 +187,8 @@ class TestPyLastUser(TestPyLastWithLastFm):
lastfm_user = self.network.get_authenticated_user() lastfm_user = self.network.get_authenticated_user()
# Act # Act
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning)
result1 = lastfm_user.get_artist_tracks("Test Artist", cacheable=False) result1 = lastfm_user.get_artist_tracks("Test Artist", cacheable=False)
result2 = lastfm_user.get_artist_tracks("Test Artist", cacheable=True) result2 = lastfm_user.get_artist_tracks("Test Artist", cacheable=True)
result3 = lastfm_user.get_artist_tracks("Test Artist") result3 = lastfm_user.get_artist_tracks("Test Artist")
@ -430,6 +433,34 @@ class TestPyLastUser(TestPyLastWithLastFm):
self.assertIsNotNone(track) self.assertIsNotNone(track)
self.assertIsInstance(track.network, pylast.LastFMNetwork) self.assertIsInstance(track.network, pylast.LastFMNetwork)
def test_user_get_track_scrobbles(self):
# Arrange
artist = "France Gall"
title = "Laisse Tomber Les Filles"
user = self.network.get_user("bbc6music")
# Act
scrobbles = user.get_track_scrobbles(artist, title)
# Assert
self.assertGreater(len(scrobbles), 0)
self.assertEqual(str(scrobbles[0].track.artist), "France Gall")
self.assertEqual(scrobbles[0].track.title, "Laisse Tomber Les Filles")
def test_cacheable_user_get_track_scrobbles(self):
# Arrange
artist = "France Gall"
title = "Laisse Tomber Les Filles"
user = self.network.get_user("bbc6music")
# Act
result1 = user.get_track_scrobbles(artist, title, cacheable=False)
result2 = user.get_track_scrobbles(artist, title, cacheable=True)
result3 = user.get_track_scrobbles(artist, title)
# Assert
self.helper_validate_results(result1, result2, result3)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main(failfast=True) unittest.main(failfast=True)