diff --git a/src/__init__.py b/src/__init__.py index 9be1698..3b98bbc 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/album.py b/src/album.py index 2a83bbc..b9b9f59 100644 --- a/src/album.py +++ b/src/album.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/api.py b/src/api.py index 715b49f..1dd09ef 100644 --- a/src/api.py +++ b/src/api.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/artist.py b/src/artist.py index 5a10781..8a17b17 100644 --- a/src/artist.py +++ b/src/artist.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" @@ -36,7 +36,7 @@ class Artist(LastfmBase): ) self.__similar = similar self.__topTags = topTags - self.__bio = bio and Bio( + self.__bio = bio and Artist.Bio( artist = self, published = bio.published, summary = bio.summary, @@ -323,7 +323,7 @@ class Artist(LastfmBase): ) for t in data.findall('tags/tag') ] - self.__bio = Bio( + self.__bio = Artist.Bio( self, published = datetime(*(time.strptime( data.findtext('bio/published').strip(), @@ -371,40 +371,40 @@ class Artist(LastfmBase): def __repr__(self): return "" % self.__name -class Bio(object): - """A class representing the biography of an artist.""" - def __init__(self, - artist, - published = None, - summary = None, - content = None): - self.__artist = artist - self.__published = published - self.__summary = summary - self.__content = content - - @property - def artist(self): - """artist for which the biography is""" - return self.__artist - - @property - def published(self): - """publication time of the biography""" - return self.__published - - @property - def summary(self): - """summary of the biography""" - return self.__summary - - @property - def content(self): - """content of the biography""" - return self.__content - - def __repr__(self): - return "" % self.__artist.name + class Bio(object): + """A class representing the biography of an artist.""" + def __init__(self, + artist, + published = None, + summary = None, + content = None): + self.__artist = artist + self.__published = published + self.__summary = summary + self.__content = content + + @property + def artist(self): + """artist for which the biography is""" + return self.__artist + + @property + def published(self): + """publication time of the biography""" + return self.__published + + @property + def summary(self): + """summary of the biography""" + return self.__summary + + @property + def content(self): + """content of the biography""" + return self.__content + + def __repr__(self): + return "" % self.__artist.name from datetime import datetime import time diff --git a/src/auth.py b/src/auth.py index ba99213..3b87f1e 100644 --- a/src/auth.py +++ b/src/auth.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" \ No newline at end of file diff --git a/src/base.py b/src/base.py index 1a2e2c8..b89b583 100644 --- a/src/base.py +++ b/src/base.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" @@ -47,12 +47,12 @@ class LastfmBase(object): @staticmethod def topProperty(listPropertyName): - def top(func): + def decorator(func): def wrapper(ob): topList = getattr(ob, listPropertyName) return (len(topList) and topList[0] or None) return property(fget = wrapper, doc = func.__doc__) - return top + return decorator def __gt__(self, other): diff --git a/src/error.py b/src/error.py index 4678a30..0ba344d 100644 --- a/src/error.py +++ b/src/error.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/event.py b/src/event.py index 12c8490..739caeb 100644 --- a/src/event.py +++ b/src/event.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/filecache.py b/src/filecache.py index a9e7037..3f25062 100644 --- a/src/filecache.py +++ b/src/filecache.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/geo.py b/src/geo.py index af2e5d5..c38c409 100644 --- a/src/geo.py +++ b/src/geo.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" @@ -14,6 +14,12 @@ class Geo(object): distance = None, page = None): params = {'method': 'geo.getevents', 'location': location} + if distance is not None: + params.update({'distance': distance}) + + if page is not None: + params.update({'page': page}) + data = api._fetchData(params).find('events') return SearchResult( diff --git a/src/group.py b/src/group.py index 2234ceb..35d110a 100644 --- a/src/group.py +++ b/src/group.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/playlist.py b/src/playlist.py index 2aaa218..3d52c7d 100644 --- a/src/playlist.py +++ b/src/playlist.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/registry.py b/src/registry.py index 2697ae8..feda78d 100644 --- a/src/registry.py +++ b/src/registry.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/search.py b/src/search.py index 275b460..f9cf89b 100644 --- a/src/search.py +++ b/src/search.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" @@ -66,4 +66,4 @@ class SearchResult(object): pass def __repr__(self): - return "" % (self.type, self.searchTerms) \ No newline at end of file + return "" % (self.totalResults, self.type, self.searchTerms) \ No newline at end of file diff --git a/src/stats.py b/src/stats.py index e79d74c..fa4383e 100644 --- a/src/stats.py +++ b/src/stats.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/tag.py b/src/tag.py index fb6aadd..8bee9e4 100644 --- a/src/tag.py +++ b/src/tag.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/tasteometer.py b/src/tasteometer.py index 07d8ae3..c6e9b2f 100644 --- a/src/tasteometer.py +++ b/src/tasteometer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/track.py b/src/track.py index 62c332f..0b1db35 100644 --- a/src/track.py +++ b/src/track.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" diff --git a/src/user.py b/src/user.py index be57298..8649570 100644 --- a/src/user.py +++ b/src/user.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" @@ -34,6 +34,7 @@ class User(LastfmBase): self.__topArtists = None self.__topTracks = None self.__topTags = None + self.__lirary = User.Library(api, self) @property def name(self): @@ -263,43 +264,109 @@ class User(LastfmBase): pass def getTopArtists(self, period = None): - pass + params = {'method': 'user.gettopartists', 'user': self.name} + if period is not None: + params.update({'period': period}) + data = self.__api._fetchData(params).find('topartists') + + return [ + Artist( + self.__api, + name = a.findtext('name'), + mbid = a.findtext('mbid'), + stats = Stats( + subject = a.findtext('name'), + rank = a.attrib['rank'].strip() and int(a.attrib['rank']) or None, + playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None + ), + url = a.findtext('url'), + streamable = (a.findtext('streamable') == "1"), + image = dict([(i.get('size'), i.text) for i in a.findall('image')]), + ) + for a in data.findall('artist') + ] @property def topArtists(self): """top artists of the user""" - return self.getTopArtists() + if self.__topArtists is None: + self.__topArtists = self.getTopArtists() + return self.__topArtists - @property + @LastfmBase.topProperty("topArtists") def topArtist(self): """top artist of the user""" - return (len(self.topArtists) and self.topArtists[0] or None) + pass def getTopTracks(self, period = None): - pass + params = {'method': 'user.gettoptracks', 'user': self.name} + if period is not None: + params.update({'period': period}) + data = self.__api._fetchData(params).find('toptracks') + return [ + 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'), + rank = t.attrib['rank'].strip() and int(t.attrib['rank']) or None, + playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None + ), + 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') + ] @property def topTracks(self): """top tracks of the user""" - return self.getTopTracks() + if self.__topTracks is None: + self.__topTracks = self.getTopTracks() + return self.__topTracks - @property + @LastfmBase.topProperty("topTracks") def topTrack(self): """top track of the user""" return (len(self.topTracks) and self.topTracks[0] or None) def getTopTags(self, limit = None): - pass + params = {'method': 'user.gettoptags', 'user': self.name} + if limit is not None: + params.update({'limit': limit}) + data = self.__api._fetchData(params).find('toptags') + return [ + 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') + ] @property def topTags(self): """top tags of the user""" - return self.getTopTags() + if self.__topTags is None: + self.__topTags = self.getTopTags() + return self.__topTags - @property + @LastfmBase.topProperty("topTags") def topTag(self): """top tag of the user""" - return (len(self.topTags) and self.topTags[0] or None) + pass @property def weeklyChartList(self): @@ -331,6 +398,10 @@ class User(LastfmBase): @property def recentWeeklyTrackChart(self): return self.getWeeklyTrackChart() + + @property + def library(self): + return self.__lirary @staticmethod def hashFunc(*args, **kwds): @@ -350,6 +421,139 @@ class User(LastfmBase): def __repr__(self): return "" % self.name + + class Library(object): + def __init__(self, api, user): + self.__api = api + self.__user = user + self.__albums = None + self.__artists = None + self.__tracks = None + + @property + def user(self): + return self.__user + + def getAlbums(self, + limit = None, + page = None): + params = {'method': 'library.getalbums'} + data = self._fetchData(params, limit, page).find('albums') + return { + 'page': int(data.attrib['page']), + 'perPage': int(data.attrib['perPage']), + 'totalPages': int(data.attrib['totalPages']), + 'albums': [ + Album( + self.__api, + name = a.findtext('name'), + artist = Artist( + self.__api, + name = a.findtext('artist/name'), + mbid = a.findtext('artist/mbid'), + url = a.findtext('artist/url'), + ), + mbid = a.findtext('mbid'), + url = a.findtext('url'), + image = dict([(i.get('size'), i.text) for i in a.findall('image')]), + stats = Stats( + subject = a.findtext('name'), + playcount = int(a.findtext('playcount')), + ) + ) + for a in data.findall('album') + ] + } + + @property + def albums(self): + if self.__albums is None: + self.__albums = self.getAlbums()['albums'] + return self.__albums + + def getArtists(self, + limit = None, + page = None): + params = {'method': 'library.getartists'} + data = self._fetchData(params, limit, page).find('artists') + return { + 'page': int(data.attrib['page']), + 'perPage': int(data.attrib['perPage']), + 'totalPages': int(data.attrib['totalPages']), + 'artists': [ + Artist( + self.__api, + name = a.findtext('name'), + mbid = a.findtext('mbid'), + stats = Stats( + subject = a.findtext('name'), + playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None, + tagcount = a.findtext('tagcount') and int(a.findtext('tagcount')) or None + ), + url = a.findtext('url'), + streamable = (a.findtext('streamable') == "1"), + image = dict([(i.get('size'), i.text) for i in a.findall('image')]), + ) + for a in data.findall('artist') + ] + } + + @property + def artists(self): + if self.__artists is None: + self.__artists = self.getArtists()['artists'] + return self.__artists + + def getTracks(self, + limit = None, + page = None): + params = {'method': 'library.gettracks'} + data = self._fetchData(params, limit, page).find('tracks') + return { + 'page': int(data.attrib['page']), + 'perPage': int(data.attrib['perPage']), + 'totalPages': int(data.attrib['totalPages']), + 'tracks': [ + 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'), + playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None, + tagcount = t.findtext('tagcount') and int(t.findtext('tagcount')) or None + ), + 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') + ] + } + + @property + def tracks(self): + if self.__tracks is None: + self.__tracks = self.getTracks()['tracks'] + return self.__tracks + + def _fetchData(self, params, limit, page): + params .update({'user': self.user.name}) + if limit is not None: + params.update({'limit': limit}) + if page is not None: + params.update({'page': page}) + + return self.__api._fetchData(params) + + def __repr__(self): + return "" % self.user.name from datetime import datetime import time @@ -360,4 +564,10 @@ from album import Album from error import LastfmError from event import Event from stats import Stats +from tag import Tag from track import Track + +#TODO +#extract self.__* property as decorator +#write depaginations +#write exceptions diff --git a/src/weeklychart.py b/src/weeklychart.py index ba99213..3b87f1e 100644 --- a/src/weeklychart.py +++ b/src/weeklychart.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -__author__ = "Abhinav Sarkar" +__author__ = "Abhinav Sarkar " __version__ = "0.1" __license__ = "GNU Lesser General Public License" \ No newline at end of file