Abhinav Sarkar 2008-07-16 13:06:42 +00:00
parent 0127a84744
commit bdf12b8152
16 changed files with 156 additions and 20 deletions

Binary file not shown.

BIN
dist/lastfm-0.1.tar.gz vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
dist/lastfm-0.1.zip vendored

Binary file not shown.

View File

@ -7,6 +7,7 @@ __license__ = "GNU Lesser General Public License"
from base import LastfmBase from base import LastfmBase
from error import LastfmError from error import LastfmError
from api import Api from api import Api
from registry import Registry
from album import Album from album import Album
from artist import Artist from artist import Artist
@ -21,4 +22,4 @@ from user import User
__all__ = ['LastfmError', 'Api', 'Album', 'Artist', 'Event', __all__ = ['LastfmError', 'Api', 'Album', 'Artist', 'Event',
'Location', 'Country', 'Group', 'Playlist', 'Tag', 'Location', 'Country', 'Group', 'Playlist', 'Tag',
'Tasteometer', 'Track', 'User'] 'Tasteometer', 'Track', 'User', 'Registry']

View File

@ -20,6 +20,8 @@ class Album(LastfmBase):
listeners = None, listeners = None,
playcount = None, playcount = None,
topTags = None): topTags = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__artist = artist self.__artist = artist
@ -60,6 +62,14 @@ class Album(LastfmBase):
return self.__playcount return self.__playcount
def getTopTags(self): def getTopTags(self):
if self.__topTags is None:
self.__topTags = Album.getInfo(
self.__api,
self.artist.name,
self.name,
self.mbid,
bypassRegistry = True
).topTags
return self.__topTags return self.__topTags
name = property(getName, None, None, "Name's Docstring") name = property(getName, None, None, "Name's Docstring")
@ -81,12 +91,14 @@ class Album(LastfmBase):
playcount = property(getPlaycount, None, None, "Playcount's Docstring") playcount = property(getPlaycount, None, None, "Playcount's Docstring")
topTags = property(getTopTags, None, None, "TopTags's Docstring") topTags = property(getTopTags, None, None, "TopTags's Docstring")
topTag = property(lambda self: self.topTags and len(self.topTags) and self.topTags[0],
None, None, "docstring")
@staticmethod @staticmethod
def getInfo(api, def getInfo(api,
artist = None, artist = None,
album = None, album = None,
mbid = None): mbid = None, **kwds):
params = {'method': 'album.getinfo'} params = {'method': 'album.getinfo'}
if not ((artist and album) or mbid): if not ((artist and album) or mbid):
raise LastfmError("either (artist and album) or mbid has to be given as argument.") raise LastfmError("either (artist and album) or mbid has to be given as argument.")
@ -106,7 +118,7 @@ class Album(LastfmBase):
id = int(data.findtext('id')), id = int(data.findtext('id')),
mbid = data.findtext('mbid'), mbid = data.findtext('mbid'),
url = data.findtext('url'), url = data.findtext('url'),
releaseDate = data.findtext('releasedate') and releaseDate = data.findtext('releasedate') and data.findtext('releasedate').strip() and
datetime(*(time.strptime(data.findtext('releasedate').strip(), '%d %b %Y, 00:00')[0:6])), datetime(*(time.strptime(data.findtext('releasedate').strip(), '%d %b %Y, 00:00')[0:6])),
image = dict([(i.get('size'), i.text) for i in data.findall('image')]), image = dict([(i.get('size'), i.text) for i in data.findall('image')]),
listeners = int(data.findtext('listeners')), listeners = int(data.findtext('listeners')),
@ -118,7 +130,8 @@ class Album(LastfmBase):
url = t.findtext('url') url = t.findtext('url')
) )
for t in data.findall('toptags/tag') for t in data.findall('toptags/tag')
] ],
**kwds
) )
@staticmethod @staticmethod
def hashFunc(*args, **kwds): def hashFunc(*args, **kwds):
@ -145,12 +158,13 @@ class Album(LastfmBase):
return self.name < other.name return self.name < other.name
def __repr__(self): def __repr__(self):
return "<lastfm.Album: %s by %s>" % (self.name, self.artist.name) return "<lastfm.Album: '%s' by %s>" % (self.name, self.artist.name)
from datetime import datetime from datetime import datetime
import time import time
from api import Api
from error import LastfmError from error import LastfmError
from tag import Tag from tag import Tag
from artist import Artist from artist import Artist

View File

@ -125,6 +125,8 @@ class Api(object):
artist = None, artist = None,
album = None, album = None,
mbid = None): mbid = None):
if isinstance(artist, Artist):
artist = artist.name
return Album.getInfo(self, artist, album, mbid) return Album.getInfo(self, artist, album, mbid)
def getArtist(self, def getArtist(self,
@ -172,6 +174,8 @@ class Api(object):
return Tasteometer(self, type1, type2, value1, value2, limit) return Tasteometer(self, type1, type2, value1, value2, limit)
def getTrack(self, name, artist = None): def getTrack(self, name, artist = None):
if isinstance(artist, Artist):
artist = artist.name
return Track(self, name = name, artist = artist) return Track(self, name = name, artist = artist)
def searchTrack(self, def searchTrack(self,
@ -179,6 +183,8 @@ class Api(object):
artist = None, artist = None,
limit = None, limit = None,
page = None): page = None):
if isinstance(artist, Artist):
artist = artist.name
return Track.search(self, track, artist, limit, page) return Track.search(self, track, artist, limit, page)
def getUser(self, name): def getUser(self, name):
@ -242,12 +248,14 @@ class Api(object):
return data return data
else: else:
return xml return xml
def __repr__(self):
return "<lastfm.Api: %s>" % self.__apiKey
import urllib import urllib
import urllib2 import urllib2
import urlparse import urlparse
import time import time
from datetime import datetime
import sys import sys
if sys.version.startswith('2.5'): if sys.version.startswith('2.5'):
import xml.etree.cElementTree as ElementTree import xml.etree.cElementTree as ElementTree

View File

@ -20,6 +20,8 @@ class Artist(LastfmBase):
similar = None, similar = None,
topTags = None, topTags = None,
bio = None): bio = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__mbid = mbid self.__mbid = mbid
@ -106,8 +108,12 @@ class Artist(LastfmBase):
stats = property(getStats, None, None, "Stats's Docstring") stats = property(getStats, None, None, "Stats's Docstring")
similar = property(getSimilar, None, None, "Similar's Docstring") similar = property(getSimilar, None, None, "Similar's Docstring")
mostSimilar = property(lambda self: len(self.similar) and self.similar[0],
None, None, "docstring")
topTags = property(getTopTags, None, None, "Tags's Docstring") topTags = property(getTopTags, None, None, "Tags's Docstring")
topTag = property(lambda self: len(self.topTags) and self.topTags[0],
None, None, "docstring")
bio = property(getBio, None, None, "Bio's Docstring") bio = property(getBio, None, None, "Bio's Docstring")
@ -159,10 +165,43 @@ class Artist(LastfmBase):
events = property(getEvents, None, None, "Docstring") events = property(getEvents, None, None, "Docstring")
def getTopAlbums(self): def getTopAlbums(self):
pass params = {'method': 'artist.gettopalbums', 'artist': self.name}
data = self.__api.fetchData(params).find('topalbums')
return [
Album(
self.__api,
name = a.findtext('name'),
artist = self,
mbid = a.findtext('mbid'),
url = a.findtext('url'),
image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
playcount = int(a.findtext('playcount')),
)
for a in data.findall('album')
]
topAlbums = property(getTopAlbums, None, None, "Docstring")
topAlbum = property(lambda self: len(self.topAlbums) and self.topAlbums[0],
None, None, "docstring")
def getTopFans(self): def getTopFans(self):
pass params = {'method': 'artist.gettopfans', 'artist': self.name}
data = self.__api.fetchData(params).find('topfans')
return [
User(
self.__api,
name = u.findtext('name'),
url = u.findtext('url'),
image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
weight = int(u.findtext('weight'))
)
for u in data.findall('user')
]
topFans = property(getTopFans, None, None, "Docstring")
topFan = property(lambda self: len(self.topFans) and self.topFans[0],
None, None, "docstring")
def getTopTracks(self): def getTopTracks(self):
pass pass
@ -230,9 +269,13 @@ class Artist(LastfmBase):
@staticmethod @staticmethod
def hashFunc(*args, **kwds): def hashFunc(*args, **kwds):
try: try:
return hash(kwds['name']) return hash(kwds['name'].lower())
except KeyError: except KeyError:
raise LastfmError("name has to be provided for hashing") try:
print args[1].lower()
return hash(args[1].lower())
except IndexError:
raise LastfmError("name has to be provided for hashing")
def __hash__(self): def __hash__(self):
return self.__class__.hashFunc(name = self.name) return self.__class__.hashFunc(name = self.name)
@ -316,7 +359,10 @@ class Bio(object):
from datetime import datetime from datetime import datetime
import time import time
from api import Api
from album import Album
from error import LastfmError from error import LastfmError
from event import Event from event import Event
from geo import Country, Location, Venue from geo import Country, Location, Venue
from tag import Tag from tag import Tag
from user import User

View File

@ -9,11 +9,16 @@ class LastfmBase(object):
registry = {} registry = {}
def __new__(cls, *args, **kwds): def __new__(cls, *args, **kwds):
inst, alreadyRegistered = LastfmBase.register(object.__new__(cls), key = cls.hashFunc(*args, **kwds)
cls.hashFunc(*args, **kwds)) inst, alreadyRegistered = LastfmBase.register(object.__new__(cls), key)
if not alreadyRegistered: if not alreadyRegistered:
inst.init(*args, **kwds) inst.init(*args, **kwds)
else:
if 'bypassRegistry' in kwds:
del kwds['bypassRegistry']
inst = object.__new__(cls)
inst.init(*args, **kwds)
return inst return inst
@staticmethod @staticmethod
@ -21,8 +26,8 @@ class LastfmBase(object):
if not ob.__class__ in LastfmBase.registry: if not ob.__class__ in LastfmBase.registry:
LastfmBase.registry[ob.__class__] = {} LastfmBase.registry[ob.__class__] = {}
if key in LastfmBase.registry[ob.__class__]: if key in LastfmBase.registry[ob.__class__]:
#print "already registered: %s" % ob.__class__
ob = LastfmBase.registry[ob.__class__][key] ob = LastfmBase.registry[ob.__class__][key]
#print "already registered: %s" % repr(ob)
return (ob, True) return (ob, True)
else: else:
#print "not already registered: %s" % ob.__class__ #print "not already registered: %s" % ob.__class__

View File

@ -23,6 +23,8 @@ class Event(LastfmBase):
attendance = None, attendance = None,
reviews = None, reviews = None,
tag = None): tag = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__id = id self.__id = id
self.__title = title self.__title = title
@ -171,6 +173,7 @@ class Event(LastfmBase):
from datetime import datetime from datetime import datetime
import time import time
from api import Api
from error import LastfmError from error import LastfmError
from artist import Artist from artist import Artist
from geo import Venue, Location, Country from geo import Venue, Location, Country

View File

@ -78,6 +78,8 @@ class Location(LastfmBase):
latitude = None, latitude = None,
longitude = None, longitude = None,
timezone = None): timezone = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__city = city self.__city = city
@ -173,6 +175,8 @@ class Country(LastfmBase):
def init(self, def init(self,
api, api,
name = None): name = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
@ -216,6 +220,7 @@ class Country(LastfmBase):
def __repr__(self): def __repr__(self):
return "<lastfm.geo.Country: %s" % self.name return "<lastfm.geo.Country: %s" % self.name
from api import Api
from error import LastfmError from error import LastfmError
from artist import Artist from artist import Artist
from track import Track from track import Track

View File

@ -11,6 +11,8 @@ class Group(LastfmBase):
def init(self, def init(self,
api, api,
name = None): name = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
@ -62,4 +64,5 @@ class Group(LastfmBase):
def __repr__(self): def __repr__(self):
return "<lastfm.Group: %s>" % self.name return "<lastfm.Group: %s>" % self.name
from api import Api
from error import LastfmError from error import LastfmError

35
src/registry.py Normal file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from error import LastfmError
from album import Album
from artist import Artist
from event import Event
from geo import Location, Country
from group import Group
from playlist import Playlist
from tag import Tag
from track import Track
from user import User
class Registry(dict):
"""The registry to contain all the entities"""
keys = [Album, Artist, Event, Location, Country, Group,
Playlist, Tag, Track, User]
def get(self, name):
if name not in Registry.keys:
raise LastfmError("Key does not correspond to a valid class")
else:
try:
vals = LastfmBase.registry[name].values()
vals.sort()
return vals
except KeyError:
return []

View File

@ -12,6 +12,8 @@ class Tag(LastfmBase):
api, api,
name = None, name = None,
url = None): url = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__url = url self.__url = url
@ -68,6 +70,7 @@ class Tag(LastfmBase):
def __repr__(self): def __repr__(self):
return "<lastfm.Tag: %s>" % self.name return "<lastfm.Tag: %s>" % self.name
from api import Api
from error import LastfmError from error import LastfmError
from album import Album from album import Album
from artist import Artist from artist import Artist

View File

@ -17,6 +17,8 @@ class Track(LastfmBase):
artist = None, artist = None,
image = None, image = None,
match = None): match = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__mbid = mbid self.__mbid = mbid
@ -69,7 +71,7 @@ class Track(LastfmBase):
if not ((artist and track) or mbid): if not ((artist and track) or mbid):
raise LastfmError("either (artist and track) or mbid has to be given as argument.") raise LastfmError("either (artist and track) or mbid has to be given as argument.")
if artist and album: if artist and track:
params.update({'artist': artist, 'track': track}) params.update({'artist': artist, 'track': track})
elif mbid: elif mbid:
params.update({'mbid': mbid}) params.update({'mbid': mbid})
@ -138,8 +140,9 @@ class Track(LastfmBase):
return self.name < other.name return self.name < other.name
def __repr__(self): def __repr__(self):
return "<lastfm.Track: %s by %s>" % (self.name, self.artist.name) return "<lastfm.Track: '%s' by %s>" % (self.name, self.artist.name)
from api import Api
from error import LastfmError from error import LastfmError
from user import User from user import User
from tag import Tag from tag import Tag

View File

@ -8,15 +8,19 @@ from base import LastfmBase
class User(LastfmBase): class User(LastfmBase):
"""A class representing an user.""" """A class representing an user."""
def __init__(self, def init(self,
api, api,
name = None, name = None,
url = None, url = None,
image = None): image = None,
weight = None):
if not isinstance(api, Api):
raise LastfmError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__url = url self.__url = url
self.__image = image self.__image = image
self.__weight = weight
def getName(self): def getName(self):
return self.__name return self.__name
@ -27,12 +31,17 @@ class User(LastfmBase):
def getImage(self): def getImage(self):
return self.__image return self.__image
def getWeight(self):
return self.__weight
name = property(getName, None, None, "Name's Docstring") name = property(getName, None, None, "Name's Docstring")
url = property(getUrl, None, None, "Url's Docstring") url = property(getUrl, None, None, "Url's Docstring")
image = property(getImage, None, None, "Image's Docstring") image = property(getImage, None, None, "Image's Docstring")
weight = property(getWeight, None, None, "Weight's Docstring")
def getEvents(self): def getEvents(self):
pass pass
@ -130,5 +139,6 @@ class User(LastfmBase):
def __repr__(self): def __repr__(self):
return "<lastfm.User: %s>" % self.name return "<lastfm.User: %s>" % self.name
from api import Api
from error import LastfmError from error import LastfmError