implemented some methods in user.py. refactored some properties as LastfmBase.topProperty.

master
Abhinav Sarkar 2008-08-21 13:39:12 +00:00
parent e21be6a3ed
commit 054fc8eeb3
9 changed files with 216 additions and 106 deletions

View File

@ -110,10 +110,10 @@ class Album(LastfmBase):
]
return self.__topTags
@property
@LastfmBase.topProperty("topTags")
def topTag(self):
"""top tag for the album"""
return (self.topTags and len(self.topTags) and self.topTags[0] or None)
pass
@staticmethod
def _fetchData(api,

View File

@ -195,7 +195,14 @@ class Api(object):
return Track.search(self, track, artist, limit, page)
def getUser(self, name):
return User(self, name = name)
user = None
try:
user = User(self, name = name)
user.friends
except LastfmError, e:
raise e
return user
def _fetchUrl(self,
url,
@ -245,9 +252,12 @@ class Api(object):
# Always return the latest version
return url_data
def _fetchData(self, params, parse = True):
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)
xml = self._fetchUrl(Api.API_ROOT_URL, params, no_cache = self._no_cache or no_cache)
#print xml
try:
data = ElementTree.XML(xml)

View File

@ -88,10 +88,7 @@ class Artist(LastfmBase):
return self.__stats
def getSimilar(self, limit = None):
params = {
'method': 'artist.getsimilar',
'artist': self.__name
}
params = {'method': 'artist.getsimilar', 'artist': self.__name}
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetchData(params).find('similarartists')
@ -118,10 +115,10 @@ class Artist(LastfmBase):
return self.getSimilar()
return self.__similar
@property
@LastfmBase.topProperty("similar")
def mostSimilar(self):
"""artist most similar to this artist"""
return (len(self.similar) and self.similar[0] or None)
pass
@property
def topTags(self):
@ -142,10 +139,10 @@ class Artist(LastfmBase):
]
return self.__topTags
@property
@LastfmBase.topProperty("topTags")
def topTag(self):
"""top tag for the artist"""
return (len(self.topTags) and self.topTags[0] or None)
pass
@property
def bio(self):
@ -192,10 +189,10 @@ class Artist(LastfmBase):
]
return self.__topAlbums
@property
@LastfmBase.topProperty("topAlbums")
def topAlbum(self):
"""top album of the artist"""
return (len(self.topAlbums) and self.topAlbums[0] or None)
pass
@property
def topFans(self):
@ -218,10 +215,10 @@ class Artist(LastfmBase):
]
return self.__topFans
@property
@LastfmBase.topProperty("topFans")
def topFan(self):
"""top fan of the artist"""
return (len(self.topFans) and self.topFans[0] or None)
pass
@property
def topTracks(self):
@ -248,9 +245,10 @@ class Artist(LastfmBase):
]
return self.__topTracks
@property
@LastfmBase.topProperty("topTracks")
def topTrack(self):
return (len(self.topTracks) and self.topTracks[0] or None)
"""topmost fan of the artist"""
pass
@staticmethod
def search(api,
@ -415,7 +413,6 @@ from album import Album
from api import Api
from error import LastfmError
from event import Event
from geo import Country, Location, Venue
from search import SearchResult
from stats import Stats
from tag import Tag

View File

@ -44,6 +44,16 @@ class LastfmBase(object):
#print "not already registered: %s" % ob.__class__
LastfmBase.registry[ob.__class__][key] = ob
return (ob, False)
@staticmethod
def topProperty(listPropertyName):
def top(func):
def wrapper(ob):
topList = getattr(ob, listPropertyName)
return (len(topList) and topList[0] or None)
return property(fget = wrapper, doc = func.__doc__)
return top
def __gt__(self, other):
return not (self.__lt__(other) or self.__eq(other))

View File

@ -23,7 +23,7 @@ class Geo(object):
totalResults = int(data.attrib['total']),
itemsPerPage = int(math.ceil(float(data.attrib['total']))/float(data.attrib['totalpages'])),
matches = [
Event.createFromData(self.__api, e)
Event.createFromData(api, e)
for e in data.findall('event')
]
)
@ -145,6 +145,7 @@ class Location(LastfmBase):
self.__latitude = latitude
self.__longitude = longitude
self.__timezone = timezone
self.__events = None
@property
def name(self):
@ -194,7 +195,9 @@ class Location(LastfmBase):
@property
def events(self):
"""events taking place at/around the location"""
return self.getEvents()
if self.__events is None:
self.__events = self.getEvents()
return self.__events
@staticmethod
def hashFunc(*args, **kwds):
@ -238,6 +241,8 @@ class Country(LastfmBase):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api
self.__name = name
self.__topArtists = None
self.__topTracks = None
@property
def name(self):
@ -247,22 +252,26 @@ class Country(LastfmBase):
@property
def topArtists(self):
"""top artists of the country"""
return Geo.getTopArtists(self.__api, self.name)
if self.__topArtists is None:
self.__topArtists = Geo.getTopArtists(self.__api, self.name)
return self.__topArtists
@property
@LastfmBase.topProperty("topArtists")
def topArtist(self):
"""top artist of the country"""
return (len(self.topArtists) and self.topArtists[0] or None)
pass
@property
def topTracks(self):
"""top tracks of the country"""
return Geo.getTopTracks(self.__api, self.name)
if self.__topTracks is None:
self.__topTracks = Geo.getTopTracks(self.__api, self.name)
return self.__topTracks
@property
@LastfmBase.topProperty("topTracks")
def topTrack(self):
"""top track of the country"""
return (len(self.topTracks) and self.topTracks[0] or None)
pass
@staticmethod
def hashFunc(*args, **kwds):
@ -283,9 +292,7 @@ class Country(LastfmBase):
def __repr__(self):
return "<lastfm.geo.Country: %s>" % self.name
from datetime import datetime
import math
import time
from api import Api
from artist import Artist

View File

@ -4,6 +4,8 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
class SearchResult(object):
"""A class to represent a search result"""
xmlns = "http://a9.com/-/spec/opensearch/1.1/"
@ -58,11 +60,10 @@ class SearchResult(object):
"""match result of the search"""
return self.__matches
@property
@LastfmBase.topProperty("matches")
def topMatch(self):
return (len(self.matches) and self.matches[0] or None)
"""top match for the search"""
pass
def __repr__(self):
return "<lastfm.SearchResult: for %s '%s'>" % (self.type, self.searchTerms)
from error import LastfmError
return "<lastfm.SearchResult: for %s '%s'>" % (self.type, self.searchTerms)

View File

@ -65,6 +65,11 @@ class Tag(LastfmBase):
]
return self.__similar
@LastfmBase.topProperty("similar")
def mostSimilar(self):
"""most similar tag to this tag"""
pass
@property
def topAlbums(self):
"""top albums for the tag"""
@ -94,10 +99,10 @@ class Tag(LastfmBase):
]
return self.__topAlbums
@property
@LastfmBase.topProperty("topAlbums")
def topAlbum(self):
"""top album for the tag"""
return (len(self.topAlbums) and self.topAlbums[0] or None)
pass
@property
def topArtists(self):
@ -123,10 +128,10 @@ class Tag(LastfmBase):
]
return self.__topArtists
@property
@LastfmBase.topProperty("topArtists")
def topArtist(self):
"""top artist for the tag"""
return (len(self.topArtists) and self.topArtists[0] or None)
pass
@property
def topTracks(self):
@ -158,9 +163,10 @@ class Tag(LastfmBase):
]
return self.__topTracks
@property
@LastfmBase.topProperty("")
def topTrack(self):
return (len(self.topTracks) and self.topTracks[0] or None)
"""top track for the tag"""
pass
@staticmethod
def getTopTags(api):

View File

@ -15,6 +15,7 @@ class Track(LastfmBase):
url = None,
streamable = None,
artist = None,
album = None,
image = None,
stats = None,
fullTrack = None,
@ -28,6 +29,7 @@ class Track(LastfmBase):
self.__url = url
self.__streamable = streamable
self.__artist = artist
self.__album = album
self.__image = image
self.__stats = stats and Stats(
subject = self,
@ -68,6 +70,11 @@ class Track(LastfmBase):
"""artist of the track"""
return self.__artist
@property
def album(self):
"""artist of the track"""
return self.__album
@property
def image(self):
"""image of the track's album cover"""
@ -141,10 +148,10 @@ class Track(LastfmBase):
]
return self.__similar
@property
@LastfmBase.topProperty("similar")
def mostSimilar(self):
"""track most similar to this track"""
return (len(self.similar) and self.similar[0] or None)
pass
@property
def topFans(self):
@ -172,9 +179,10 @@ class Track(LastfmBase):
]
return self.__topFans
@property
@LastfmBase.topProperty("topFans")
def topFan(self):
return (len(self.topFans) and self.topFans[0] or None)
"""topmost fan of the track"""
pass
@property
def topTags(self):
@ -201,9 +209,10 @@ class Track(LastfmBase):
]
return self.__topTags
@property
@LastfmBase.topProperty("topTags")
def topTag(self):
return (len(self.topTags) and self.topTags[0] or None)
"""topmost tag for the track"""
pass
@staticmethod
def search(api,

View File

@ -13,8 +13,7 @@ class User(LastfmBase):
name = None,
url = None,
image = None,
stats = None,
mostRecentTrack = None):
stats = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api
@ -29,8 +28,12 @@ class User(LastfmBase):
self.__events = None
self.__pastEvents = None
self.__friends = None
self.__neighbours = None
self.__lovedTracks = None
self.__mostRecentTrack = mostRecentTrack
self.__topAlbums = None
self.__topArtists = None
self.__topTracks = None
self.__topTags = None
@property
def name(self):
@ -64,59 +67,42 @@ class User(LastfmBase):
]
return self.__events
def getPastEvents(self,
page = None,
limit = None):
params = {'method': 'user.getpastevents', 'user': self.name}
if page is not None:
params.update({'page': page})
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetchData(params).find('events')
return [
Event.createFromData(self.__api, e)
for e in data.findall('event')
]
@property
def pastEvents(self):
if self.__pastEvents is None:
params = {'method': 'user.getpastevents', 'user': self.name}
data = self.__api._fetchData(params).find('events')
self.__pastEvents = [
Event.createFromData(self.__api, e)
for e in data.findall('event')
]
self.__pastEvents = self.getPastEvents()
return self.__pastEvents
def getFriends(self,
recentTrack = False,
limit = None):
params = {'method': 'user.getfriends', 'user': self.name}
if recentTrack:
params.update({'recenttracks': 'true'})
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetchData(params).find('friends')
if recentTrack:
return [
User(
self.__api,
name = u.findtext('name'),
image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
url = u.findtext('url'),
mostRecentTrack = Track(
self.__api,
name = u.findtext('recenttrack/name'),
mbid = u.findtext('recenttrack/mbid'),
url = u.findtext('recenttrack/url'),
artist = Artist(
self.__api,
name = u.findtext('recenttrack/artist/name'),
mbid = u.findtext('recenttrack/artist/mbid'),
url = u.findtext('recenttrack/artist/url'),
),
),
)
for u in data.findall('user')
]
else:
return [
User(
self.__api,
name = u.findtext('name'),
image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
url = u.findtext('url'),
)
for u in data.findall('user')
]
return [
User(
self.__api,
name = u.findtext('name'),
image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
url = u.findtext('url'),
)
for u in data.findall('user')
]
@property
@ -127,13 +113,36 @@ class User(LastfmBase):
return self.__friends
def getNeighbours(self, limit = None):
pass
params = {'method': 'user.getneighbours', 'user': self.name}
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetchData(params).find('neighbours')
return [
User(
self.__api,
name = u.findtext('name'),
image = {'medium': u.findtext('image')},
url = u.findtext('url'),
stats = Stats(
subject = u.findtext('name'),
match = float(u.findtext('match')),
),
)
for u in data.findall('user')
]
@property
def neighbours(self):
"""neightbours of the user"""
return self.getNeighbours()
"""neighbours of the user"""
if self.__neighbours is None:
self.__neighbours = self.getNeighbours()
return self.__neighbours
@LastfmBase.topProperty("neighbours")
def nearestNeighbour(self):
"""nearest neightbour of the user"""
pass
@property
def playlists(self):
"""playlists of the user"""
@ -168,30 +177,90 @@ class User(LastfmBase):
return self.__lovedTracks
def getRecentTracks(self, limit = None):
pass
params = {'method': 'user.getrecenttracks', 'user': self.name}
data = self.__api._fetchData(params, no_cache = True).find('recenttracks')
return [
Track(
self.__api,
name = t.findtext('name'),
artist = Artist(
self.__api,
name = t.findtext('artist'),
mbid = t.find('artist').attrib['mbid'],
),
album = Album(
self.__api,
name = t.findtext('album'),
artist = Artist(
self.__api,
name = t.findtext('artist'),
mbid = t.find('artist').attrib['mbid'],
),
mbid = t.find('album').attrib['mbid'],
),
mbid = t.findtext('mbid'),
streamable = (t.findtext('streamable') == '1'),
url = t.findtext('url'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
playedOn = datetime(*(
time.strptime(
t.findtext('date').strip(),
'%d %b %Y, %H:%M'
)[0:6])
)
)
for t in data.findall('track')
]
@property
def recentTracks(self):
"""recent tracks played by the user"""
return self.getRecentTracks()
@property
@LastfmBase.topProperty("recentTracks")
def mostRecentTrack(self):
"""most recent track played by the user"""
return (len(self.recentTracks) and self.recentTracks[0] or None)
pass
def getTopAlbums(self, period = None):
pass
params = {'method': 'user.gettopalbums', 'user': self.name}
if period is not None:
params.update({'period': period})
data = self.__api._fetchData(params).find('topalbums')
return [
Album(
self.__api,
name = a.findtext('name'),
artist = Artist(
self.__api,
name = a.findtext('artist/name'),
mbid = a.findtext('artist/mbid'),
url = a.findtext('artist/url'),
),
mbid = a.findtext('mbid'),
url = a.findtext('url'),
image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
stats = Stats(
subject = a.findtext('name'),
playcount = int(a.findtext('playcount')),
rank = int(a.attrib['rank'])
)
)
for a in data.findall('album')
]
@property
def topAlbums(self):
"""top albums of the user"""
return self.getTopAlbums()
@property
"""overall top albums of the user"""
if self.__topAlbums is None:
self.__topAlbums = self.getTopAlbums()
return self.__topAlbums
@LastfmBase.topProperty("topAlbums")
def topAlbum(self):
"""top album fo the user"""
return (len(self.topAlbums) and self.topAlbums[0] or None)
"""overall top most album of the user"""
pass
def getTopArtists(self, period = None):
pass
@ -287,6 +356,7 @@ import time
from api import Api
from artist import Artist
from album import Album
from error import LastfmError
from event import Event
from stats import Stats