works with CDATA tags

This commit is contained in:
Matt Jeffery 2013-03-01 19:38:41 +00:00
parent 78aac5c437
commit e2cc69a7e8
7 changed files with 116 additions and 130 deletions

2
.build
View file

@ -1 +1 @@
14 11

2
AUTHORS Normal file
View file

@ -0,0 +1,2 @@
Amr Hassan <amr.hassan@gmail.com>
Lukas Lipka <lukaslipka@gmail.com>

View file

@ -1,6 +0,0 @@
include pylast.py
include setup.py
include README
include COPYING
include INSTALL
include .build

10
PKG-INFO Normal file
View file

@ -0,0 +1,10 @@
Metadata-Version: 1.0
Name: pylast
Version: 0.5.11
Summary: A Python interface to Last.fm (and other API compatible social networks)
Home-page: http://code.google.com/p/pylast/
Author: Amr Hassan <amr.hassan@gmail.com>
Author-email: amr.hassan@gmail.com
License: Apache2
Description: UNKNOWN
Platform: UNKNOWN

4
README
View file

@ -3,5 +3,5 @@ pylast
A python interface to Last.fm. Try using the pydoc utility for help A python interface to Last.fm. Try using the pydoc utility for help
on usage. on usage.
For more info check out the project's home page at http://code.google.com/p/pylast/
Original code can be found at: http://code.google.com/p/pylast/ or the mailing list http://groups.google.com/group/pylast/

103
pylast.py
View file

@ -313,6 +313,37 @@ class _Network(object):
return Playlist(user, e_id, self) return Playlist(user, e_id, self)
def get_top_artists(self, limit=None):
"""Returns a sequence of the most played artists."""
doc = _Request(self, "chart.getTopArtists").execute(True)
seq = []
for node in doc.getElementsByTagName("artist"):
title = _extract(node, "name")
artist = Artist(title, self)
seq.append(artist)
if limit:
seq = seq[:limit]
return seq
def get_top_tracks(self, limit=None):
"""Returns a sequence of the most played tracks."""
doc = _Request(self, "chart.getTopTracks").execute(True)
seq = []
for node in doc.getElementsByTagName("track"):
title = _extract(node, "name")
artist = _extract(node, "name", 1)
track = Track(artist, title, self)
seq.append(track)
if limit:
seq = seq[:limit]
return seq
def get_top_tags(self, limit=None): def get_top_tags(self, limit=None):
"""Returns a sequence of the most used tags as a sequence of TopItem objects.""" """Returns a sequence of the most used tags as a sequence of TopItem objects."""
@ -352,6 +383,8 @@ class _Network(object):
def enable_caching(self, file_path = None): def enable_caching(self, file_path = None):
"""Enables caching request-wide for all cachable calls. """Enables caching request-wide for all cachable calls.
In choosing the backend used for caching, it will try _SqliteCacheBackend first if
the module sqlite3 is present. If not, it will fallback to _ShelfCacheBackend which uses shelve.Shelf objects.
* file_path: A file path for the backend storage file. If * file_path: A file path for the backend storage file. If
None set, a temp file would probably be created, according the backend. None set, a temp file would probably be created, according the backend.
@ -1150,9 +1183,8 @@ class Album(_BaseObject, _Taggable):
title = None title = None
artist = None artist = None
username = None
def __init__(self, artist, title, network, username=None): def __init__(self, artist, title, network):
""" """
Create an album instance. Create an album instance.
# Parameters: # Parameters:
@ -1169,7 +1201,6 @@ class Album(_BaseObject, _Taggable):
self.artist = Artist(artist, self.network) self.artist = Artist(artist, self.network)
self.title = title self.title = title
self.username = username
def __repr__(self): def __repr__(self):
return "pylast.Album(%s, %s, %s)" %(repr(self.artist.name), repr(self.title), repr(self.network)) return "pylast.Album(%s, %s, %s)" %(repr(self.artist.name), repr(self.title), repr(self.network))
@ -1229,16 +1260,6 @@ class Album(_BaseObject, _Taggable):
return _number(_extract(self._request("album.getInfo", cacheable = True), "playcount")) return _number(_extract(self._request("album.getInfo", cacheable = True), "playcount"))
def get_userplaycount(self):
"""Returns the number of plays by a given username"""
if not self.username: return
params = self._get_params()
params['username'] = self.username
return _number(_extract(self._request("album.getInfo", True, params), "userplaycount"))
def get_listener_count(self): def get_listener_count(self):
"""Returns the number of liteners on the network""" """Returns the number of liteners on the network"""
@ -1334,9 +1355,8 @@ class Artist(_BaseObject, _Taggable):
"""An artist.""" """An artist."""
name = None name = None
username = None
def __init__(self, name, network, username=None): def __init__(self, name, network):
"""Create an artist object. """Create an artist object.
# Parameters: # Parameters:
* name str: The artist's name. * name str: The artist's name.
@ -1346,7 +1366,6 @@ class Artist(_BaseObject, _Taggable):
_Taggable.__init__(self, 'artist') _Taggable.__init__(self, 'artist')
self.name = name self.name = name
self.username = username
def __repr__(self): def __repr__(self):
return "pylast.Artist(%s, %s)" %(repr(self.get_name()), repr(self.network)) return "pylast.Artist(%s, %s)" %(repr(self.get_name()), repr(self.network))
@ -1392,16 +1411,6 @@ class Artist(_BaseObject, _Taggable):
return _number(_extract(self._request("artist.getInfo", True), "playcount")) return _number(_extract(self._request("artist.getInfo", True), "playcount"))
def get_userplaycount(self):
"""Returns the number of plays by a given username"""
if not self.username: return
params = self._get_params()
params['username'] = self.username
return _number(_extract(self._request("artist.getInfo", True, params), "userplaycount"))
def get_mbid(self): def get_mbid(self):
"""Returns the MusicBrainz ID of this artist.""" """Returns the MusicBrainz ID of this artist."""
@ -2344,9 +2353,8 @@ class Track(_BaseObject, _Taggable):
artist = None artist = None
title = None title = None
username = None
def __init__(self, artist, title, network, username=None): def __init__(self, artist, title, network):
_BaseObject.__init__(self, network) _BaseObject.__init__(self, network)
_Taggable.__init__(self, 'track') _Taggable.__init__(self, 'track')
@ -2357,8 +2365,6 @@ class Track(_BaseObject, _Taggable):
self.title = title self.title = title
self.username = username
def __repr__(self): def __repr__(self):
return "pylast.Track(%s, %s, %s)" %(repr(self.artist.name), repr(self.title), repr(self.network)) return "pylast.Track(%s, %s, %s)" %(repr(self.artist.name), repr(self.title), repr(self.network))
@ -2430,17 +2436,6 @@ class Track(_BaseObject, _Taggable):
doc = self._request("track.getInfo", True) doc = self._request("track.getInfo", True)
return _number(_extract(doc, "playcount")) return _number(_extract(doc, "playcount"))
def get_userplaycount(self):
"""Returns the number of plays by a given username"""
if not self.username: return
params = self._get_params()
params['username'] = self.username
doc = self._request("track.getInfo", True, params)
return _number(_extract(doc, "userplaycount"))
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."""
@ -2835,24 +2830,6 @@ class User(_BaseObject):
return events return events
def get_artist_tracks(self, artist):
"""Get a list of tracks by a given artist scrobbled by this user, including scrobble time."""
# Not implemented: "Can be limited to specific timeranges, defaults to all time."
params = self._get_params()
params['artist'] = artist
seq = []
for track in _collect_nodes(None, self, "user.getArtistTracks", False, params):
title = _extract(track, "name")
artist = _extract(track, "artist")
date = _extract(track, "date")
timestamp = track.getElementsByTagName("date")[0].getAttribute("uts")
seq.append(PlayedTrack(Track(artist, title, self.network), date, timestamp))
return seq
def get_friends(self, limit = 50): def get_friends(self, limit = 50):
"""Returns a list of the user's friends. """ """Returns a list of the user's friends. """
@ -2946,7 +2923,7 @@ class User(_BaseObject):
artist = _extract(e, 'artist') artist = _extract(e, 'artist')
title = _extract(e, 'name') title = _extract(e, 'name')
return Track(artist, title, self.network, self.name) return Track(artist, title, self.network)
def get_recent_tracks(self, limit = 10): def get_recent_tracks(self, limit = 10):
@ -3552,7 +3529,7 @@ def _string(text):
def _collect_nodes(limit, sender, method_name, cacheable, params=None): def _collect_nodes(limit, sender, method_name, cacheable, params=None):
""" """
Returns a sequence of dom.Node objects about as close to Returns a sequqnce of dom.Node objects about as close to
limit as possible limit as possible
""" """
@ -3577,7 +3554,7 @@ def _collect_nodes(limit, sender, method_name, cacheable, params=None):
raise Exception("No total pages attribute") raise Exception("No total pages attribute")
for node in main.childNodes: for node in main.childNodes:
if not node.nodeType == xml.dom.Node.TEXT_NODE and (not limit or (len(nodes) < limit)): if not node.nodeType == xml.dom.Node.TEXT_NODE and len(nodes) < limit:
nodes.append(node) nodes.append(node)
if page >= total_pages: if page >= total_pages:
@ -3594,7 +3571,7 @@ def _extract(node, name, index = 0):
if len(nodes): if len(nodes):
if nodes[index].firstChild: if nodes[index].firstChild:
return _unescape_htmlentity(nodes[index].firstChild.data.strip()) return _unescape_htmlentity(nodes[index].firstChild.wholeText.strip())
else: else:
return None return None

7
setup.py Executable file → Normal file
View file

@ -1,5 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
try:
from setuptools import setup
except:
from distutils.core import setup from distutils.core import setup
import os import os
@ -22,11 +25,11 @@ def get_build():
return str(build) return str(build)
setup(name = "pylast", setup(name = "pylast",
version = "0.1+0.5." + get_build(), version = "0.5." + get_build(),
author = "Amr Hassan <amr.hassan@gmail.com>", author = "Amr Hassan <amr.hassan@gmail.com>",
description = "A Python interface to Last.fm (and other API compatible social networks)", description = "A Python interface to Last.fm (and other API compatible social networks)",
author_email = "amr.hassan@gmail.com", author_email = "amr.hassan@gmail.com",
url = "https://github.com/Elizacat/", url = "http://code.google.com/p/pylast/",
py_modules = ("pylast",), py_modules = ("pylast",),
license = "Apache2" license = "Apache2"
) )