diff --git a/src/artist.py b/src/artist.py index 773a59a..ef3bceb 100644 --- a/src/artist.py +++ b/src/artist.py @@ -338,7 +338,6 @@ class Artist(LastfmBase): return hash(kwds['name'].lower()) except KeyError: try: - print args[1].lower() return hash(args[1].lower()) except IndexError: raise LastfmError("name has to be provided for hashing") diff --git a/src/group.py b/src/group.py index 35d110a..d4f56ec 100644 --- a/src/group.py +++ b/src/group.py @@ -19,56 +19,87 @@ class Group(LastfmBase): @property def name(self): return self.__name - - @property + + @LastfmBase.cachedProperty def weeklyChartList(self): - pass + params = {'method': 'group.getweeklychartlist', 'group': self.name} + data = self.__api._fetchData(params).find('weeklychartlist') + return [ + WeeklyChart.createFromData(self.__api, self, c) + for c in data.findall('chart') + ] + def _checkWeeklyChartParams(self, params, start = None, end = None): + if (start is not None and end is None) or (start is None and end is not None): + raise LastfmError("both start and end have to be provided.") + if start is not None and end is not None: + if isinstance(start, datetime) and isinstance(end, datetime): + params.update({ + 'start': int(time.mktime(start.timetuple())), + 'end': int(time.mktime(end.timetuple())) + }) + else: + raise LastfmError("start and end must be datetime.datetime instances") + + return params def getWeeklyAlbumChart(self, start = None, end = None): - pass - - @property + params = {'method': 'group.getweeklyalbumchart', 'group': self.name} + params = self._checkWeeklyChartParams(params, start, end) + data = self.__api._fetchData(params).find('weeklyalbumchart') + return WeeklyAlbumChart.createFromData(self.__api, self, data) + + @LastfmBase.cachedProperty def recentWeeklyAlbumChart(self): return self.getWeeklyAlbumChart() - + def getWeeklyArtistChart(self, start = None, end = None): - pass - - @property + params = {'method': 'group.getweeklyartistchart', 'group': self.name} + params = self._checkWeeklyChartParams(params, start, end) + data = self.__api._fetchData(params).find('weeklyartistchart') + return WeeklyArtistChart.createFromData(self.__api, self, data) + + @LastfmBase.cachedProperty def recentWeeklyArtistChart(self): return self.getWeeklyArtistChart() - + def getWeeklyTrackChart(self, start = None, end = None): - pass - - @property + params = {'method': 'group.getweeklytrackchart', 'group': self.name} + params = self._checkWeeklyChartParams(params, start, end) + data = self.__api._fetchData(params).find('weeklytrackchart') + return WeeklyTrackChart.createFromData(self.__api, self, data) + + @LastfmBase.cachedProperty def recentWeeklyTrackChart(self): return self.getWeeklyTrackChart() - + @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 "" % self.name +import time +from datetime import datetime + from api import Api -from error import LastfmError \ No newline at end of file +from error import LastfmError +from weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart diff --git a/src/registry.py b/src/registry.py index feda78d..4ad334d 100644 --- a/src/registry.py +++ b/src/registry.py @@ -15,11 +15,12 @@ from playlist import Playlist from tag import Tag from track import Track from user import User +from weeklychart import WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart class Registry(object): """The registry to contain all the entities""" keys = [Album, Artist, Event, Location, Country, Group, - Playlist, Tag, Track, User] + Playlist, Tag, Track, User, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart] def get(self, name): if name not in Registry.keys: diff --git a/src/user.py b/src/user.py index 0f914eb..47008af 100644 --- a/src/user.py +++ b/src/user.py @@ -341,34 +341,61 @@ class User(LastfmBase): """top tag of the user""" pass - @property + @LastfmBase.cachedProperty def weeklyChartList(self): - pass - + params = {'method': 'user.getweeklychartlist', 'user': self.name} + data = self.__api._fetchData(params).find('weeklychartlist') + return [ + WeeklyChart.createFromData(self.__api, self, c) + for c in data.findall('chart') + ] + def _checkWeeklyChartParams(self, params, start = None, end = None): + if (start is not None and end is None) or (start is None and end is not None): + raise LastfmError("both start and end have to be provided.") + if start is not None and end is not None: + if isinstance(start, datetime) and isinstance(end, datetime): + params.update({ + 'start': int(time.mktime(start.timetuple())), + 'end': int(time.mktime(end.timetuple())) + }) + else: + raise LastfmError("start and end must be datetime.datetime instances") + + return params + def getWeeklyAlbumChart(self, start = None, end = None): - pass + params = {'method': 'user.getweeklyalbumchart', 'user': self.name} + params = self._checkWeeklyChartParams(params, start, end) + data = self.__api._fetchData(params).find('weeklyalbumchart') + return WeeklyAlbumChart.createFromData(self.__api, self, data) - @property + @LastfmBase.cachedProperty def recentWeeklyAlbumChart(self): return self.getWeeklyAlbumChart() def getWeeklyArtistChart(self, start = None, end = None): - pass + params = {'method': 'user.getweeklyartistchart', 'user': self.name} + params = self._checkWeeklyChartParams(params, start, end) + data = self.__api._fetchData(params).find('weeklyartistchart') + return WeeklyArtistChart.createFromData(self.__api, self, data) - @property + @LastfmBase.cachedProperty def recentWeeklyArtistChart(self): return self.getWeeklyArtistChart() def getWeeklyTrackChart(self, start = None, end = None): - pass + params = {'method': 'user.getweeklytrackchart', 'user': self.name} + params = self._checkWeeklyChartParams(params, start, end) + data = self.__api._fetchData(params).find('weeklytrackchart') + return WeeklyTrackChart.createFromData(self.__api, self, data) - @property + @LastfmBase.cachedProperty def recentWeeklyTrackChart(self): return self.getWeeklyTrackChart() @@ -531,6 +558,7 @@ from event import Event from stats import Stats from tag import Tag from track import Track +from weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart #TODO #write depaginations diff --git a/src/weeklychart.py b/src/weeklychart.py index 3b87f1e..efe428a 100644 --- a/src/weeklychart.py +++ b/src/weeklychart.py @@ -2,4 +2,197 @@ __author__ = "Abhinav Sarkar " __version__ = "0.1" -__license__ = "GNU Lesser General Public License" \ No newline at end of file +__license__ = "GNU Lesser General Public License" + +from base import LastfmBase + +class WeeklyChart(LastfmBase): + """A class for representing the weekly charts""" + + def init(self, subject, start, end): + self._subject = subject + self._start = start + self._end = end + + @property + def subject(self): + return self._subject + + @property + def start(self): + return self._start + + @property + def end(self): + return self._end + + @staticmethod + def createFromData(api, subject, data): + return WeeklyChart( + subject = subject, + start = datetime.utcfromtimestamp(int(data.attrib['from'])), + end = datetime.utcfromtimestamp(int(data.attrib['to'])) + ) + + @staticmethod + def hashFunc(*args, **kwds): + try: + return "%s%s%s%s" % ( + hash(kwds['subject'].__class__.__name__), + hash(kwds['subject'].name), + hash(kwds['start']), + hash(kwds['end']) + ) + except KeyError: + raise LastfmError("subject, start and end have to be provided for hashing") + + def __hash__(self): + return self.__class__.hashFunc( + subject = self.subject, + start = self.start, + end = self.end + ) + + def __eq__(self, other): + return self.subject == other.subject and \ + self.start == other.start and \ + self.end == other.end + + def __lt__(self, other): + if self.subject == other.subject: + if self.start == other.start: + return self.end < other.end + else: + return self.start < other.start + else: + return self.subject < other.subject + + def __repr__(self): + return "" % \ + ( + self.__class__.__name__, + self.subject.__class__.__name__, + self.subject.name, + self.start.strftime("%x"), + self.end.strftime("%x"), + ) + +class WeeklyAlbumChart(WeeklyChart): + """A class for representing the weekly album charts""" + def init(self, subject, start, end, albums): + self._subject = subject + self._start = start + self._end = end + self.__albums = albums + + @property + def albums(self): + return self.__albums + + @staticmethod + def createFromData(api, subject, data): + return WeeklyAlbumChart( + subject = subject, + start = datetime.utcfromtimestamp(int(data.attrib['from'])), + end = datetime.utcfromtimestamp(int(data.attrib['to'])), + albums = [ + Album( + api, + name = a.findtext('name'), + mbid = a.findtext('mbid'), + artist = Artist( + api, + name = a.findtext('artist'), + mbid = a.find('artist').attrib['mbid'], + ), + stats = Stats( + subject = a.findtext('name'), + rank = int(a.attrib['rank']), + playcount = int(a.findtext('playcount')), + ), + url = a.findtext('url'), + ) + for a in data.findall('album') + ] + ) + +class WeeklyArtistChart(WeeklyChart): + """A class for representing the weekly artist charts""" + def init(self, subject, start, end, artists): + self._subject = subject + self._start = start + self._end = end + self.__artists = artists + + @property + def artists(self): + return self.__artists + + @staticmethod + def createFromData(api, subject, data): + return WeeklyArtistChart( + subject = subject, + start = datetime.utcfromtimestamp(int(data.attrib['from'])), + end = datetime.utcfromtimestamp(int(data.attrib['to'])), + artists = [ + Artist( + api, + name = a.findtext('name'), + mbid = a.findtext('mbid'), + stats = Stats( + subject = a.findtext('name'), + rank = int(a.attrib['rank']), + playcount = int(a.findtext('playcount')), + ), + url = a.findtext('url'), + ) + for a in data.findall('artist') + ] + ) + +class WeeklyTrackChart(WeeklyChart): + """A class for representing the weekly track charts""" + def init(self, subject, start, end, tracks): + self._subject = subject + self._start = start + self._end = end + self.__tracks = tracks + + @property + def tracks(self): + return self.__tracks + + @staticmethod + def createFromData(api, subject, data): + return WeeklyTrackChart( + subject = subject, + start = datetime.utcfromtimestamp(int(data.attrib['from'])), + end = datetime.utcfromtimestamp(int(data.attrib['to'])), + tracks = [ + Track( + api, + name = t.findtext('name'), + mbid = t.findtext('mbid'), + artist = Artist( + api, + name = t.findtext('artist'), + mbid = t.find('artist').attrib['mbid'], + ), + stats = Stats( + subject = t.findtext('name'), + rank = int(t.attrib['rank']), + playcount = int(t.findtext('playcount')), + ), + url = t.findtext('url'), + ) + for t in data.findall('track') + ] + ) + +from datetime import datetime + +from album import Album +from artist import Artist +from error import LastfmError +from stats import Stats +from track import Track \ No newline at end of file