diff --git a/dist/lastfm-0.1-py2.5.egg b/dist/lastfm-0.1-py2.5.egg index a507993..62e906b 100644 Binary files a/dist/lastfm-0.1-py2.5.egg and b/dist/lastfm-0.1-py2.5.egg differ diff --git a/dist/lastfm-0.1.tar.gz b/dist/lastfm-0.1.tar.gz new file mode 100644 index 0000000..37ecc9e Binary files /dev/null and b/dist/lastfm-0.1.tar.gz differ diff --git a/dist/lastfm-0.1.win32-py2.5.msi b/dist/lastfm-0.1.win32-py2.5.msi index 943a255..2ae74ed 100644 Binary files a/dist/lastfm-0.1.win32-py2.5.msi and b/dist/lastfm-0.1.win32-py2.5.msi differ diff --git a/dist/lastfm-0.1.zip b/dist/lastfm-0.1.zip index 71f8b0c..fb2653c 100644 Binary files a/dist/lastfm-0.1.zip and b/dist/lastfm-0.1.zip differ diff --git a/src/__init__.py b/src/__init__.py index 60f2d3d..4f02010 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -7,6 +7,7 @@ __license__ = "GNU Lesser General Public License" from base import LastfmBase from error import LastfmError from api import Api +from registry import Registry from album import Album from artist import Artist @@ -21,4 +22,4 @@ from user import User __all__ = ['LastfmError', 'Api', 'Album', 'Artist', 'Event', 'Location', 'Country', 'Group', 'Playlist', 'Tag', - 'Tasteometer', 'Track', 'User'] \ No newline at end of file + 'Tasteometer', 'Track', 'User', 'Registry'] \ No newline at end of file diff --git a/src/album.py b/src/album.py index 7885d98..59656ad 100644 --- a/src/album.py +++ b/src/album.py @@ -20,6 +20,8 @@ class Album(LastfmBase): listeners = None, playcount = None, topTags = None): + if not isinstance(api, Api): + raise LastfmError("api reference must be supplied as an argument") self.__api = api self.__name = name self.__artist = artist @@ -60,6 +62,14 @@ class Album(LastfmBase): return self.__playcount 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 name = property(getName, None, None, "Name's Docstring") @@ -81,12 +91,14 @@ class Album(LastfmBase): playcount = property(getPlaycount, None, None, "Playcount'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 def getInfo(api, artist = None, album = None, - mbid = None): + mbid = None, **kwds): params = {'method': 'album.getinfo'} if not ((artist and album) or mbid): 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')), mbid = data.findtext('mbid'), 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])), image = dict([(i.get('size'), i.text) for i in data.findall('image')]), listeners = int(data.findtext('listeners')), @@ -118,7 +130,8 @@ class Album(LastfmBase): url = t.findtext('url') ) for t in data.findall('toptags/tag') - ] + ], + **kwds ) @staticmethod def hashFunc(*args, **kwds): @@ -145,12 +158,13 @@ class Album(LastfmBase): return self.name < other.name def __repr__(self): - return "" % (self.name, self.artist.name) + return "" % (self.name, self.artist.name) from datetime import datetime import time +from api import Api from error import LastfmError from tag import Tag from artist import Artist \ No newline at end of file diff --git a/src/api.py b/src/api.py index 7a080a4..87e55df 100644 --- a/src/api.py +++ b/src/api.py @@ -125,6 +125,8 @@ class Api(object): artist = None, album = None, mbid = None): + if isinstance(artist, Artist): + artist = artist.name return Album.getInfo(self, artist, album, mbid) def getArtist(self, @@ -172,6 +174,8 @@ class Api(object): return Tasteometer(self, type1, type2, value1, value2, limit) def getTrack(self, name, artist = None): + if isinstance(artist, Artist): + artist = artist.name return Track(self, name = name, artist = artist) def searchTrack(self, @@ -179,6 +183,8 @@ class Api(object): artist = None, limit = None, page = None): + if isinstance(artist, Artist): + artist = artist.name return Track.search(self, track, artist, limit, page) def getUser(self, name): @@ -242,12 +248,14 @@ class Api(object): return data else: return xml + + def __repr__(self): + return "" % self.__apiKey import urllib import urllib2 import urlparse import time -from datetime import datetime import sys if sys.version.startswith('2.5'): import xml.etree.cElementTree as ElementTree diff --git a/src/artist.py b/src/artist.py index 07f6940..7c4a3a3 100644 --- a/src/artist.py +++ b/src/artist.py @@ -20,6 +20,8 @@ class Artist(LastfmBase): similar = None, topTags = None, bio = None): + if not isinstance(api, Api): + raise LastfmError("api reference must be supplied as an argument") self.__api = api self.__name = name self.__mbid = mbid @@ -106,8 +108,12 @@ class Artist(LastfmBase): stats = property(getStats, None, None, "Stats'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") + topTag = property(lambda self: len(self.topTags) and self.topTags[0], + None, None, "docstring") bio = property(getBio, None, None, "Bio's Docstring") @@ -159,10 +165,43 @@ class Artist(LastfmBase): events = property(getEvents, None, None, "Docstring") 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): - 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): pass @@ -230,9 +269,13 @@ class Artist(LastfmBase): @staticmethod def hashFunc(*args, **kwds): try: - return hash(kwds['name']) + return hash(kwds['name'].lower()) 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): return self.__class__.hashFunc(name = self.name) @@ -316,7 +359,10 @@ class Bio(object): from datetime import datetime import time +from api import Api +from album import Album from error import LastfmError from event import Event from geo import Country, Location, Venue from tag import Tag +from user import User diff --git a/src/base.py b/src/base.py index 4434786..ecdee5e 100644 --- a/src/base.py +++ b/src/base.py @@ -9,11 +9,16 @@ class LastfmBase(object): registry = {} - def __new__(cls, *args, **kwds): - inst, alreadyRegistered = LastfmBase.register(object.__new__(cls), - cls.hashFunc(*args, **kwds)) + def __new__(cls, *args, **kwds): + key = cls.hashFunc(*args, **kwds) + inst, alreadyRegistered = LastfmBase.register(object.__new__(cls), key) if not alreadyRegistered: inst.init(*args, **kwds) + else: + if 'bypassRegistry' in kwds: + del kwds['bypassRegistry'] + inst = object.__new__(cls) + inst.init(*args, **kwds) return inst @staticmethod @@ -21,8 +26,8 @@ class LastfmBase(object): if not ob.__class__ in LastfmBase.registry: LastfmBase.registry[ob.__class__] = {} if key in LastfmBase.registry[ob.__class__]: - #print "already registered: %s" % ob.__class__ ob = LastfmBase.registry[ob.__class__][key] + #print "already registered: %s" % repr(ob) return (ob, True) else: #print "not already registered: %s" % ob.__class__ diff --git a/src/event.py b/src/event.py index 680084b..39278df 100644 --- a/src/event.py +++ b/src/event.py @@ -23,6 +23,8 @@ class Event(LastfmBase): attendance = None, reviews = None, tag = None): + if not isinstance(api, Api): + raise LastfmError("api reference must be supplied as an argument") self.__api = api self.__id = id self.__title = title @@ -171,6 +173,7 @@ class Event(LastfmBase): from datetime import datetime import time +from api import Api from error import LastfmError from artist import Artist from geo import Venue, Location, Country \ No newline at end of file diff --git a/src/geo.py b/src/geo.py index 2f46bf2..3c5a08e 100644 --- a/src/geo.py +++ b/src/geo.py @@ -78,6 +78,8 @@ class Location(LastfmBase): latitude = None, longitude = None, timezone = None): + if not isinstance(api, Api): + raise LastfmError("api reference must be supplied as an argument") self.__api = api self.__name = name self.__city = city @@ -173,6 +175,8 @@ class Country(LastfmBase): def init(self, api, name = None): + if not isinstance(api, Api): + raise LastfmError("api reference must be supplied as an argument") self.__api = api self.__name = name @@ -216,6 +220,7 @@ class Country(LastfmBase): def __repr__(self): return "" % self.name +from api import Api from error import LastfmError \ No newline at end of file diff --git a/src/registry.py b/src/registry.py new file mode 100644 index 0000000..17a5f35 --- /dev/null +++ b/src/registry.py @@ -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 [] + diff --git a/src/tag.py b/src/tag.py index 04a919d..9e1fabb 100644 --- a/src/tag.py +++ b/src/tag.py @@ -12,6 +12,8 @@ class Tag(LastfmBase): api, name = None, url = None): + if not isinstance(api, Api): + raise LastfmError("api reference must be supplied as an argument") self.__api = api self.__name = name self.__url = url @@ -68,6 +70,7 @@ class Tag(LastfmBase): def __repr__(self): return "" % self.name +from api import Api from error import LastfmError from album import Album from artist import Artist diff --git a/src/track.py b/src/track.py index a33a41c..414924b 100644 --- a/src/track.py +++ b/src/track.py @@ -17,6 +17,8 @@ class Track(LastfmBase): artist = None, image = None, match = None): + if not isinstance(api, Api): + raise LastfmError("api reference must be supplied as an argument") self.__api = api self.__name = name self.__mbid = mbid @@ -69,7 +71,7 @@ class Track(LastfmBase): if not ((artist and track) or mbid): 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}) elif mbid: params.update({'mbid': mbid}) @@ -138,8 +140,9 @@ class Track(LastfmBase): return self.name < other.name def __repr__(self): - return "" % (self.name, self.artist.name) - + return "" % (self.name, self.artist.name) + +from api import Api from error import LastfmError from user import User from tag import Tag \ No newline at end of file diff --git a/src/user.py b/src/user.py index aa38d35..590ad3d 100644 --- a/src/user.py +++ b/src/user.py @@ -8,15 +8,19 @@ from base import LastfmBase class User(LastfmBase): """A class representing an user.""" - def __init__(self, + def init(self, api, name = 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.__name = name self.__url = url self.__image = image + self.__weight = weight def getName(self): return self.__name @@ -27,12 +31,17 @@ class User(LastfmBase): def getImage(self): return self.__image + def getWeight(self): + return self.__weight + name = property(getName, None, None, "Name's Docstring") url = property(getUrl, None, None, "Url's Docstring") image = property(getImage, None, None, "Image's Docstring") + weight = property(getWeight, None, None, "Weight's Docstring") + def getEvents(self): pass @@ -130,5 +139,6 @@ class User(LastfmBase): def __repr__(self): return "" % self.name - + +from api import Api from error import LastfmError \ No newline at end of file