commit
139fdddb44
|
@ -31,6 +31,8 @@ matrix:
|
||||||
env: TOXENV=pypy3
|
env: TOXENV=pypy3
|
||||||
- python: pypy
|
- python: pypy
|
||||||
env: TOXENV=pypy
|
env: TOXENV=pypy
|
||||||
|
- python: 3.6-dev
|
||||||
|
env: TOXENV=py36dev
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- env: TOXENV=pypy
|
- env: TOXENV=pypy
|
||||||
- env: TOXENV=pypy3
|
- env: TOXENV=pypy3
|
||||||
|
|
|
@ -19,6 +19,14 @@ Installation
|
||||||
Install via pip:
|
Install via pip:
|
||||||
|
|
||||||
pip install pylast
|
pip install pylast
|
||||||
|
|
||||||
|
Install latest development version:
|
||||||
|
|
||||||
|
pip install -U git+https://github.com/pylast/pylast.git
|
||||||
|
|
||||||
|
Or from requirements.txt:
|
||||||
|
|
||||||
|
-e git://github.com/pylast/pylast.git#egg=pylast
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
|
|
||||||
|
|
|
@ -86,11 +86,12 @@ DOMAIN_RUSSIAN = 9
|
||||||
DOMAIN_JAPANESE = 10
|
DOMAIN_JAPANESE = 10
|
||||||
DOMAIN_CHINESE = 11
|
DOMAIN_CHINESE = 11
|
||||||
|
|
||||||
COVER_SMALL = 0
|
# COVER_X is deprecated since 2.1.0 and will be removed in a future version
|
||||||
COVER_MEDIUM = 1
|
SIZE_SMALL = COVER_SMALL = 0
|
||||||
COVER_LARGE = 2
|
SIZE_MEDIUM = COVER_MEDIUM = 1
|
||||||
COVER_EXTRA_LARGE = 3
|
SIZE_LARGE = COVER_LARGE = 2
|
||||||
COVER_MEGA = 4
|
SIZE_EXTRA_LARGE = COVER_EXTRA_LARGE = 3
|
||||||
|
SIZE_MEGA = COVER_MEGA = 4
|
||||||
|
|
||||||
IMAGES_ORDER_POPULARITY = "popularity"
|
IMAGES_ORDER_POPULARITY = "popularity"
|
||||||
IMAGES_ORDER_DATE = "dateadded"
|
IMAGES_ORDER_DATE = "dateadded"
|
||||||
|
@ -1468,14 +1469,14 @@ class Album(_Opus):
|
||||||
def __init__(self, artist, title, network, username=None):
|
def __init__(self, artist, title, network, username=None):
|
||||||
super(Album, self).__init__(artist, title, network, "album", username)
|
super(Album, self).__init__(artist, title, network, "album", username)
|
||||||
|
|
||||||
def get_cover_image(self, size=COVER_EXTRA_LARGE):
|
def get_cover_image(self, size=SIZE_EXTRA_LARGE):
|
||||||
"""
|
"""
|
||||||
Returns a uri to the cover image
|
Returns a uri to the cover image
|
||||||
size can be one of:
|
size can be one of:
|
||||||
COVER_EXTRA_LARGE
|
SIZE_EXTRA_LARGE
|
||||||
COVER_LARGE
|
SIZE_LARGE
|
||||||
COVER_MEDIUM
|
SIZE_MEDIUM
|
||||||
COVER_SMALL
|
SIZE_SMALL
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return _extract_all(
|
return _extract_all(
|
||||||
|
@ -1575,15 +1576,15 @@ class Artist(_BaseObject, _Taggable):
|
||||||
return _extract(
|
return _extract(
|
||||||
self._request(self.ws_prefix + ".getCorrection"), "name")
|
self._request(self.ws_prefix + ".getCorrection"), "name")
|
||||||
|
|
||||||
def get_cover_image(self, size=COVER_MEGA):
|
def get_cover_image(self, size=SIZE_EXTRA_LARGE):
|
||||||
"""
|
"""
|
||||||
Returns a uri to the cover image
|
Returns a uri to the cover image
|
||||||
size can be one of:
|
size can be one of:
|
||||||
COVER_MEGA
|
SIZE_MEGA
|
||||||
COVER_EXTRA_LARGE
|
SIZE_EXTRA_LARGE
|
||||||
COVER_LARGE
|
SIZE_LARGE
|
||||||
COVER_MEDIUM
|
SIZE_MEDIUM
|
||||||
COVER_SMALL
|
SIZE_SMALL
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return _extract_all(
|
return _extract_all(
|
||||||
|
@ -2287,8 +2288,8 @@ class User(_BaseObject, _Chartable):
|
||||||
|
|
||||||
doc = self._request(self.ws_prefix + ".getInfo", True)
|
doc = self._request(self.ws_prefix + ".getInfo", True)
|
||||||
|
|
||||||
return doc.getElementsByTagName(
|
return int(doc.getElementsByTagName(
|
||||||
"registered")[0].getAttribute("unixtime")
|
"registered")[0].getAttribute("unixtime"))
|
||||||
|
|
||||||
def get_tagged_albums(self, tag, limit=None, cacheable=True):
|
def get_tagged_albums(self, tag, limit=None, cacheable=True):
|
||||||
"""Returns the albums tagged by a user."""
|
"""Returns the albums tagged by a user."""
|
||||||
|
@ -2409,12 +2410,19 @@ class User(_BaseObject, _Chartable):
|
||||||
return self._get_things(
|
return self._get_things(
|
||||||
"getTopTracks", "track", Track, params, cacheable)
|
"getTopTracks", "track", Track, params, cacheable)
|
||||||
|
|
||||||
def get_image(self):
|
def get_image(self, size=SIZE_EXTRA_LARGE):
|
||||||
"""Returns the user's avatar."""
|
"""
|
||||||
|
Returns the user's avatar
|
||||||
|
size can be one of:
|
||||||
|
SIZE_EXTRA_LARGE
|
||||||
|
SIZE_LARGE
|
||||||
|
SIZE_MEDIUM
|
||||||
|
SIZE_SMALL
|
||||||
|
"""
|
||||||
|
|
||||||
doc = self._request(self.ws_prefix + ".getInfo", True)
|
doc = self._request(self.ws_prefix + ".getInfo", True)
|
||||||
|
|
||||||
return _extract(doc, "image")
|
return _extract_all(doc, "image")[size]
|
||||||
|
|
||||||
def get_url(self, domain_name=DOMAIN_ENGLISH):
|
def get_url(self, domain_name=DOMAIN_ENGLISH):
|
||||||
"""Returns the url of the user page on the network.
|
"""Returns the url of the user page on the network.
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -27,6 +27,7 @@ setup(
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
"Programming Language :: Python :: Implementation :: PyPy",
|
"Programming Language :: Python :: Implementation :: PyPy",
|
||||||
],
|
],
|
||||||
|
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||||
keywords=["Last.fm", "music", "scrobble", "scrobbling"],
|
keywords=["Last.fm", "music", "scrobble", "scrobbling"],
|
||||||
packages=find_packages(exclude=('tests*',)),
|
packages=find_packages(exclude=('tests*',)),
|
||||||
license="Apache2"
|
license="Apache2"
|
||||||
|
|
|
@ -14,7 +14,7 @@ class TestPyLastNetwork(PyLastTestCase):
|
||||||
|
|
||||||
def test_scrobble(self):
|
def test_scrobble(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
artist = "Test Artist"
|
artist = "test artist"
|
||||||
title = "test title"
|
title = "test title"
|
||||||
timestamp = self.unix_timestamp()
|
timestamp = self.unix_timestamp()
|
||||||
lastfm_user = self.network.get_user(self.username)
|
lastfm_user = self.network.get_user(self.username)
|
||||||
|
@ -25,8 +25,8 @@ class TestPyLastNetwork(PyLastTestCase):
|
||||||
# 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), str(artist))
|
self.assertEqual(str(last_scrobble.track.artist).lower(), artist)
|
||||||
self.assertEqual(str(last_scrobble.track.title), str(title))
|
self.assertEqual(str(last_scrobble.track.title).lower(), title)
|
||||||
self.assertEqual(str(last_scrobble.timestamp), str(timestamp))
|
self.assertEqual(str(last_scrobble.timestamp), str(timestamp))
|
||||||
|
|
||||||
def test_update_now_playing(self):
|
def test_update_now_playing(self):
|
||||||
|
@ -44,8 +44,8 @@ class TestPyLastNetwork(PyLastTestCase):
|
||||||
# Assert
|
# Assert
|
||||||
current_track = lastfm_user.get_now_playing()
|
current_track = lastfm_user.get_now_playing()
|
||||||
self.assertIsNotNone(current_track)
|
self.assertIsNotNone(current_track)
|
||||||
self.assertEqual(str(current_track.title), "test title")
|
self.assertEqual(str(current_track.title).lower(), "test title")
|
||||||
self.assertEqual(str(current_track.artist), "Test Artist")
|
self.assertEqual(str(current_track.artist).lower(), "test artist")
|
||||||
|
|
||||||
def test_enable_rate_limiting(self):
|
def test_enable_rate_limiting(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
|
|
@ -23,8 +23,8 @@ class TestPyLastTrack(PyLastTestCase):
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
loved = lastfm_user.get_loved_tracks(limit=1)
|
loved = lastfm_user.get_loved_tracks(limit=1)
|
||||||
self.assertEqual(str(loved[0].track.artist), "Test Artist")
|
self.assertEqual(str(loved[0].track.artist).lower(), "test artist")
|
||||||
self.assertEqual(str(loved[0].track.title), "test title")
|
self.assertEqual(str(loved[0].track.title).lower(), "test title")
|
||||||
|
|
||||||
def test_unlove(self):
|
def test_unlove(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
|
|
@ -87,7 +87,7 @@ class TestPyLastUser(PyLastTestCase):
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
# Just check date because of timezones
|
# Just check date because of timezones
|
||||||
self.assertEqual(unixtime_registered, u"1037793040")
|
self.assertEqual(unixtime_registered, 1037793040)
|
||||||
|
|
||||||
def test_get_countryless_user(self):
|
def test_get_countryless_user(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -399,7 +399,7 @@ class TestPyLastUser(PyLastTestCase):
|
||||||
title = track.get_title(properly_capitalized=True)
|
title = track.get_title(properly_capitalized=True)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
self.assertEqual(title, "test title")
|
self.assertEqual(title, "Test Title")
|
||||||
|
|
||||||
def test_track_listener_count(self):
|
def test_track_listener_count(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
|
Loading…
Reference in a new issue