works with CDATA tags
This commit is contained in:
parent
78aac5c437
commit
e2cc69a7e8
2
AUTHORS
Normal file
2
AUTHORS
Normal file
|
@ -0,0 +1,2 @@
|
|||
Amr Hassan <amr.hassan@gmail.com>
|
||||
Lukas Lipka <lukaslipka@gmail.com>
|
|
@ -1,6 +0,0 @@
|
|||
include pylast.py
|
||||
include setup.py
|
||||
include README
|
||||
include COPYING
|
||||
include INSTALL
|
||||
include .build
|
10
PKG-INFO
Normal file
10
PKG-INFO
Normal 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
4
README
|
@ -3,5 +3,5 @@ pylast
|
|||
|
||||
A python interface to Last.fm. Try using the pydoc utility for help
|
||||
on usage.
|
||||
|
||||
Original code can be found at: http://code.google.com/p/pylast/
|
||||
For more info check out the project's home page at http://code.google.com/p/pylast/
|
||||
or the mailing list http://groups.google.com/group/pylast/
|
||||
|
|
103
pylast.py
103
pylast.py
|
@ -313,6 +313,37 @@ class _Network(object):
|
|||
|
||||
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):
|
||||
"""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):
|
||||
"""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
|
||||
None set, a temp file would probably be created, according the backend.
|
||||
|
@ -1150,9 +1183,8 @@ class Album(_BaseObject, _Taggable):
|
|||
|
||||
title = None
|
||||
artist = None
|
||||
username = None
|
||||
|
||||
def __init__(self, artist, title, network, username=None):
|
||||
def __init__(self, artist, title, network):
|
||||
"""
|
||||
Create an album instance.
|
||||
# Parameters:
|
||||
|
@ -1169,7 +1201,6 @@ class Album(_BaseObject, _Taggable):
|
|||
self.artist = Artist(artist, self.network)
|
||||
|
||||
self.title = title
|
||||
self.username = username
|
||||
|
||||
def __repr__(self):
|
||||
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"))
|
||||
|
||||
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):
|
||||
"""Returns the number of liteners on the network"""
|
||||
|
||||
|
@ -1334,9 +1355,8 @@ class Artist(_BaseObject, _Taggable):
|
|||
"""An artist."""
|
||||
|
||||
name = None
|
||||
username = None
|
||||
|
||||
def __init__(self, name, network, username=None):
|
||||
def __init__(self, name, network):
|
||||
"""Create an artist object.
|
||||
# Parameters:
|
||||
* name str: The artist's name.
|
||||
|
@ -1346,7 +1366,6 @@ class Artist(_BaseObject, _Taggable):
|
|||
_Taggable.__init__(self, 'artist')
|
||||
|
||||
self.name = name
|
||||
self.username = username
|
||||
|
||||
def __repr__(self):
|
||||
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"))
|
||||
|
||||
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):
|
||||
"""Returns the MusicBrainz ID of this artist."""
|
||||
|
||||
|
@ -2344,9 +2353,8 @@ class Track(_BaseObject, _Taggable):
|
|||
|
||||
artist = None
|
||||
title = None
|
||||
username = None
|
||||
|
||||
def __init__(self, artist, title, network, username=None):
|
||||
def __init__(self, artist, title, network):
|
||||
_BaseObject.__init__(self, network)
|
||||
_Taggable.__init__(self, 'track')
|
||||
|
||||
|
@ -2357,8 +2365,6 @@ class Track(_BaseObject, _Taggable):
|
|||
|
||||
self.title = title
|
||||
|
||||
self.username = username
|
||||
|
||||
def __repr__(self):
|
||||
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)
|
||||
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):
|
||||
"""Returns True if the track is available at Last.fm."""
|
||||
|
||||
|
@ -2835,24 +2830,6 @@ class User(_BaseObject):
|
|||
|
||||
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):
|
||||
"""Returns a list of the user's friends. """
|
||||
|
||||
|
@ -2946,7 +2923,7 @@ class User(_BaseObject):
|
|||
artist = _extract(e, 'artist')
|
||||
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):
|
||||
|
@ -3552,7 +3529,7 @@ def _string(text):
|
|||
|
||||
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
|
||||
"""
|
||||
|
||||
|
@ -3577,7 +3554,7 @@ def _collect_nodes(limit, sender, method_name, cacheable, params=None):
|
|||
raise Exception("No total pages attribute")
|
||||
|
||||
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)
|
||||
|
||||
if page >= total_pages:
|
||||
|
@ -3594,7 +3571,7 @@ def _extract(node, name, index = 0):
|
|||
|
||||
if len(nodes):
|
||||
if nodes[index].firstChild:
|
||||
return _unescape_htmlentity(nodes[index].firstChild.data.strip())
|
||||
return _unescape_htmlentity(nodes[index].firstChild.wholeText.strip())
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
9
setup.py
Executable file → Normal file
9
setup.py
Executable file → Normal file
|
@ -1,6 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from distutils.core import setup
|
||||
try:
|
||||
from setuptools import setup
|
||||
except:
|
||||
from distutils.core import setup
|
||||
|
||||
import os
|
||||
def get_build():
|
||||
|
@ -22,11 +25,11 @@ def get_build():
|
|||
return str(build)
|
||||
|
||||
setup(name = "pylast",
|
||||
version = "0.1+0.5." + get_build(),
|
||||
version = "0.5." + get_build(),
|
||||
author = "Amr Hassan <amr.hassan@gmail.com>",
|
||||
description = "A Python interface to Last.fm (and other API compatible social networks)",
|
||||
author_email = "amr.hassan@gmail.com",
|
||||
url = "https://github.com/Elizacat/",
|
||||
url = "http://code.google.com/p/pylast/",
|
||||
py_modules = ("pylast",),
|
||||
license = "Apache2"
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue