implemented the singleton pattern

This commit is contained in:
Abhinav Sarkar 2008-07-14 19:08:39 +00:00
parent 4b1217f56a
commit 7363f5cd18
13 changed files with 409 additions and 44 deletions

View File

@ -4,7 +4,9 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from error import LastfmError
from api import Api
from album import Album
from artist import Artist
@ -17,6 +19,6 @@ from tasteometer import Tasteometer
from track import Track
from user import User
__all__ = ['Album', 'Artist', 'Event', 'Location', 'Country',
'Group', 'Playlist', 'Tag', 'Tasteometer', 'Track',
'User']
__all__ = ['LastfmError', 'Api', 'Album', 'Artist', 'Event',
'Location', 'Country', 'Group', 'Playlist', 'Tag',
'Tasteometer', 'Track', 'User']

View File

@ -4,9 +4,11 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Album(object):
from base import LastfmBase
class Album(LastfmBase):
"""A class representing an album."""
def __init__(self,
def init(self,
api,
name = None,
artist = None,
@ -118,9 +120,33 @@ class Album(object):
for t in data.findall('toptags/tag')
]
)
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash("%s%s" % (kwds['name'], hash(kwds['artist'])))
except KeyError:
raise LastfmError("name and artist have to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(name = self.name, artist = self.artist)
def __eq__(self, other):
return self.id == other.id
if self.id and other.id:
return self.id == other.id
if self.mbid and other.mbid:
return self.mbid == other.mbid
if self.url and other.url:
return self.url == other.url
if (self.name and self.artist) and (other.name and other.artist):
return (self.name == other.name) and (self.artist == other.artist)
return super(Album, self).__eq__(other)
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.Album: %s by %s>" % (self.name, self.artist.name)
from datetime import datetime
import time

View File

@ -265,5 +265,5 @@ from group import Group
from playlist import Playlist
from tag import Tag
from tasteometer import Tasteometer
#from track import Track
#from user import User
from track import Track
from user import User

View File

@ -4,13 +4,16 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Artist(object):
from base import LastfmBase
class Artist(LastfmBase):
"""A class representing an artist."""
def __init__(self,
def init(self,
api,
name = None,
mbid = None,
url = None,
match = None,
image = None,
streamable = None,
stats = None,
@ -20,7 +23,8 @@ class Artist(object):
self.__api = api
self.__name = name
self.__mbid = mbid
self.___url = url
self.__url = url
self.__match = match
self.__image = image
self.__streamable = streamable
self.__stats = stats and Stats(
@ -43,6 +47,12 @@ class Artist(object):
def getMbid(self):
return self.__mbid
def getUrl(self):
return self.__url
def getMatch(self):
return self.__match
def getImage(self):
return self.__image
@ -53,10 +63,24 @@ class Artist(object):
return self.__stats
def getSimilar(self, limit = None):
if self.__similar:
return self.__similar
else:
pass
params = {
'method': 'artist.getsimilar',
'artist': self.__name}
if limit is not None:
params.update({'limit': limit})
data = self.__api.fetchData(params).find('similarartists')
self.__similar = [
Artist(
self.__api,
name = a.findtext('name'),
mbid = a.findtext('mbid'),
match = float(a.findtext('match')),
url = 'http://' + a.findtext('url'),
image = {'large': a.findtext('image')}
)
for a in data.findall('artist')
]
return self.__similar
def getTopTags(self):
if self.__topTags:
@ -70,6 +94,10 @@ class Artist(object):
name = property(getName, None, None, "Name's Docstring")
mbid = property(getMbid, None, None, "Mbid's Docstring")
url = property(getUrl, None, None, "Url's Docstring")
match = property(getMatch, None, None, "Match's Docstring")
image = property(getImage, None, None, "Image's Docstring")
@ -84,7 +112,51 @@ class Artist(object):
bio = property(getBio, None, None, "Bio's Docstring")
def getEvents(self):
pass
params = {'method': 'artist.getevents', 'artist': self.name}
data = self.__api.fetchData(params).find('events')
return [
Event(
self.__api,
id = int(e.findtext('id')),
title = e.findtext('title'),
artists = [Artist(self.__api, name = a.text) for a in e.findall('artists/artist')],
headliner = e.findtext('artists/headliner'),
venue = Venue(
name = e.findtext('venue/name'),
location = Location(
self.__api,
city = e.findtext('venue/location/city'),
country = Country(
self.__api,
name = e.findtext('venue/location/country')
),
street = e.findtext('venue/location/street'),
postalCode = e.findtext('venue/location/postalcode'),
latitude = float(e.findtext(
'venue/location/{%s}point/{%s}lat' % ((Location.xmlns,)*2)
)),
longitude = float(e.findtext(
'venue/location/{%s}point/{%s}long' % ((Location.xmlns,)*2)
)),
timezone = e.findtext('venue/location/timezone')
),
url = e.findtext('venue/url')
),
startDate = e.findtext('startDate') and
datetime(*(time.strptime(e.findtext('startDate').strip(), '%a, %d %b %Y')[0:6])) or
None,
startTime = e.findtext('startTime') and
datetime(*(time.strptime(e.findtext('startTime').strip(), '%H:%M')[0:6])) or
None,
description = e.findtext('description'),
image = dict([(i.get('size'), i.text) for i in e.findall('image')]),
url = e.findtext('url')
)
for e in data.findall('event')
]
events = property(getEvents, None, None, "Docstring")
def getTopAlbums(self):
pass
@ -136,7 +208,7 @@ class Artist(object):
)
for a in data.findall('similar/artist')
],
tags = [
topTags = [
Tag(
api,
name = t.findtext('name'),
@ -154,9 +226,29 @@ class Artist(object):
content = data.findtext('bio/content')
)
)
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise LastfmError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(name = self.name)
def __eq__(self, other):
if self.mbid and other.mbid:
return self.mbid == other.mbid
if self.url and other.url:
return self.url == other.url
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.Artist: %s>" % self.__name
class Stats(object):
"""A class representing the stats of an artist."""
@ -182,6 +274,9 @@ class Stats(object):
plays = property(getPlays, None, None, "Plays's Docstring")
artist = property(getArtist, None, None, "Artist's Docstring")
def __repr__(self):
return "<lastfm.artist.Stats: for artist '%s'>" % self.__artist.name
class Bio(object):
"""A class representing the biography of an artist."""
@ -214,10 +309,14 @@ class Bio(object):
content = property(getContent, None, None, "Content's Docstring")
artist = property(getArtist, None, None, "Artist's Docstring")
def __repr__(self):
return "<lastfm.artist.Bio: for artist '%s'>" % self.__artist.name
from datetime import datetime
import time
import types
from error import LastfmError
from event import Event
from geo import Country, Location, Venue
from tag import Tag

42
lastfm/base.py Normal file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class LastfmBase(object):
"""Base class for all the classes in this package"""
registry = {}
def __new__(cls, *args, **kwds):
inst, alreadyRegistered = LastfmBase.register(object.__new__(cls),
cls.hashFunc(*args, **kwds))
if not alreadyRegistered:
inst.init(*args, **kwds)
return inst
@staticmethod
def register(ob, key):
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]
return (ob, True)
else:
#print "not already registered: %s" % ob.__class__
LastfmBase.registry[ob.__class__][key] = ob
return (ob, False)
def __gt__(self, other):
return not (self.__lt__(other) or self.__eq(other))
def __ne__(self, other):
return not self.__eq__(other)
def __ge__(self, other):
return not self.__lt__(other)
def __le__(self, other):
return not self.__gt__(other)

View File

@ -4,9 +4,11 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Event(object):
from base import LastfmBase
class Event(LastfmBase):
"""A class representing an event."""
def __init__(self,
def init(self,
api,
id = None,
title = None,
@ -105,7 +107,7 @@ class Event(object):
def getInfo(api, event):
params = {'method': 'event.getinfo', 'event': event}
data = api.fetchData(params).find('event')
return Event(
api,
id = int(data.findtext('id')),
@ -133,8 +135,12 @@ class Event(object):
),
url = data.findtext('venue/url')
),
startDate = datetime(*(time.strptime(data.findtext('startDate').strip(), '%a, %d %b %Y')[0:6])),
startTime = datetime(*(time.strptime(data.findtext('startTime').strip(), '%H:%M')[0:6])),
startDate = data.findtext('startDate') and
datetime(*(time.strptime(data.findtext('startDate').strip(), '%a, %d %b %Y')[0:6])) or
None,
startTime = data.findtext('startTime') and
datetime(*(time.strptime(data.findtext('startTime').strip(), '%H:%M')[0:6])) or
None,
description = data.findtext('description'),
image = dict([(i.get('size'), i.text) for i in data.findall('image')]),
url = data.findtext('url'),
@ -142,8 +148,25 @@ class Event(object):
reviews = int(data.findtext('reviews')),
tag = data.findtext('tag')
)
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['id'])
except KeyError:
raise LastfmError("id has to be provided for hashing")
def __hash__(self):
return Event.hashFunc(id = self.id)
def __eq__(self, other):
return self.id == other.id
def __lt__(self, other):
return self.startDate < other.startDate
def __repr__(self):
return "<lastfm.Event: %s at %s on %s>" % (self.title, self.venue.name, self.startDate.strftime("%x"))
from datetime import datetime
import time

View File

@ -4,6 +4,8 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
class Geo(object):
"""A class representing an geographic location."""
@staticmethod
@ -18,9 +20,9 @@ class Geo(object):
def getTopTracks(api, country):
pass
class Venue(object):
class Venue(LastfmBase):
"""A class representing a venue of an event"""
def __init__(self,
def init(self,
name = None,
location = None,
url = None):
@ -43,14 +45,30 @@ class Venue(object):
url = property(getUrl, None, None, "Url's Docstring")
def __eq__(self, other):
return sefl.url == other.url
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['url'])
except KeyError:
raise LastfmError("url has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(url = self.url)
class Location(object):
def __eq__(self, other):
return self.url == other.url
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.geo.Venue: %s, %s>" % (self.name, self.location.city)
class Location(LastfmBase):
"""A class representing a location of an event"""
xmlns = "http://www.w3.org/2003/01/geo/wgs84_pos#"
def __init__(self,
def init(self,
api,
name = None,
city = None,
@ -117,12 +135,31 @@ class Location(object):
events = property(getEvents, None, None, "Event's Docstring")
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash("%s%s" % (kwds['latitude'], kwds['longitude']))
except KeyError:
raise LastfmError("latitude and longitude have to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(latitude = self.latitude, longitude = self.longitude)
def __eq__(self, other):
return self.latitude == other.latitude and self.longitude == other.longitude
class Country(object):
def __lt__(self, other):
if self.country != other.country:
return self.country < other.country
else:
return self.city < other.city
def __repr__(self):
return "<lastfm.geo.Location: (%s, %s)>" % (self.latitude, self.longitude)
class Country(LastfmBase):
"""A class representing a country."""
def __init__(self,
def init(self,
api,
name = None):
self.__api = api
@ -149,8 +186,24 @@ class Country(object):
topTrack = property(lambda self: len(self.topTracks) and self.topTracks[0],
None, None, "Docstring")
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise LastfmError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(name = self.name)
def __eq__(self, other):
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.geo.Country: %s" % self.name
from artist import Artist
from track import Track

View File

@ -4,9 +4,11 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Group(object):
from base import LastfmBase
class Group(LastfmBase):
"""A class representing a group on last.fm."""
def __init__(self,
def init(self,
api,
name = None):
self.__api = api
@ -39,4 +41,23 @@ class Group(object):
end = None):
pass
weeklyTrackChart = property(getWeeklyTrackChart, None, None, "Docstring")
weeklyTrackChart = property(getWeeklyTrackChart, None, None, "Docstring")
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise LastfmError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(name = self.name)
def __eq__(self, other):
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.Group: %s>" % self.name

View File

@ -4,12 +4,39 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Playlist(str):
from base import LastfmBase
class Playlist(LastfmBase, str):
"""A class representing an XPSF playlist."""
def __init__(self, xpsfData):
def init(self, xpsfData, playlistUrl):
self = xpsfData
self.__playlistUrl = playlistUrl
def getPlaylistUrl(self):
return self.__playlistUrl
playlistUrl = property(getPlaylistUrl, None, None, "PlaylistUrl's Docstring")
@staticmethod
def fetch(api, playlistUrl):
params = {'method': 'playlist.fetch'}
return Playlist(api.fetchData(params, parse = False))
return Playlist(api.fetchData(params, parse = False), playlistUrl)
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['playlistUrl'])
except KeyError:
raise LastfmError("playlistUrl has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(playlistUrl = self.playlistUrl)
def __eq__(self, other):
return self.playlistUrl == other.playlistUrl
def __lt__(self, other):
return self.playlistUrl < other.playlistUrl
def __repr__(self):
return "<lastfm.Playlist: %s>" % self.playlistUrl

View File

@ -4,9 +4,11 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Tag(object):
from base import LastfmBase
class Tag(LastfmBase):
""""A class representing a tag."""
def __init__(self,
def init(self,
api,
name = None,
url = None):
@ -47,6 +49,25 @@ class Tag(object):
page = None):
pass
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise LastfmError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(name = self.name)
def __eq__(self, other):
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.Tag: %s>" % self.name
from album import Album
from artist import Artist
from track import Track

View File

@ -12,7 +12,7 @@ class Tasteometer(object):
artists = None):
self.__score = score
self.__matches = matches
self.__artists = artists
self.__artists = artists#set
def getScore(self):
return self.__score
@ -35,6 +35,9 @@ class Tasteometer(object):
value1, value2,
limit = None):
pass
def __repr__(self):
return "<lastfm.Tasteometer>"
from artist import Artist
from error import LastfmError

View File

@ -4,9 +4,11 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Track(object):
from base import LastfmBase
class Track(LastfmBase):
"""A class representing a track."""
def __init__(self,
def init(self,
api,
name = None,
mbid = None,
@ -112,6 +114,31 @@ class Track(object):
limit = None,
page = None):
pass
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash("%s%s" % (kwds['name'], hash(kwds['artist'])))
except KeyError:
raise LastfmError("name and artist have to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(name = self.name, artist = self.artist)
def __eq__(self, other):
if self.mbid and other.mbid:
return self.mbid == other.mbid
if self.url and other.url:
return self.url == other.url
if (self.name and self.artist) and (other.name and other.artist):
return (self.name == other.name) and (self.artist == other.artist)
return super(Track, self).__eq__(other)
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.Track: %s by %s>" % (self.name, self.artist.name)
from error import LastfmError
from user import User

View File

@ -4,7 +4,9 @@ __author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class User(object):
from base import LastfmBase
class User(LastfmBase):
"""A class representing an user."""
def __init__(self,
api,
@ -108,4 +110,23 @@ class User(object):
end = None):
pass
weeklyTrackChart = property(getWeeklyTrackChart, None, None, "Docstring")
weeklyTrackChart = property(getWeeklyTrackChart, None, None, "Docstring")
@staticmethod
def hashFunc(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise LastfmError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hashFunc(name = self.name)
def __eq__(self, other):
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.User: %s>" % self.name