refactored out tag API methods in taggable module. applied the module to album, artist and track.

This commit is contained in:
Abhinav Sarkar 2008-10-03 11:43:37 +00:00
parent 4277b4d280
commit fc831421b7
4 changed files with 122 additions and 96 deletions

View File

@ -5,8 +5,9 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License" __license__ = "GNU Lesser General Public License"
from base import LastfmBase from base import LastfmBase
from taggable import Taggable
class Album(LastfmBase): class Album(Taggable, LastfmBase):
"""A class representing an album.""" """A class representing an album."""
def init(self, def init(self,
api, api,
@ -21,6 +22,7 @@ class Album(LastfmBase):
topTags = None): topTags = None):
if not isinstance(api, Api): if not isinstance(api, Api):
raise LastfmInvalidParametersError("api reference must be supplied as an argument") raise LastfmInvalidParametersError("api reference must be supplied as an argument")
super(self.__class__, self).init(api)
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__artist = artist self.__artist = artist
@ -118,6 +120,14 @@ class Album(LastfmBase):
def playlist(self): def playlist(self):
return Playlist.fetch(self.__api, "lastfm://playlist/album/%s" % self.id) return Playlist.fetch(self.__api, "lastfm://playlist/album/%s" % self.id)
def _defaultParams(self, extraParams = None):
if not (self.artist and self.name):
raise LastfmInvalidParametersError("artist and album have to be provided.")
params = {'artist': self.artist.name, 'album': self.name}
if extraParams is not None:
params.update(extraParams)
return params
@staticmethod @staticmethod
def _fetchData(api, def _fetchData(api,
artist = None, artist = None,

View File

@ -5,9 +5,10 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License" __license__ = "GNU Lesser General Public License"
from base import LastfmBase from base import LastfmBase
from taggable import Taggable
from lazylist import lazylist from lazylist import lazylist
class Artist(LastfmBase): class Artist(Taggable, LastfmBase):
"""A class representing an artist.""" """A class representing an artist."""
def init(self, def init(self,
api, api,
@ -22,6 +23,7 @@ class Artist(LastfmBase):
bio = None): bio = None):
if not isinstance(api, Api): if not isinstance(api, Api):
raise LastfmInvalidParametersError("api reference must be supplied as an argument") raise LastfmInvalidParametersError("api reference must be supplied as an argument")
super(self.__class__, self).init(api)
self.__api = api self.__api = api
self.__name = name self.__name = name
self.__mbid = mbid self.__mbid = mbid
@ -84,8 +86,16 @@ class Artist(LastfmBase):
self._fillInfo() self._fillInfo()
return self.__stats return self.__stats
def _defaultParams(self, extraParams = None):
if not self.name:
raise LastfmInvalidParametersError("artist has to be provided.")
params = {'artist': self.name}
if extraParams is not None:
params.update(extraParams)
return params
def getSimilar(self, limit = None): def getSimilar(self, limit = None):
params = {'method': 'artist.getSimilar', 'artist': self.__name} params = self._defaultParams({'method': 'artist.getSimilar'})
if limit is not None: if limit is not None:
params.update({'limit': limit}) params.update({'limit': limit})
data = self.__api._fetchData(params).find('similarartists') data = self.__api._fetchData(params).find('similarartists')
@ -122,10 +132,7 @@ class Artist(LastfmBase):
def topTags(self): def topTags(self):
"""top tags for the artist""" """top tags for the artist"""
if self.__topTags is None or len(self.__topTags) < 6: if self.__topTags is None or len(self.__topTags) < 6:
params = { params = self._defaultParams({'method': 'artist.getTopTags'})
'method': 'artist.getTopTags',
'artist': self.__name
}
data = self.__api._fetchData(params).find('toptags') data = self.__api._fetchData(params).find('toptags')
self.__topTags = [ self.__topTags = [
Tag( Tag(
@ -153,7 +160,7 @@ class Artist(LastfmBase):
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def events(self): def events(self):
"""events for the artist""" """events for the artist"""
params = {'method': 'artist.getEvents', 'artist': self.name} params = self._defaultParams({'method': 'artist.getEvents'})
data = self.__api._fetchData(params).find('events') data = self.__api._fetchData(params).find('events')
return [ return [
@ -164,7 +171,7 @@ class Artist(LastfmBase):
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def topAlbums(self): def topAlbums(self):
"""top albums of the artist""" """top albums of the artist"""
params = {'method': 'artist.getTopAlbums', 'artist': self.name} params = self._defaultParams({'method': 'artist.getTopAlbums'})
data = self.__api._fetchData(params).find('topalbums') data = self.__api._fetchData(params).find('topalbums')
return [ return [
@ -193,7 +200,7 @@ class Artist(LastfmBase):
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def topFans(self): def topFans(self):
"""top fans of the artist""" """top fans of the artist"""
params = {'method': 'artist.getTopFans', 'artist': self.name} params = self._defaultParams({'method': 'artist.getTopFans'})
data = self.__api._fetchData(params).find('topfans') data = self.__api._fetchData(params).find('topfans')
return [ return [
User( User(
@ -218,7 +225,7 @@ class Artist(LastfmBase):
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def topTracks(self): def topTracks(self):
"""top tracks of the artist""" """top tracks of the artist"""
params = {'method': 'artist.getTopTracks', 'artist': self.name} params = self._defaultParams({'method': 'artist.getTopTracks'})
data = self.__api._fetchData(params).find('toptracks') data = self.__api._fetchData(params).find('toptracks')
return [ return [
Track( Track(

63
src/taggable.py Normal file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
__version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from safelist import SafeList
class Taggable(object):
def init(self, api):
self.__api = api
@LastfmBase.cachedProperty
def tags(self):
from tag import Tag
params = self._defaultParams({'method': '%s.getTags' % self.__class__.__name__.lower()})
data = self.__api._fetchData(params, sign = True, session = True, no_cache = True).find('tags')
return SafeList([
Tag(
self.__api,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('tag')
],
self.addTags, self.removeTag)
def addTags(self, tags):
from tag import Tag
while(len(tags) > 10):
section = tags[0:9]
tags = tags[9:]
self.addTags(section)
if len(tags) == 0: return
tagnames = []
for tag in tags:
if isinstance(tag, Tag):
tagnames.append(tag.name)
elif isinstance(tag, str):
tagnames.append(tag)
params = self._defaultParams({
'method': '%s.addTags' % self.__class__.__name__.lower(),
'tags': ",".join(tagnames)
})
self.__api._postData(params)
self.__tags = None
def removeTag(self, tag):
from tag import Tag
if isinstance(tag, Tag):
tag = tag.name
params = self._defaultParams({
'method': '%s.removeTag' % self.__class__.__name__.lower(),
'tag': tag
})
self.__api._postData(params)
self.__tags = None

View File

@ -5,9 +5,10 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License" __license__ = "GNU Lesser General Public License"
from base import LastfmBase from base import LastfmBase
from taggable import Taggable
from lazylist import lazylist from lazylist import lazylist
class Track(LastfmBase): class Track(LastfmBase, Taggable):
"""A class representing a track.""" """A class representing a track."""
def init(self, def init(self,
api, api,
@ -27,6 +28,7 @@ class Track(LastfmBase):
wiki = None): wiki = None):
if not isinstance(api, Api): if not isinstance(api, Api):
raise LastfmInvalidParametersError("api reference must be supplied as an argument") raise LastfmInvalidParametersError("api reference must be supplied as an argument")
super(self.__class__, self).init(api)
self.__api = api self.__api = api
self.__id = id self.__id = id
self.__name = name self.__name = name
@ -141,25 +143,19 @@ class Track(LastfmBase):
if self.__wiki is None: if self.__wiki is None:
self._fillInfo() self._fillInfo()
return self.__wiki return self.__wiki
def __checkParams(self, def _defaultParams(self, extraParams = None):
params, if not (self.artist and self.name):
artist = None, raise LastfmInvalidParametersError("artist and track have to be provided.")
track = None, params = {'artist': self.artist.name, 'track': self.name}
mbid = None): if extraParams is not None:
if not ((artist and track) or mbid): params.update(extraParams)
raise LastfmInvalidParametersError("either (artist and track) or mbid has to be given as argument.")
if artist and track:
params.update({'artist': artist, 'track': track})
elif mbid:
params.update({'mbid': mbid})
return params return params
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def similar(self): def similar(self):
"""tracks similar to this track""" """tracks similar to this track"""
params = self.__checkParams( params = Track._checkParams(
{'method': 'track.getSimilar'}, {'method': 'track.getSimilar'},
self.artist.name, self.artist.name,
self.name, self.name,
@ -198,7 +194,7 @@ class Track(LastfmBase):
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def topFans(self): def topFans(self):
"""top fans of the track""" """top fans of the track"""
params = self.__checkParams( params = Track._checkParams(
{'method': 'track.getTopFans'}, {'method': 'track.getTopFans'},
self.artist.name, self.artist.name,
self.name, self.name,
@ -228,7 +224,7 @@ class Track(LastfmBase):
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def topTags(self): def topTags(self):
"""top tags for the track""" """top tags for the track"""
params = self.__checkParams( params = Track._checkParams(
{'method': 'track.getTopTags'}, {'method': 'track.getTopTags'},
self.artist.name, self.artist.name,
self.name, self.name,
@ -254,73 +250,16 @@ class Track(LastfmBase):
"""topmost tag for the track""" """topmost tag for the track"""
pass pass
@LastfmBase.cachedProperty
def tags(self):
if not (self.artist and self.name):
raise LastfmInvalidParametersError("artist and track name have to be provided.")
params = {'method': 'track.getTags', 'artist': self.artist.name, 'track': self.name}
data = self.__api._fetchData(params, sign = True, session = True, no_cache = True).find('tags')
return SafeList([
Tag(
self.__api,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('tag')
],
self.addTags, self.removeTag)
def addTags(self, tags):
while(len(tags) > 10):
section = tags[0:9]
tags = tags[9:]
self.addTags(section)
if len(tags) == 0: return
tagnames = []
for tag in tags:
if isinstance(tag, Tag):
tagnames.append(tag.name)
elif isinstance(tag, str):
tagnames.append(tag)
params = {
'method': 'track.addTags',
'artist': self.artist.name,
'track': self.name,
'tags': ",".join(tagnames)
}
self.__api._postData(params)
self.__tags = None
def removeTag(self, tag):
if isinstance(tag, Tag):
tag = tag.name
params = {
'method': 'track.removeTag',
'artist': self.artist.name,
'track': self.name,
'tag': tag
}
self.__api._postData(params)
self.__tags = None
def love(self): def love(self):
params = {'method': 'track.love', 'artist': self.artist.name, 'track': self.name} params = self._defaultParams({'method': 'track.love'})
self.__api._postData(params) self.__api._postData(params)
def ban(self): def ban(self):
params = {'method': 'track.ban', 'artist': self.artist.name, 'track': self.name} params = self._defaultParams({'method': 'track.ban'})
self.__api._postData(params) self.__api._postData(params)
def share(self, recipient, message = None): def share(self, recipient, message = None):
params = { params = self._defaultParams({'method': 'track.share'})
'method': 'track.share',
'artist': self.artist.name,
'track': self.name
}
if message is not None: if message is not None:
params['message'] = message params['message'] = message
@ -382,13 +321,7 @@ class Track(LastfmBase):
artist = None, artist = None,
track = None, track = None,
mbid = None): mbid = None):
params = {'method': 'track.getInfo'} params = Track._checkParams({'method': 'track.getInfo'}, artist, track, mbid)
if not ((artist and track) or mbid):
raise LastfmInvalidParametersError("either (artist and track) or mbid has to be given as argument.")
if artist and track:
params.update({'artist': artist, 'track': track})
elif mbid:
params.update({'mbid': mbid})
return api._fetchData(params).find('track') return api._fetchData(params).find('track')
def _fillInfo(self): def _fillInfo(self):
@ -451,6 +384,20 @@ class Track(LastfmBase):
t._fillInfo() t._fillInfo()
return t return t
@staticmethod
def _checkParams(params,
artist = None,
track = None,
mbid = None):
if not ((artist and track) or mbid):
raise LastfmInvalidParametersError("either (artist and track) or mbid has to be given as argument.")
if artist and track:
params.update({'artist': artist, 'track': track})
elif mbid:
params.update({'mbid': mbid})
return params
@staticmethod @staticmethod
def hashFunc(*args, **kwds): def hashFunc(*args, **kwds):
try: try:
@ -483,7 +430,6 @@ from api import Api
from artist import Artist from artist import Artist
from album import Album from album import Album
from error import LastfmInvalidParametersError from error import LastfmInvalidParametersError
from safelist import SafeList
from stats import Stats from stats import Stats
from tag import Tag from tag import Tag
from user import User from user import User