Refactor shouts to duplicate code

This commit is contained in:
hugovk 2014-03-06 18:11:39 +02:00
parent 7cb8a654ec
commit ac87cee29d
2 changed files with 201 additions and 195 deletions

313
pylast.py
View file

@ -1340,7 +1340,7 @@ class _BaseObject(object):
tag_name)[0].firstChild.wholeText.strip() tag_name)[0].firstChild.wholeText.strip()
def _get_things( def _get_things(
self, method, thing, thing_type, params = None, cacheable=True): self, method, thing, thing_type, params=None, cacheable=True):
"""Returns a list of the most played thing_types by this thing.""" """Returns a list of the most played thing_types by this thing."""
doc = self._request( doc = self._request(
@ -1368,55 +1368,14 @@ class _BaseObject(object):
return seq return seq
def get_weekly_artist_charts(self, from_date=None, to_date=None): def get_weekly_charts(self, chart_kind, from_date=None, to_date=None):
"""
Returns the weekly artist charts for the week starting from the
from_date value to the to_date value.
"""
params = self._get_params()
if from_date and to_date:
params["from"] = from_date
params["to"] = to_date
doc = self._request(
self.ws_prefix + ".getWeeklyArtistChart", True, params)
seq = []
for node in doc.getElementsByTagName("artist"):
item = Artist(_extract(node, "name"), self.network)
weight = _number(_extract(node, "playcount"))
seq.append(TopItem(item, weight))
return seq
def get_weekly_album_charts(self, from_date=None, to_date=None):
"""
Returns the weekly album charts for the week starting from the
from_date value to the to_date value.
"""
params = self._get_params()
if from_date and to_date:
params["from"] = from_date
params["to"] = to_date
doc = self._request(
self.ws_prefix + ".getWeeklyAlbumChart", True, params)
seq = []
for node in doc.getElementsByTagName("album"):
item = Album(
_extract(node, "artist"), _extract(node, "name"), self.network)
weight = _number(_extract(node, "playcount"))
seq.append(TopItem(item, weight))
return seq
def get_weekly_track_charts(self, from_date=None, to_date=None):
""" """
Returns the weekly track charts for the week starting from the Returns the weekly track charts for the week starting from the
from_date value to the to_date value. from_date value to the to_date value.
chart_kind should be one of "album", "track"
""" """
method = ".getWeekly" + chart_kind.title() + "Chart"
chart_type = eval(chart_kind.title())
params = self._get_params() params = self._get_params()
if from_date and to_date: if from_date and to_date:
@ -1424,11 +1383,11 @@ class _BaseObject(object):
params["to"] = to_date params["to"] = to_date
doc = self._request( doc = self._request(
self.ws_prefix + ".getWeeklyTrackChart", True, params) self.ws_prefix + method, True, params)
seq = [] seq = []
for node in doc.getElementsByTagName("track"): for node in doc.getElementsByTagName(chart_kind.lower()):
item = Track( item = chart_type(
_extract(node, "artist"), _extract(node, "name"), self.network) _extract(node, "artist"), _extract(node, "name"), self.network)
weight = _number(_extract(node, "playcount")) weight = _number(_extract(node, "playcount"))
seq.append(TopItem(item, weight)) seq.append(TopItem(item, weight))
@ -1463,7 +1422,8 @@ class _BaseObject(object):
""" """
Shares this (sends out recommendations). Shares this (sends out recommendations).
Parameters: Parameters:
* users [User|str,]: A list that can contain usernames, emails, User objects, or all of them. * 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. * message str: A message to include in the recommendation message.
Only for Artist/Event/Track. Only for Artist/Event/Track.
""" """
@ -1492,7 +1452,7 @@ class _BaseObject(object):
def get_wiki_published_date(self): def get_wiki_published_date(self):
""" """
Returns the date of publishing this version of the wiki. Returns the date of publishing this version of the wiki.
Only for Album/Track. Only for Album/Tag/Track.
""" """
doc = self._request(self.ws_prefix + ".getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
@ -1534,12 +1494,32 @@ class _BaseObject(object):
return _extract(node, "content") return _extract(node, "content")
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 _Taggable(object): class _Taggable(object):
"""Common functions for classes with tags.""" """Common functions for classes with tags."""
def __init__(self, ws_prefix): def __init__(self, ws_prefix):
self.ws_prefix = ws_prefix # TODO move to _BaseObject self.ws_prefix = ws_prefix # TODO move to _BaseObject
def add_tags(self, tags): def add_tags(self, tags):
"""Adds one or several tags. """Adds one or several tags.
@ -1712,8 +1692,8 @@ class NetworkError(Exception):
class Album(_BaseObject, _Taggable): class Album(_BaseObject, _Taggable):
"""An album.""" """An album."""
title = None
artist = None artist = None
title = None
username = None username = None
__hash__ = _BaseObject.__hash__ __hash__ = _BaseObject.__hash__
@ -1762,7 +1742,8 @@ class Album(_BaseObject, _Taggable):
def _get_params(self): def _get_params(self):
return { return {
'artist': self.get_artist().get_name(), 'album': self.get_title(), 'artist': self.get_artist().get_name(),
self.ws_prefix: self.get_title(),
} }
def get_artist(self): def get_artist(self):
@ -1781,10 +1762,10 @@ class Album(_BaseObject, _Taggable):
return self.get_title() return self.get_title()
def get_release_date(self): def get_release_date(self):
"""Retruns the release date of the album.""" """Returns the release date of the album."""
return _extract( return _extract(self._request(
self._request("album.getInfo", cacheable=True), "releasedate") self.ws_prefix + ".getInfo", cacheable=True), "releasedate")
def get_cover_image(self, size=COVER_EXTRA_LARGE): def get_cover_image(self, size=COVER_EXTRA_LARGE):
""" """
@ -1797,18 +1778,21 @@ class Album(_BaseObject, _Taggable):
""" """
return _extract_all( return _extract_all(
self._request("album.getInfo", cacheable=True), 'image')[size] self._request(
self.ws_prefix + ".getInfo", cacheable=True), 'image')[size]
def get_id(self): def get_id(self):
"""Returns the ID""" """Returns the ID"""
return _extract(self._request("album.getInfo", cacheable=True), "id") return _extract(
self._request(self.ws_prefix + ".getInfo", cacheable=True), "id")
def get_playcount(self): def get_playcount(self):
"""Returns the number of plays on the network""" """Returns the number of plays on the network"""
return _number(_extract( return _number(_extract(
self._request("album.getInfo", cacheable=True), "playcount")) self._request(
self.ws_prefix + ".getInfo", cacheable=True), "playcount"))
def get_userplaycount(self): def get_userplaycount(self):
"""Returns the number of plays by a given username""" """Returns the number of plays by a given username"""
@ -1819,13 +1803,15 @@ class Album(_BaseObject, _Taggable):
params['username'] = self.username params['username'] = self.username
return _number(_extract( return _number(_extract(
self._request("album.getInfo", True, params), "userplaycount")) self._request(
self.ws_prefix + ".getInfo", True, params), "userplaycount"))
def get_listener_count(self): def get_listener_count(self):
"""Returns the number of listeners on the network""" """Returns the number of listeners on the network"""
return _number(_extract( return _number(_extract(
self._request("album.getInfo", cacheable=True), "listeners")) self._request(
self.ws_prefix + ".getInfo", cacheable=True), "listeners"))
def get_tracks(self): def get_tracks(self):
"""Returns the list of Tracks on this album.""" """Returns the list of Tracks on this album."""
@ -1837,7 +1823,8 @@ class Album(_BaseObject, _Taggable):
def get_mbid(self): def get_mbid(self):
"""Returns the MusicBrainz id of the album.""" """Returns the MusicBrainz id of the album."""
return _extract(self._request("album.getInfo", cacheable=True), "mbid") return _extract(
self._request(self.ws_prefix + ".getInfo", cacheable=True), "mbid")
def get_url(self, domain_name=DOMAIN_ENGLISH): def get_url(self, domain_name=DOMAIN_ENGLISH):
"""Returns the url of the album page on the network. """Returns the url of the album page on the network.
@ -1861,7 +1848,7 @@ class Album(_BaseObject, _Taggable):
album = _url_safe(self.get_title()) album = _url_safe(self.get_title())
return self.network._get_url( return self.network._get_url(
domain_name, "album") % {'artist': artist, 'album': album} domain_name, "album") % {'artist': artist, self.ws_prefix: album}
class Artist(_BaseObject, _Taggable): class Artist(_BaseObject, _Taggable):
@ -2094,22 +2081,6 @@ class Artist(_BaseObject, _Taggable):
) )
return images return images
def get_shouts(self, limit=50, cacheable=False):
"""
Returns a sequqence of Shout objects
"""
shouts = []
for node in _collect_nodes(limit, self, "artist.getShouts", cacheable):
shouts.append(
Shout(
_extract(node, "body"),
User(_extract(node, "author"), self.network),
_extract(node, "date")
)
)
return shouts
def shout(self, message): def shout(self, message):
""" """
Post a shout Post a shout
@ -2279,22 +2250,6 @@ class Event(_BaseObject):
return self.network._get_url( return self.network._get_url(
domain_name, "event") % {'id': self.get_id()} domain_name, "event") % {'id': self.get_id()}
def get_shouts(self, limit=50, cacheable=False):
"""
Returns a sequqence of Shout objects
"""
shouts = []
for node in _collect_nodes(limit, self, "event.getShouts", cacheable):
shouts.append(
Shout(
_extract(node, "body"),
User(_extract(node, "author"), self.network),
_extract(node, "date")
)
)
return shouts
def shout(self, message): def shout(self, message):
""" """
Post a shout Post a shout
@ -2305,6 +2260,7 @@ class Event(_BaseObject):
self._request("event.Shout", False, params) self._request("event.Shout", False, params)
class Country(_BaseObject): class Country(_BaseObject):
"""A country at Last.fm.""" """A country at Last.fm."""
@ -2330,7 +2286,7 @@ class Country(_BaseObject):
def __ne__(self, other): def __ne__(self, other):
return self.get_name() != other.get_name() return self.get_name() != other.get_name()
def _get_params(self): # TODO can move to _BaseObject def _get_params(self): # TODO can move to _BaseObject
return {'country': self.get_name()} return {'country': self.get_name()}
def _get_name_from_code(self, alpha2code): def _get_name_from_code(self, alpha2code):
@ -2980,6 +2936,12 @@ class Track(_BaseObject, _Taggable):
__hash__ = _BaseObject.__hash__ __hash__ = _BaseObject.__hash__
def __init__(self, artist, title, network, username=None): def __init__(self, artist, title, network, username=None):
"""
Create a track instance.
# Parameters:
* artist: An artist name or an Artist object.
* title: The artist title.
"""
_BaseObject.__init__(self, network, 'track') _BaseObject.__init__(self, network, 'track')
_Taggable.__init__(self, 'track') _Taggable.__init__(self, 'track')
@ -2989,7 +2951,6 @@ class Track(_BaseObject, _Taggable):
self.artist = Artist(artist, self.network) self.artist = Artist(artist, self.network)
self.title = title self.title = title
self.username = username self.username = username
def __repr__(self): def __repr__(self):
@ -3016,7 +2977,8 @@ class Track(_BaseObject, _Taggable):
def _get_params(self): def _get_params(self):
return { return {
'artist': self.get_artist().get_name(), 'track': self.get_title()} 'artist': self.get_artist().get_name(),
self.ws_prefix: self.get_title()}
def get_artist(self): def get_artist(self):
"""Returns the associated Artist object.""" """Returns the associated Artist object."""
@ -3027,7 +2989,8 @@ class Track(_BaseObject, _Taggable):
"""Returns the track title.""" """Returns the track title."""
if properly_capitalized: if properly_capitalized:
self.title = _extract(self._request("track.getInfo", True), "name") self.title = _extract(
self._request(self.ws_prefix + ".getInfo", True), "name")
return self.title return self.title
@ -3039,21 +3002,21 @@ class Track(_BaseObject, _Taggable):
def get_id(self): def get_id(self):
"""Returns the track id on the network.""" """Returns the track id on the network."""
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "id") return _extract(doc, "id")
def get_duration(self): def get_duration(self):
"""Returns the track duration.""" """Returns the track duration."""
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _number(_extract(doc, "duration")) return _number(_extract(doc, "duration"))
def get_mbid(self): def get_mbid(self):
"""Returns the MusicBrainz ID of this track.""" """Returns the MusicBrainz ID of this track."""
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "mbid") return _extract(doc, "mbid")
@ -3063,14 +3026,14 @@ class Track(_BaseObject, _Taggable):
if hasattr(self, "listener_count"): if hasattr(self, "listener_count"):
return self.listener_count return self.listener_count
else: else:
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
self.listener_count = _number(_extract(doc, "listeners")) self.listener_count = _number(_extract(doc, "listeners"))
return self.listener_count return self.listener_count
def get_playcount(self): def get_playcount(self):
"""Returns the play count.""" """Returns the play count."""
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _number(_extract(doc, "playcount")) return _number(_extract(doc, "playcount"))
def get_userplaycount(self): def get_userplaycount(self):
@ -3081,7 +3044,7 @@ class Track(_BaseObject, _Taggable):
params = self._get_params() params = self._get_params()
params['username'] = self.username params['username'] = self.username
doc = self._request("track.getInfo", True, params) doc = self._request(self.ws_prefix + ".getInfo", True, params)
return _number(_extract(doc, "userplaycount")) return _number(_extract(doc, "userplaycount"))
def get_userloved(self): def get_userloved(self):
@ -3092,27 +3055,27 @@ class Track(_BaseObject, _Taggable):
params = self._get_params() params = self._get_params()
params['username'] = self.username params['username'] = self.username
doc = self._request("track.getInfo", True, params) doc = self._request(self.ws_prefix + ".getInfo", True, params)
loved = _number(_extract(doc, "userloved")) loved = _number(_extract(doc, "userloved"))
return bool(loved) return bool(loved)
def is_streamable(self): def is_streamable(self):
"""Returns True if the track is available at Last.fm.""" """Returns True if the track is available at Last.fm."""
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "streamable") == "1" return _extract(doc, "streamable") == "1"
def is_fulltrack_available(self): def is_fulltrack_available(self):
"""Returns True if the fulltrack is available for streaming.""" """Returns True if the fulltrack is available for streaming."""
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return doc.getElementsByTagName( return doc.getElementsByTagName(
"streamable")[0].getAttribute("fulltrack") == "1" "streamable")[0].getAttribute("fulltrack") == "1"
def get_album(self): def get_album(self):
"""Returns the album object of this track.""" """Returns the album object of this track."""
doc = self._request("track.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
albums = doc.getElementsByTagName("album") albums = doc.getElementsByTagName("album")
@ -3126,17 +3089,17 @@ class Track(_BaseObject, _Taggable):
def love(self): def love(self):
"""Adds the track to the user's loved tracks. """ """Adds the track to the user's loved tracks. """
self._request('track.love') self._request(self.ws_prefix + '.love')
def unlove(self): def unlove(self):
"""Remove the track to the user's loved tracks. """ """Remove the track to the user's loved tracks. """
self._request('track.unlove') self._request(self.ws_prefix + '.unlove')
def ban(self): def ban(self):
"""Ban this track from ever playing on the radio. """ """Ban this track from ever playing on the radio. """
self._request('track.ban') self._request(self.ws_prefix + '.ban')
def get_similar(self): def get_similar(self):
""" """
@ -3144,10 +3107,10 @@ class Track(_BaseObject, _Taggable):
based on listening data. based on listening data.
""" """
doc = self._request('track.getSimilar', True) doc = self._request(self.ws_prefix + '.getSimilar', True)
seq = [] seq = []
for node in doc.getElementsByTagName("track"): for node in doc.getElementsByTagName(self.ws_prefix):
title = _extract(node, 'name') title = _extract(node, 'name')
artist = _extract(node, 'name', 1) artist = _extract(node, 'name', 1)
match = _number(_extract(node, "match")) match = _number(_extract(node, "match"))
@ -3180,22 +3143,6 @@ class Track(_BaseObject, _Taggable):
'domain': self.network._get_language_domain(domain_name), 'domain': self.network._get_language_domain(domain_name),
'artist': artist, 'title': title} 'artist': artist, 'title': title}
def get_shouts(self, limit=50, cacheable=False):
"""
Returns a sequqence of Shout objects
"""
shouts = []
for node in _collect_nodes(limit, self, "track.getShouts", cacheable):
shouts.append(
Shout(
_extract(node, "body"),
User(_extract(node, "author"), self.network),
_extract(node, "date")
)
)
return shouts
class Group(_BaseObject): class Group(_BaseObject):
"""A Last.fm group.""" """A Last.fm group."""
@ -3223,7 +3170,7 @@ class Group(_BaseObject):
return self.get_name() != other.get_name() return self.get_name() != other.get_name()
def _get_params(self): def _get_params(self):
return {'group': self.get_name()} return {self.ws_prefix: self.get_name()}
def get_name(self): def get_name(self):
"""Returns the group name. """ """Returns the group name. """
@ -3256,7 +3203,8 @@ class Group(_BaseObject):
if limit==None it will return all if limit==None it will return all
""" """
nodes = _collect_nodes(limit, self, "group.getMembers", cacheable) nodes = _collect_nodes(
limit, self, self.ws_prefix + ".getMembers", cacheable)
users = [] users = []
@ -3347,20 +3295,21 @@ class User(_BaseObject):
return True return True
def _get_params(self): def _get_params(self):
return {"user": self.get_name()} return {self.ws_prefix: self.get_name()}
def get_name(self, properly_capitalized=False): def get_name(self, properly_capitalized=False):
"""Returns the user name.""" """Returns the user name."""
if properly_capitalized: if properly_capitalized:
self.name = _extract(self._request("user.getInfo", True), "name") self.name = _extract(
self._request(self.ws_prefix + ".getInfo", True), "name")
return self.name return self.name
def get_upcoming_events(self): def get_upcoming_events(self):
"""Returns all the upcoming events for this user.""" """Returns all the upcoming events for this user."""
doc = self._request('user.getEvents', True) doc = self._request(self.ws_prefix + '.getEvents', True)
return _extract_events_from_doc(doc, self.network) return _extract_events_from_doc(doc, self.network)
@ -3377,7 +3326,11 @@ class User(_BaseObject):
seq = [] seq = []
for track in _collect_nodes( for track in _collect_nodes(
None, self, "user.getArtistTracks", cacheable, params): None,
self,
self.ws_prefix + ".getArtistTracks",
cacheable,
params):
title = _extract(track, "name") title = _extract(track, "name")
artist = _extract(track, "artist") artist = _extract(track, "artist")
date = _extract(track, "date") date = _extract(track, "date")
@ -3394,7 +3347,11 @@ class User(_BaseObject):
"""Returns a list of the user's friends. """ """Returns a list of the user's friends. """
seq = [] seq = []
for node in _collect_nodes(limit, self, "user.getFriends", cacheable): for node in _collect_nodes(
limit,
self,
self.ws_prefix + ".getFriends",
cacheable):
seq.append(User(_extract(node, "name"), self.network)) seq.append(User(_extract(node, "name"), self.network))
return seq return seq
@ -3419,8 +3376,11 @@ class User(_BaseObject):
seq = [] seq = []
for track in _collect_nodes( for track in _collect_nodes(
limit, self, "user.getLovedTracks", cacheable, params): limit,
self,
self.ws_prefix + ".getLovedTracks",
cacheable,
params):
title = _extract(track, "name") title = _extract(track, "name")
artist = _extract(track, "name", 1) artist = _extract(track, "name", 1)
date = _extract(track, "date") date = _extract(track, "date")
@ -3439,7 +3399,7 @@ class User(_BaseObject):
if limit: if limit:
params['limit'] = limit params['limit'] = limit
doc = self._request('user.getNeighbours', True, params) doc = self._request(self.ws_prefix + '.getNeighbours', True, params)
seq = [] seq = []
names = _extract_all(doc, 'name') names = _extract_all(doc, 'name')
@ -3456,7 +3416,11 @@ class User(_BaseObject):
""" """
seq = [] seq = []
for n in _collect_nodes(limit, self, "user.getPastEvents", cacheable): for n in _collect_nodes(
limit,
self,
self.ws_prefix + ".getPastEvents",
cacheable):
seq.append(Event(_extract(n, "id"), self.network)) seq.append(Event(_extract(n, "id"), self.network))
return seq return seq
@ -3464,7 +3428,7 @@ class User(_BaseObject):
def get_playlists(self): def get_playlists(self):
"""Returns a list of Playlists that this user owns.""" """Returns a list of Playlists that this user owns."""
doc = self._request("user.getPlaylists", True) doc = self._request(self.ws_prefix + ".getPlaylists", True)
playlists = [] playlists = []
for playlist_id in _extract_all(doc, "id"): for playlist_id in _extract_all(doc, "id"):
@ -3481,7 +3445,7 @@ class User(_BaseObject):
params = self._get_params() params = self._get_params()
params['limit'] = '1' params['limit'] = '1'
doc = self._request('user.getRecentTracks', False, params) doc = self._request(self.ws_prefix + '.getRecentTracks', False, params)
tracks = doc.getElementsByTagName('track') tracks = doc.getElementsByTagName('track')
@ -3518,7 +3482,11 @@ class User(_BaseObject):
seq = [] seq = []
for track in _collect_nodes( for track in _collect_nodes(
limit, self, "user.getRecentTracks", cacheable, params): limit,
self,
self.ws_prefix + ".getRecentTracks",
cacheable,
params):
if track.hasAttribute('nowplaying'): if track.hasAttribute('nowplaying'):
continue # to prevent the now playing track from sneaking in continue # to prevent the now playing track from sneaking in
@ -3536,23 +3504,23 @@ class User(_BaseObject):
return seq return seq
def get_id(self): def get_id(self):
"""Returns the user id.""" """Returns the user ID."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "id") return _extract(doc, "id")
def get_language(self): def get_language(self):
"""Returns the language code of the language used by the user.""" """Returns the language code of the language used by the user."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "lang") return _extract(doc, "lang")
def get_country(self): def get_country(self):
"""Returns the name of the country of the user.""" """Returns the name of the country of the user."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
country = _extract(doc, "country") country = _extract(doc, "country")
@ -3564,14 +3532,14 @@ class User(_BaseObject):
def get_age(self): def get_age(self):
"""Returns the user's age.""" """Returns the user's age."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _number(_extract(doc, "age")) return _number(_extract(doc, "age"))
def get_gender(self): def get_gender(self):
"""Returns the user's gender. Either USER_MALE or USER_FEMALE.""" """Returns the user's gender. Either USER_MALE or USER_FEMALE."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
value = _extract(doc, "gender") value = _extract(doc, "gender")
@ -3585,28 +3553,28 @@ class User(_BaseObject):
def is_subscriber(self): def is_subscriber(self):
"""Returns whether the user is a subscriber or not. True or False.""" """Returns whether the user is a subscriber or not. True or False."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "subscriber") == "1" return _extract(doc, "subscriber") == "1"
def get_playcount(self): def get_playcount(self):
"""Returns the user's playcount so far.""" """Returns the user's playcount so far."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _number(_extract(doc, "playcount")) return _number(_extract(doc, "playcount"))
def get_registered(self): def get_registered(self):
"""Returns the user's registration date.""" """Returns the user's registration date."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "registered") return _extract(doc, "registered")
def get_unixtime_registered(self): def get_unixtime_registered(self):
"""Returns the user's registration date as a UNIX timestamp.""" """Returns the user's registration date as a UNIX timestamp."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return doc.getElementsByTagName( return doc.getElementsByTagName(
"registered")[0].getAttribute("unixtime") "registered")[0].getAttribute("unixtime")
@ -3624,7 +3592,7 @@ class User(_BaseObject):
params = self._get_params() params = self._get_params()
params['period'] = period params['period'] = period
doc = self._request('user.getTopAlbums', True, params) doc = self._request(self.ws_prefix + '.getTopAlbums', True, params)
seq = [] seq = []
for album in doc.getElementsByTagName('album'): for album in doc.getElementsByTagName('album'):
@ -3649,7 +3617,7 @@ class User(_BaseObject):
params = self._get_params() params = self._get_params()
params['period'] = period params['period'] = period
doc = self._request('user.getTopArtists', True, params) doc = self._request(self.ws_prefix + '.getTopArtists', True, params)
seq = [] seq = []
for node in doc.getElementsByTagName('artist'): for node in doc.getElementsByTagName('artist'):
@ -3671,7 +3639,7 @@ class User(_BaseObject):
params = self._get_params() params = self._get_params()
if limit: params["limit"] = limit if limit: params["limit"] = limit
doc = self._request("user.getTopTags", cacheable, params) doc = self._request(self.ws_prefix + ".getTopTags", cacheable, params)
seq = [] seq = []
for node in doc.getElementsByTagName("tag"): for node in doc.getElementsByTagName("tag"):
@ -3681,7 +3649,8 @@ class User(_BaseObject):
return seq return seq
def get_top_tracks(self, period=PERIOD_OVERALL, limit=None, cacheable=True): def get_top_tracks(
self, period=PERIOD_OVERALL, limit=None, cacheable=True):
"""Returns the top tracks played by a user. """Returns the top tracks played by a user.
* period: The period of time. Possible values: * period: The period of time. Possible values:
o PERIOD_OVERALL o PERIOD_OVERALL
@ -3735,7 +3704,7 @@ class User(_BaseObject):
def get_image(self): def get_image(self):
"""Returns the user's avatar.""" """Returns the user's avatar."""
doc = self._request("user.getInfo", True) doc = self._request(self.ws_prefix + ".getInfo", True)
return _extract(doc, "image") return _extract(doc, "image")
@ -3765,22 +3734,6 @@ class User(_BaseObject):
return Library(self, self.network) return Library(self, self.network)
def get_shouts(self, limit=50, cacheable=False):
"""
Returns a sequence of Shout objects
"""
shouts = []
for node in _collect_nodes(limit, self, "user.getShouts", cacheable):
shouts.append(
Shout(
_extract(node, "body"),
User(_extract(node, "author"), self.network),
_extract(node, "date")
)
)
return shouts
def shout(self, message): def shout(self, message):
""" """
Post a shout Post a shout
@ -3789,7 +3742,7 @@ class User(_BaseObject):
params = self._get_params() params = self._get_params()
params["message"] = message params["message"] = message
self._request("user.Shout", False, params) self._request(self.ws_prefix + ".Shout", False, params)
class AuthenticatedUser(User): class AuthenticatedUser(User):
@ -4031,7 +3984,7 @@ class Venue(_BaseObject):
return self.get_id() == other.get_id() return self.get_id() == other.get_id()
def _get_params(self): def _get_params(self):
return {"venue": self.get_id()} return {self.ws_prefix: self.get_id()}
def get_id(self): def get_id(self):
"""Returns the id of the venue.""" """Returns the id of the venue."""
@ -4056,14 +4009,14 @@ class Venue(_BaseObject):
def get_upcoming_events(self): def get_upcoming_events(self):
"""Returns the upcoming events in this venue.""" """Returns the upcoming events in this venue."""
doc = self._request("venue.getEvents", True) doc = self._request(self.ws_prefix + ".getEvents", True)
return _extract_events_from_doc(doc, self.network) return _extract_events_from_doc(doc, self.network)
def get_past_events(self): def get_past_events(self):
"""Returns the past events held in this venue.""" """Returns the past events held in this venue."""
doc = self._request("venue.getEvents", True) doc = self._request(self.ws_prefix + ".getEvents", True)
return _extract_events_from_doc(doc, self.network) return _extract_events_from_doc(doc, self.network)

View file

@ -1028,6 +1028,15 @@ class TestPyLast(unittest.TestCase):
self.assertEqual(type(thing2.item), expected_type) self.assertEqual(type(thing2.item), expected_type)
self.assertNotEqual(thing1, thing2) self.assertNotEqual(thing1, thing2)
def helper_two_things_in_list(self, things, expected_type):
# Assert
self.assertEqual(len(things), 2)
self.assertEqual(type(things), list)
thing1 = things[0]
thing2 = things[1]
self.assertEqual(type(thing1), expected_type)
self.assertEqual(type(thing2), expected_type)
def test_user_get_top_tags_with_limit(self): def test_user_get_top_tags_with_limit(self):
# Arrange # Arrange
user = self.network.get_user("RJ") user = self.network.get_user("RJ")
@ -1145,10 +1154,10 @@ class TestPyLast(unittest.TestCase):
(from_date, to_date) = date (from_date, to_date) = date
# Act # Act
artist_chart = thing.get_weekly_artist_charts(from_date, to_date) artist_chart = thing.get_weekly_charts("artist", from_date, to_date)
if type(thing) is not pylast.Tag: if type(thing) is not pylast.Tag:
album_chart = thing.get_weekly_album_charts(from_date, to_date) album_chart = thing.get_weekly_charts("album", from_date, to_date)
track_chart = thing.get_weekly_track_charts(from_date, to_date) track_chart = thing.get_weekly_charts("track", from_date, to_date)
# Assert # Assert
self.helper_assert_chart(artist_chart, pylast.Artist) self.helper_assert_chart(artist_chart, pylast.Artist)
@ -1174,7 +1183,6 @@ class TestPyLast(unittest.TestCase):
# Act/Assert # Act/Assert
self.helper_get_assert_charts(tag, dates[-1]) self.helper_get_assert_charts(tag, dates[-1])
def test_user_charts(self): def test_user_charts(self):
# Arrange # Arrange
lastfm_user = self.network.get_user("RJ") lastfm_user = self.network.get_user("RJ")
@ -1184,17 +1192,6 @@ class TestPyLast(unittest.TestCase):
# Act/Assert # Act/Assert
self.helper_get_assert_charts(lastfm_user, dates[-1]) self.helper_get_assert_charts(lastfm_user, dates[-1])
def test_artist_top_fans(self):
# Arrange
artist = self.network.get_artist("Test Artist")
# Act
fans = artist.get_top_fans()
# Assert
self.helper_at_least_one_thing_in_top_list(fans, pylast.User)
def test_track_top_fans(self): def test_track_top_fans(self):
# Arrange # Arrange
track = self.network.get_track("The Cinematic Orchestra", "Postlude") track = self.network.get_track("The Cinematic Orchestra", "Postlude")
@ -1222,6 +1219,62 @@ class TestPyLast(unittest.TestCase):
# Assert # Assert
# Check inbox for spam! # Check inbox for spam!
#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)
if __name__ == '__main__': if __name__ == '__main__':