implemented playlist related methods in album, tag and user modules. updated some methods to the latest API docs. The read-only part of API is complete.

master
Abhinav Sarkar 2008-09-02 14:19:03 +00:00
parent a2320e6dd0
commit 27a1676c3b
7 changed files with 148 additions and 38 deletions

View File

@ -114,6 +114,10 @@ class Album(LastfmBase):
"""top tag for the album"""
pass
@LastfmBase.cachedProperty
def playlist(self):
return Playlist.fetch(self.__api, "lastfm://playlist/album/%s" % self.id)
@staticmethod
def _fetchData(api,
artist = None,
@ -203,5 +207,6 @@ import time
from api import Api
from artist import Artist
from error import LastfmInvalidParametersError
from playlist import Playlist
from stats import Stats
from tag import Tag

View File

@ -13,7 +13,7 @@ class Api(object):
SEARCH_XMLNS = "http://a9.com/-/spec/opensearch/1.1/"
def __init__(self,
apiKey = '23caa86333d2cb2055fa82129802780a',
apiKey,
input_encoding=None,
request_headers=None,
no_cache = False,
@ -264,7 +264,6 @@ class Api(object):
def _fetchData(self,
params,
parse = True,
no_cache = False):
params.update({'api_key': self.__apiKey})
xml = self._fetchUrl(Api.API_ROOT_URL, params, no_cache = self._no_cache or no_cache)
@ -280,10 +279,7 @@ class Api(object):
raise errorMap[code](message, code)
else:
raise LastfmError(message, code)
if parse:
return data
else:
return xml
return data
def __repr__(self):
return "<lastfm.Api: %s>" % self.__apiKey

View File

@ -12,10 +12,15 @@ class Geo(object):
@staticmethod
def getEvents(api,
location,
latitude = None,
longitude = None,
distance = None):
params = {'method': 'geo.getevents', 'location': location}
if distance is not None:
params.update({'distance': distance})
if latitude is not None and longitude is not None:
params.update({'latitude': latitude, 'longitude': longitude})
@lazylist
def gen(lst):
@ -58,8 +63,11 @@ class Geo(object):
]
@staticmethod
def getTopTracks(api, country):
def getTopTracks(api, country, location = None):
params = {'method': 'geo.gettoptracks', 'country': country}
if location is not None:
params.update({'location': location})
data = api._fetchData(params).find('toptracks')
return [
Track(
@ -135,7 +143,6 @@ class Location(LastfmBase):
def init(self,
api,
name = None,
city = None,
country = None,
street = None,
@ -146,7 +153,6 @@ class Location(LastfmBase):
if not isinstance(api, Api):
raise LastfmInvalidParametersError("api reference must be supplied as an argument")
self.__api = api
self.__name = name
self.__city = city
self.__country = country
self.__street = street
@ -155,11 +161,6 @@ class Location(LastfmBase):
self.__longitude = longitude
self.__timezone = timezone
@property
def name(self):
"""name of the location"""
return self.__name
@property
def city(self):
"""city in which the location is situated"""
@ -194,10 +195,26 @@ class Location(LastfmBase):
def timezone(self):
"""timezone in which the location is situated"""
return self.__timezone
@LastfmBase.cachedProperty
def topTracks(self):
"""top tracks of the location"""
if self.country is None or self.city is None:
raise LastfmInvalidParametersError("country and city of this location are required for calling this method")
return Geo.getTopTracks(self.__api, self.country.name, self.city)
@LastfmBase.topProperty("topTracks")
def topTrack(self):
"""top track of the location"""
pass
def getEvents(self,
distance = None):
return Geo.getEvents(self.__api, self.name, distance)
return Geo.getEvents(self.__api,
self.city,
self.latitude,
self.longitude,
distance)
@LastfmBase.cachedProperty
def events(self):
@ -210,9 +227,9 @@ class Location(LastfmBase):
return hash("latlong%s%s" % (kwds['latitude'], kwds['longitude']))
except KeyError:
try:
return hash("name%s" % kwds['name'])
return hash("name%s" % kwds['city'])
except KeyError:
raise LastfmInvalidParametersError("either latitude and longitude or name has to be provided for hashing")
raise LastfmInvalidParametersError("either latitude and longitude or city has to be provided for hashing")
def __hash__(self):
if not self.name:
@ -220,7 +237,7 @@ class Location(LastfmBase):
latitude = self.latitude,
longitude = self.longitude)
else:
return self.__class__.hashFunc(name = self.name)
return self.__class__.hashFunc(name = self.city)
def __eq__(self, other):
return self.latitude == other.latitude and self.longitude == other.longitude
@ -232,10 +249,10 @@ class Location(LastfmBase):
return self.city < other.city
def __repr__(self):
if self.name is None:
if self.city is None:
return "<lastfm.geo.Location: (%s, %s)>" % (self.latitude, self.longitude)
else:
return "<lastfm.geo.Location: %s>" % self.name
return "<lastfm.geo.Location: %s>" % self.city
class Country(LastfmBase):
"""A class representing a country."""
@ -262,21 +279,24 @@ class Country(LastfmBase):
"""top artist of the country"""
pass
def getTopTracks(self, location = None):
return Geo.getTopTracks(self.__api, self.name, location)
@LastfmBase.cachedProperty
def topTracks(self):
"""top tracks of the country"""
return Geo.getTopTracks(self.__api, self.name)
return self.getTopTracks()
@LastfmBase.cachedProperty
def events(self):
"""events taking place at/around the location"""
return Geo.getEvents(self.__api, self.name)
@LastfmBase.topProperty("topTracks")
def topTrack(self):
"""top track of the country"""
pass
@LastfmBase.cachedProperty
def events(self):
"""events taking place at/around the location"""
return Geo.getEvents(self.__api, self.name)
@staticmethod
def hashFunc(*args, **kwds):
try:

View File

@ -8,14 +8,18 @@ from base import LastfmBase
class Playlist(LastfmBase):
"""A class representing an XPSF playlist."""
def init(self, xpsfData, url):
self.__data = xpsfData
def init(self, api, url):
self.__api = api
self.__data = None
self.__url = url
@property
@LastfmBase.cachedProperty
def data(self):
"""playlist's data"""
return self.__data
params = {'method': 'playlist.fetch', 'playlistURL': self.__url}
tmp = StringIO.StringIO()
ElementTree.ElementTree(self.__api._fetchData(params)[0]).write(tmp)
return tmp.getvalue()
@property
def url(self):
@ -24,8 +28,7 @@ class Playlist(LastfmBase):
@staticmethod
def fetch(api, url):
params = {'method': 'playlist.fetch', 'playlistURL': url}
return Playlist(api._fetchData(params, parse = False), url = url)
return Playlist(api, url = url)
@staticmethod
def hashFunc(*args, **kwds):
@ -45,5 +48,18 @@ class Playlist(LastfmBase):
def __repr__(self):
return "<lastfm.Playlist: %s>" % self.url
from error import LastfmInvalidParametersError
import StringIO
import sys
from error import LastfmInvalidParametersError
if sys.version.startswith('2.5'):
import xml.etree.cElementTree as ElementTree
else:
try:
import cElementTree as ElementTree
except ImportError:
try:
import ElementTree
except ImportError:
raise LastfmError("Install ElementTree package for using python-lastfm")

View File

@ -163,6 +163,11 @@ class Tag(LastfmBase):
"""top track for the tag"""
pass
@LastfmBase.cachedProperty
def playlist(self):
return Playlist.fetch(self.__api,
"lastfm://playlist/tag/%s/freetracks" % self.name)
@staticmethod
def getTopTags(api):
params = {'method': 'tag.getTopTags'}
@ -240,5 +245,6 @@ from album import Album
from api import Api
from artist import Artist
from error import LastfmInvalidParametersError
from playlist import Playlist
from stats import Stats
from track import Track

View File

@ -61,6 +61,6 @@ class Tasteometer(object):
def __repr__(self):
return "<lastfm.Tasteometer>"
return "<lastfm.Tasteometer: %s%% match>" % (self.score*100)
from artist import Artist

View File

@ -6,6 +6,7 @@ __license__ = "GNU Lesser General Public License"
from base import LastfmBase
from lazylist import lazylist
import playlist
class User(LastfmBase):
"""A class representing an user."""
@ -141,10 +142,27 @@ class User(LastfmBase):
"""nearest neightbour of the user"""
pass
@property
@LastfmBase.cachedProperty
def playlists(self):
"""playlists of the user"""
pass
params = {'method': 'user.getPlaylists', 'user': self.name}
data = self.__api._fetchData(params).find('playlists')
return [
User.Playlist(
self.__api,
id = int(p.findtext('id')),
title = p.findtext('title'),
date = datetime(*(
time.strptime(
p.findtext('date').strip(),
'%Y-%m-%dT%H:%M:%S'
)[0:6])
),
size = int(p.findtext('size')),
creator = self
)
for p in data.findall('playlist')
]
@LastfmBase.cachedProperty
def lovedTracks(self):
@ -451,6 +469,11 @@ class User(LastfmBase):
pass
return gen()
def compare(self, other, limit = None):
return Tasteometer.compare(self.__api,
'user', 'user',
self.name, other.name,
limit)
@property
def library(self):
return self.__lirary
@ -474,6 +497,49 @@ class User(LastfmBase):
def __repr__(self):
return "<lastfm.User: %s>" % self.name
class Playlist(playlist.Playlist):
"""A class representing a playlist belonging to the user."""
def init(self, api, id, title, date, size, creator):
super(User.Playlist, self).init(api, "lastfm://playlist/%s" % id)
self.__id = id
self.__title = title
self.__date = date
self.__size = size
self.__creator = creator
@property
def id(self):
return self.__id
@property
def title(self):
return self.__title
@property
def date(self):
return self.__date
@property
def size(self):
return self.__size
@property
def creator(self):
return self.__creator
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['id'])
except KeyError:
raise LastfmInvalidParametersError("id has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(id = self.id)
def __repr__(self):
return "<lastfm.User.Playlist: %s>" % self.title
class Library(object):
"""A class representing the music library of the user."""
def __init__(self, api, user):
@ -649,5 +715,6 @@ from error import LastfmError, LastfmInvalidParametersError
from event import Event
from stats import Stats
from tag import Tag
from tasteometer import Tasteometer
from track import Track
from weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart