From 4646a6cac0b68b47285165ae0a8c32dd2e630cea Mon Sep 17 00:00:00 2001 From: Abhinav Sarkar Date: Sun, 17 Aug 2008 18:42:32 +0000 Subject: [PATCH] tag, tasteometer and track module are now complete --- src/api.py | 2 +- src/artist.py | 4 +- src/tag.py | 56 ++++++++++++++++-- src/tasteometer.py | 26 ++++++++- src/track.py | 143 ++++++++++++++++++++++++++++++++++++--------- 5 files changed, 197 insertions(+), 34 deletions(-) diff --git a/src/api.py b/src/api.py index ecf66e6..9c4d156 100644 --- a/src/api.py +++ b/src/api.py @@ -175,7 +175,7 @@ class Api(object): type1, type2, value1, value2, limit = None): - return Tasteometer(self, type1, type2, value1, value2, limit) + return Tasteometer.compare(self, type1, type2, value1, value2, limit) def getTrack(self, name, artist = None): if isinstance(artist, Artist): diff --git a/src/artist.py b/src/artist.py index 955cf53..8637ed3 100644 --- a/src/artist.py +++ b/src/artist.py @@ -114,7 +114,9 @@ class Artist(LastfmBase): @property def similar(self): """artists similar to this artist""" - return self.getSimilar() + if self.__similar is None: + return self.getSimilar() + return self.__similar @property def mostSimilar(self): diff --git a/src/tag.py b/src/tag.py index e270d06..d826043 100644 --- a/src/tag.py +++ b/src/tag.py @@ -12,13 +12,18 @@ class Tag(LastfmBase): api, name = None, url = None, - streamable = None): + streamable = None, + stats = 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.__streamable = streamable + self.__stats = stats and Stats( + subject = self, + count = stats.count + ) self.__similar = None self.__topAlbums = None self.__topArtists = None @@ -39,6 +44,10 @@ class Tag(LastfmBase): """is the tag streamable""" return self.__streamable + @property + def stats(self): + return self.__stats + @property def similar(self): """tags similar to this tag""" @@ -155,14 +164,52 @@ class Tag(LastfmBase): @staticmethod def getTopTags(api): - pass + params = {'method': 'tag.getTopTags'} + data = api._fetchData(params).find('toptags') + return [ + Tag( + api, + name = t.findtext('name'), + url = t.findtext('url'), + stats = Stats( + subject = t.findtext('name'), + count = int(t.findtext('count')), + ) + ) + for t in data.findall('tag') + ] @staticmethod def search(api, tag, limit = None, page = None): - pass + params = {'method': 'tag.search', 'tag': tag} + if limit: + params.update({'limit': limit}) + if page: + params.update({'page': page}) + data = api._fetchData(params).find('results') + return SearchResult( + type = 'tag', + searchTerms = data.find("{%s}Query" % SearchResult.xmlns).attrib['searchTerms'], + startPage = int(data.find("{%s}Query" % SearchResult.xmlns).attrib['startPage']), + totalResults = int(data.findtext("{%s}totalResults" % SearchResult.xmlns)), + startIndex = int(data.findtext("{%s}startIndex" % SearchResult.xmlns)), + itemsPerPage = int(data.findtext("{%s}itemsPerPage" % SearchResult.xmlns)), + matches = [ + Tag( + api, + name = t.findtext('name'), + url = t.findtext('url'), + stats = Stats( + subject = t.findtext('name'), + count = int(t.findtext('count')), + ) + ) + for t in data.findall('tagmatches/tag') + ] + ) @staticmethod def hashFunc(*args, **kwds): @@ -188,4 +235,5 @@ from error import LastfmError from album import Album from artist import Artist from track import Track -from stats import Stats \ No newline at end of file +from stats import Stats +from search import SearchResult \ No newline at end of file diff --git a/src/tasteometer.py b/src/tasteometer.py index f3d3fe5..8f284c5 100644 --- a/src/tasteometer.py +++ b/src/tasteometer.py @@ -34,7 +34,31 @@ class Tasteometer(object): type1, type2, value1, value2, limit = None): - pass + params = { + 'method': 'tasteometer.compare', + 'type1': type1, + 'type2': type2, + 'value1': value1, + 'value2': value2 + } + if limit is not None: + params.update({'limit': limit}) + data = api._fetchData(params).find('comparison/result') + return Tasteometer( + score = float(data.findtext('score')), + matches = int(data.find('artists').attrib['matches']), + artists = [ + Artist( + api, + name = a.findtext('name'), + url = a.findtext('url'), + image = dict([(i.get('size'), i.text) for i in a.findall('image')]), + ) + for a in data.findall('artists/artist') + ] + ) + + def __repr__(self): return "" diff --git a/src/track.py b/src/track.py index 08823b1..d095888 100644 --- a/src/track.py +++ b/src/track.py @@ -31,9 +31,13 @@ class Track(LastfmBase): subject = self, match = stats.match, playcount = stats.playcount, - rank = stats.rank + rank = stats.rank, + listeners = stats.listeners, ) self.__fullTrack = fullTrack + self.__similar = None + self.__topFans = None + self.__topTags = None @property def name(self): @@ -89,50 +93,99 @@ class Track(LastfmBase): params.update({'mbid': mbid}) return params - def getSimilar(self, - artist = None, - track = None, - mbid = None): - params = self.__checkParams({'method': 'track.getsimilar'}, artist, track, mbid) - data = self.__api._fetchData(params).find('similartracks') - @property def similar(self): """tracks similar to this track""" - return self.getSimilar() + if self.__similar is None: + params = self.__checkParams( + {'method': 'track.getsimilar'}, + self.artist.name, + self.name, + self.mbid + ) + data = self.__api._fetchData(params).find('similartracks') + self.__similar = [ + Track( + self.__api, + name = t.findtext('name'), + artist = Artist( + self.__api, + name = t.findtext('artist/name'), + mbid = t.findtext('artist/mbid'), + url = t.findtext('artist/url') + ), + mbid = t.findtext('mbid'), + stats = Stats( + subject = t.findtext('name'), + match = float(t.findtext('match')) + ), + streamable = (t.findtext('streamable') == '1'), + fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'), + image = dict([(i.get('size'), i.text) for i in t.findall('image')]), + ) + for t in data.findall('track') + ] + return self.__similar @property def mostSimilar(self): """track most similar to this track""" return (len(self.similar) and self.similar[0] or None) - def getTopFans(self, - artist = None, - track = None, - mbid = None): - params = self.__checkParams({'method': 'track.gettopfans'}, artist, track, mbid) - data = self.__api._fetchData(params).find('topfans') - @property def topFans(self): """top fans of the track""" - return self.getTopFans() + if self.__topFans is None: + params = self.__checkParams( + {'method': 'track.gettopfans'}, + self.artist.name, + self.name, + self.mbid + ) + data = self.__api._fetchData(params).find('topfans') + self.__topFans = [ + User( + self.__api, + name = u.findtext('name'), + url = u.findtext('url'), + image = dict([(i.get('size'), i.text) for i in u.findall('image')]), + stats = Stats( + subject = u.findtext('name'), + weight = int(u.findtext('weight')) + ) + ) + for u in data.findall('user') + ] + return self.__topFans @property def topFan(self): return (len(self.topFans) and self.topFans[0] or None) - def getTopTags(self, - artist = None, - track = None, - mbid = None): - params = self.__checkParams({'method': 'track.gettoptags'}, artist, track, mbid) - data = self.__api._fetchData(params).find('toptags') - @property def topTags(self): """top tags for the track""" - return self.getTopTags() + if self.__topTags is None: + params = self.__checkParams( + {'method': 'track.gettoptags'}, + self.artist.name, + self.name, + self.mbid + ) + data = self.__api._fetchData(params).find('toptags') + self.__topTags = [ + Tag( + self.__api, + name = t.findtext('name'), + url = t.findtext('url'), + stats = Stats( + subject = t.findtext('name'), + count = int(t.findtext('count')), + ) + ) + for t in data.findall('tag') + ] + return self.__topTags @property def topTag(self): @@ -144,7 +197,41 @@ class Track(LastfmBase): artist = None, limit = None, page = None): - pass + params = {'method': 'track.search', 'track': track} + if artist is not None: + params.update({'artist': artist}) + if limit is not None: + params.update({'limit': limit}) + if page is not None: + params.update({'page': page}) + data = api._fetchData(params).find('results') + return SearchResult( + type = 'track', + searchTerms = data.find("{%s}Query" % SearchResult.xmlns).attrib['searchTerms'], + startPage = int(data.find("{%s}Query" % SearchResult.xmlns).attrib['startPage']), + totalResults = int(data.findtext("{%s}totalResults" % SearchResult.xmlns)), + startIndex = int(data.findtext("{%s}startIndex" % SearchResult.xmlns)), + itemsPerPage = int(data.findtext("{%s}itemsPerPage" % SearchResult.xmlns)), + matches = [ + Track( + api, + name = t.findtext('name'), + artist = Artist( + api, + name = t.findtext('artist') + ), + url = t.findtext('url'), + stats = Stats( + subject = t.findtext('name'), + listeners = int(t.findtext('listeners')) + ), + streamable = (t.findtext('streamable') == '1'), + fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'), + image = dict([(i.get('size'), i.text) for i in t.findall('image')]), + ) + for t in data.findall('trackmatches/track') + ] + ) @staticmethod def hashFunc(*args, **kwds): @@ -175,4 +262,6 @@ from api import Api from error import LastfmError from user import User from tag import Tag -from stats import Stats \ No newline at end of file +from stats import Stats +from artist import Artist +from search import SearchResult \ No newline at end of file