* added Rolling Charts: Monthly, Quaterly, Half-yearly and Yearly; Album, Artist, Track and Tag charts
* refactored the chart related code to mixins.chartable module * made related changes in user, tag and group modulesmaster
parent
42aa35fcbb
commit
d709434a7b
352
lastfm/chart.py
352
lastfm/chart.py
|
@ -10,7 +10,7 @@ from lastfm.mixins import Cacheable
|
|||
from operator import xor
|
||||
|
||||
class Chart(LastfmBase, Cacheable):
|
||||
"""A class for representing the weekly charts"""
|
||||
"""The base class for all the chart classes"""
|
||||
|
||||
def init(self, subject, start, end, stats = None):
|
||||
self._subject = subject
|
||||
|
@ -35,26 +35,16 @@ class Chart(LastfmBase, Cacheable):
|
|||
return self._stats
|
||||
|
||||
@staticmethod
|
||||
def create_from_data(api, subject, data):
|
||||
return Chart(
|
||||
subject = subject,
|
||||
start = datetime.utcfromtimestamp(int(data.attrib['from'])),
|
||||
end = datetime.utcfromtimestamp(int(data.attrib['to']))
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _check_chart_params(params, start = None, end = None):
|
||||
def _check_chart_params(params, subject, start = None, end = None):
|
||||
if xor(start is None, end is None):
|
||||
raise InvalidParametersError("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({
|
||||
'from': int(calendar.timegm(start.timetuple())),
|
||||
'to': int(calendar.timegm(end.timetuple()))
|
||||
})
|
||||
else:
|
||||
if not (isinstance(start, datetime) and isinstance(end, datetime)):
|
||||
raise InvalidParametersError("start and end must be datetime.datetime instances")
|
||||
|
||||
params.update({
|
||||
'from': int(calendar.timegm(start.timetuple())),
|
||||
'to': int(calendar.timegm(end.timetuple()))
|
||||
})
|
||||
return params
|
||||
|
||||
@staticmethod
|
||||
|
@ -71,10 +61,10 @@ class Chart(LastfmBase, Cacheable):
|
|||
|
||||
def __hash__(self):
|
||||
return self.__class__._hash_func(
|
||||
subject = self.subject,
|
||||
start = self.start,
|
||||
end = self.end
|
||||
)
|
||||
subject = self.subject,
|
||||
start = self.start,
|
||||
end = self.end
|
||||
)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.subject == other.subject and \
|
||||
|
@ -99,21 +89,68 @@ class Chart(LastfmBase, Cacheable):
|
|||
self.start.strftime("%x"),
|
||||
self.end.strftime("%x"),
|
||||
)
|
||||
|
||||
class WeeklyChart(Chart):
|
||||
def init(self, subject, start, end, stats = None):
|
||||
super(WeeklyChart, self).init(subject, start, end, stats)
|
||||
|
||||
class WeeklyAlbumChart(WeeklyChart):
|
||||
"""A class for representing the weekly album charts"""
|
||||
class AlbumChart(Chart):
|
||||
def init(self, subject, start, end, stats, albums):
|
||||
super(WeeklyAlbumChart, self).init(subject, start, end, stats)
|
||||
super(AlbumChart, self).init(subject, start, end, stats)
|
||||
self._albums = albums
|
||||
|
||||
@property
|
||||
def albums(self):
|
||||
return self._albums
|
||||
|
||||
class ArtistChart(Chart):
|
||||
def init(self, subject, start, end, stats, artists):
|
||||
super(ArtistChart, self).init(subject, start, end, stats)
|
||||
self._artists = artists
|
||||
|
||||
@property
|
||||
def artists(self):
|
||||
return self._artists
|
||||
|
||||
class TrackChart(Chart):
|
||||
def init(self, subject, start, end, tracks, stats):
|
||||
super(TrackChart, self).init(subject, start, end, stats)
|
||||
self._tracks = tracks
|
||||
|
||||
@property
|
||||
def tracks(self):
|
||||
return self._tracks
|
||||
|
||||
class TagChart(Chart):
|
||||
def init(self, subject, start, end, tags, stats):
|
||||
super(TagChart, self).init(subject, start, end, stats)
|
||||
self._tags = tags
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
return self._tags
|
||||
|
||||
class WeeklyChart(Chart):
|
||||
"""A class for representing the weekly charts"""
|
||||
@staticmethod
|
||||
def create_from_data(api, subject, data):
|
||||
return WeeklyChart(
|
||||
subject = subject,
|
||||
start = datetime.utcfromtimestamp(int(data.attrib['from'])),
|
||||
end = datetime.utcfromtimestamp(int(data.attrib['to']))
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _check_chart_params(params, subject, start = None, end = None):
|
||||
params = Chart._check_chart_params(params, subject, start, end)
|
||||
if start is not None and end is not None:
|
||||
wcl = subject.weekly_chart_list
|
||||
is_valid = False
|
||||
for wc in wcl:
|
||||
if wc.start == start and wc.end == end:
|
||||
is_valid = True
|
||||
if not is_valid:
|
||||
raise InvalidParametersError("%s - %s chart dates are invalid" % (start, end))
|
||||
return params
|
||||
|
||||
class WeeklyAlbumChart(AlbumChart, WeeklyChart):
|
||||
"""A class for representing the weekly album charts"""
|
||||
@staticmethod
|
||||
def create_from_data(api, subject, data):
|
||||
w = WeeklyChart(
|
||||
|
@ -158,16 +195,8 @@ class WeeklyAlbumChart(WeeklyChart):
|
|||
]
|
||||
)
|
||||
|
||||
class WeeklyArtistChart(WeeklyChart):
|
||||
class WeeklyArtistChart(ArtistChart, WeeklyChart):
|
||||
"""A class for representing the weekly artist charts"""
|
||||
def init(self, subject, start, end, stats, artists):
|
||||
super(WeeklyArtistChart, self).init(subject, start, end, stats)
|
||||
self._artists = artists
|
||||
|
||||
@property
|
||||
def artists(self):
|
||||
return self._artists
|
||||
|
||||
@staticmethod
|
||||
def create_from_data(api, subject, data):
|
||||
w = WeeklyChart(
|
||||
|
@ -208,16 +237,8 @@ class WeeklyArtistChart(WeeklyChart):
|
|||
]
|
||||
)
|
||||
|
||||
class WeeklyTrackChart(WeeklyChart):
|
||||
class WeeklyTrackChart(TrackChart, WeeklyChart):
|
||||
"""A class for representing the weekly track charts"""
|
||||
def init(self, subject, start, end, tracks, stats):
|
||||
super(WeeklyTrackChart, self).init(subject, start, end, stats)
|
||||
self._tracks = tracks
|
||||
|
||||
@property
|
||||
def tracks(self):
|
||||
return self._tracks
|
||||
|
||||
@staticmethod
|
||||
def create_from_data(api, subject, data):
|
||||
w = WeeklyChart(
|
||||
|
@ -261,16 +282,8 @@ class WeeklyTrackChart(WeeklyChart):
|
|||
]
|
||||
)
|
||||
|
||||
class WeeklyTagChart(WeeklyChart):
|
||||
class WeeklyTagChart(TagChart, WeeklyChart):
|
||||
"""A class for representing the weekly tag charts"""
|
||||
def init(self, subject, start, end, tags, stats):
|
||||
super(WeeklyTagChart, self).init(subject, start, end, stats)
|
||||
self._tags = tags
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
return self._tags
|
||||
|
||||
@staticmethod
|
||||
def create_from_data(api, subject, start, end):
|
||||
w = WeeklyChart(
|
||||
|
@ -356,77 +369,216 @@ class WeeklyTagChart(WeeklyChart):
|
|||
return wtc
|
||||
|
||||
class RollingChart(Chart):
|
||||
pass
|
||||
"""Base class for the rolling charts classes"""
|
||||
@classmethod
|
||||
def _check_chart_params(cls, params, subject, start = None, end = None):
|
||||
duration = cls._period['duration']
|
||||
params = Chart._check_chart_params(params, subject, start, end)
|
||||
if start is not None and end is not None:
|
||||
mcl = MonthlyChart.get_chart_list(subject)
|
||||
is_valid = False
|
||||
for i in xrange(len(mcl)-(duration-1)):
|
||||
if mcl[i].start == start and mcl[i+(duration-1)].end == end:
|
||||
is_valid = True
|
||||
if not is_valid:
|
||||
raise InvalidParametersError("%s - %s chart dates are invalid" % (start, end))
|
||||
return params
|
||||
|
||||
@classmethod
|
||||
def create_from_data(cls, subject, key_func,
|
||||
start = None, end = None):
|
||||
chart_type = cls.mro()[0]._chart_type
|
||||
period = cls.mro()[3]._period
|
||||
globals()["%slyChart" % period['name'].title().replace(' ','')]._check_chart_params({}, subject, start, end)
|
||||
mcl = MonthlyChart.get_chart_list(subject)
|
||||
if start is None and end is None:
|
||||
start = mcl[-period['duration']].start
|
||||
end = mcl[-1].end
|
||||
wcl = subject.weekly_chart_list
|
||||
period_wcl = [wc for wc in wcl
|
||||
if start < wc.start < end or start < wc.end < end]
|
||||
period_wacl = []
|
||||
for wc in period_wcl:
|
||||
try:
|
||||
period_wacl.append(
|
||||
getattr(subject, "get_weekly_%s_chart" % chart_type)(wc.start, wc.end))
|
||||
except LastfmError:
|
||||
pass
|
||||
stats_dict = period_wacl[0].__dict__["_%ss" % chart_type][0].stats.__dict__
|
||||
count_attribute = [k for k in stats_dict.keys()
|
||||
if stats_dict[k] is not None and k not in ['_rank', '_subject']][0]
|
||||
items = {}
|
||||
for wac in period_wacl:
|
||||
for item in wac.__dict__["_%ss" % chart_type]:
|
||||
key = key_func(item)
|
||||
mw_start = max(wac.start, start)
|
||||
mw_end = min(wac.end, end)
|
||||
count = item.stats.__dict__[count_attribute] * (mw_end - mw_start).days / 7.0
|
||||
if key in items:
|
||||
items[key].stats.__dict__[count_attribute] += count
|
||||
else:
|
||||
items[key] = item
|
||||
items[key].stats.__dict__[count_attribute] = count
|
||||
items = items.values()
|
||||
items = [a for a in items if a.stats.__dict__[count_attribute] >= 1]
|
||||
items.sort(key = lambda a: a.stats.__dict__[count_attribute], reverse=True)
|
||||
for i,item in enumerate(items):
|
||||
item.stats._rank = i + 1
|
||||
item.stats.__dict__[count_attribute] = int(item.stats.__dict__[count_attribute])
|
||||
return globals()[
|
||||
"%sly%sChart" % (
|
||||
period['name'].title().replace(' ',''),
|
||||
chart_type.capitalize()
|
||||
)](
|
||||
subject = subject,
|
||||
start = start,
|
||||
end = end,
|
||||
stats = Stats(
|
||||
subject = subject,
|
||||
**{count_attribute[1:]: sum([a.stats.__dict__[count_attribute] for a in items])}
|
||||
),
|
||||
**{"%ss" % chart_type: items}
|
||||
)
|
||||
|
||||
class RollingAlbumChart(AlbumChart):
|
||||
@classmethod
|
||||
def create_from_data(cls, subject, start = None, end = None):
|
||||
key_func = lambda album: "::".join((album.name, album.artist.name))
|
||||
return super(cls.mro()[3], cls).create_from_data(
|
||||
subject, key_func, start, end)
|
||||
|
||||
class RollingArtistChart(ArtistChart):
|
||||
@classmethod
|
||||
def create_from_data(cls, subject, start = None, end = None):
|
||||
key_func = lambda artist: artist.name
|
||||
return super(cls.mro()[3], cls).create_from_data(
|
||||
subject, key_func, start, end)
|
||||
|
||||
class RollingTrackChart(TrackChart):
|
||||
@classmethod
|
||||
def create_from_data(cls, subject, start = None, end = None):
|
||||
key_func = lambda track: "::".join((track.name, track.artist.name))
|
||||
return super(cls.mro()[3], cls).create_from_data(
|
||||
subject, key_func, start, end)
|
||||
|
||||
class RollingTagChart(TagChart):
|
||||
@classmethod
|
||||
def create_from_data(cls, subject, start = None, end = None):
|
||||
key_func = lambda tag: tag.name
|
||||
chart = super(cls.mro()[3], cls).create_from_data(
|
||||
subject, key_func, start, end)
|
||||
count_sum = sum([t.stats.count for t in chart.tags])
|
||||
for t in chart.tags:
|
||||
t.stats.__dict__['_count'] /= count_sum
|
||||
return chart
|
||||
|
||||
class MonthlyChart(RollingChart):
|
||||
pass
|
||||
"""A class for representing the monthly charts"""
|
||||
_period = {'name': 'month', 'duration': 1}
|
||||
|
||||
@staticmethod
|
||||
def get_chart_list(subject):
|
||||
wcl = subject.weekly_chart_list
|
||||
months = set()
|
||||
for l in wcl:
|
||||
months.add(l.start.replace(day=1, hour=12, minute=0, second=0))
|
||||
months = list(months)
|
||||
months.sort()
|
||||
months[0] = wcl[0].start.replace(hour=12, minute=0, second=0)
|
||||
months.append(wcl[-1].end.replace(hour=12, minute=0, second=0))
|
||||
|
||||
class MonthlyAlbumChart(MonthlyChart):
|
||||
pass
|
||||
return [MonthlyChart(
|
||||
subject=subject,
|
||||
start=months[i],
|
||||
end=months[i+1]
|
||||
)
|
||||
for i in xrange(len(months)-1)]
|
||||
|
||||
class MonthlyAlbumChart(RollingAlbumChart, MonthlyChart):
|
||||
"""A class for representing the monthly album charts"""
|
||||
_chart_type = "album"
|
||||
|
||||
class MonthlyArtistChart(RollingArtistChart, MonthlyChart):
|
||||
"""A class for representing the monthly artist charts"""
|
||||
_chart_type = "artist"
|
||||
|
||||
class MonthlyArtistChart(MonthlyChart):
|
||||
pass
|
||||
class MonthlyTrackChart(RollingTrackChart, MonthlyChart):
|
||||
"""A class for representing the monthly track charts"""
|
||||
_chart_type = "track"
|
||||
|
||||
class MonthlyTrackChart(MonthlyChart):
|
||||
pass
|
||||
class MonthlyTagChart(RollingTagChart, MonthlyChart):
|
||||
"""A class for representing the monthly tag charts"""
|
||||
_chart_type = "tag"
|
||||
|
||||
class MonthlyTagChart(MonthlyChart):
|
||||
pass
|
||||
class QuaterlyChart(RollingChart):
|
||||
"""A class for representing the three monthly charts"""
|
||||
_period = {'name': 'quater', 'duration': 3}
|
||||
|
||||
class ThreeMonthlyChart(RollingChart):
|
||||
pass
|
||||
class QuaterlyAlbumChart(RollingAlbumChart, QuaterlyChart):
|
||||
"""A class for representing the three monthly album charts"""
|
||||
_chart_type = "album"
|
||||
|
||||
class ThreeMonthlyAlbumChart(ThreeMonthlyChart):
|
||||
pass
|
||||
class QuaterlyArtistChart(RollingArtistChart, QuaterlyChart):
|
||||
"""A class for representing the three monthly artist charts"""
|
||||
_chart_type = "artist"
|
||||
|
||||
class ThreeMonthlyArtistChart(ThreeMonthlyChart):
|
||||
pass
|
||||
class QuaterlyTrackChart(RollingTrackChart, QuaterlyChart):
|
||||
"""A class for representing the three monthly track charts"""
|
||||
_chart_type = "track"
|
||||
|
||||
class ThreeMonthlyTrackChart(ThreeMonthlyChart):
|
||||
pass
|
||||
class QuaterlyTagChart(RollingTagChart, QuaterlyChart):
|
||||
"""A class for representing the three monthly tag charts"""
|
||||
_chart_type = "tag"
|
||||
|
||||
class ThreeMonthlyTagChart(ThreeMonthlyChart):
|
||||
pass
|
||||
class HalfYearlyChart(RollingChart):
|
||||
"""A class for representing the six monthly charts"""
|
||||
_period = {'name': 'half year', 'duration': 6}
|
||||
|
||||
class SixMonthlyChart(RollingChart):
|
||||
pass
|
||||
class HalfYearlyAlbumChart(RollingAlbumChart, HalfYearlyChart):
|
||||
"""A class for representing the six monthly album charts"""
|
||||
_chart_type = "album"
|
||||
|
||||
class SixMonthlyAlbumChart(SixMonthlyChart):
|
||||
pass
|
||||
class HalfYearlyArtistChart(RollingArtistChart, HalfYearlyChart):
|
||||
"""A class for representing the six monthly artist charts"""
|
||||
_chart_type = "artist"
|
||||
|
||||
class SixMonthlyArtistChart(SixMonthlyChart):
|
||||
pass
|
||||
class HalfYearlyTrackChart(RollingTrackChart, HalfYearlyChart):
|
||||
"""A class for representing the six monthly track charts"""
|
||||
_chart_type = "track"
|
||||
|
||||
class SixMonthlyTrackChart(SixMonthlyChart):
|
||||
pass
|
||||
|
||||
class SixMonthlyTagChart(SixMonthlyChart):
|
||||
pass
|
||||
class HalfYearlyTagChart(RollingTagChart, HalfYearlyChart):
|
||||
"""A class for representing the six monthly tag charts"""
|
||||
_chart_type = "tag"
|
||||
|
||||
class YearlyChart(RollingChart):
|
||||
pass
|
||||
"""A class for representing the yearly charts"""
|
||||
_period = {'name': 'year', 'duration': 12}
|
||||
|
||||
class YearlyAlbumChart(YearlyChart):
|
||||
pass
|
||||
class YearlyAlbumChart(RollingAlbumChart, YearlyChart):
|
||||
"""A class for representing the yearly album charts"""
|
||||
_chart_type = "album"
|
||||
|
||||
class YearlyArtistChart(YearlyChart):
|
||||
pass
|
||||
class YearlyArtistChart(RollingArtistChart, YearlyChart):
|
||||
"""A class for representing the yearly artist charts"""
|
||||
_chart_type = "artist"
|
||||
|
||||
class YearlyTrackChart(YearlyChart):
|
||||
pass
|
||||
class YearlyTrackChart(RollingTrackChart, YearlyChart):
|
||||
"""A class for representing the yearly track charts"""
|
||||
_chart_type = "track"
|
||||
|
||||
class YearlyTagChart(YearlyChart):
|
||||
pass
|
||||
class YearlyTagChart(RollingTagChart, YearlyChart):
|
||||
"""A class for representing the yearly tag charts"""
|
||||
_chart_type = "tag"
|
||||
|
||||
__all__ = [
|
||||
'WeeklyChart',
|
||||
'WeeklyAlbumChart', 'WeeklyArtistChart', 'WeeklyTrackChart', 'WeeklyTagChart',
|
||||
'MonthlyChart',
|
||||
'MonthlyAlbumChart', 'MonthlyArtistChart', 'MonthlyTrackChart', 'MonthlyTagChart',
|
||||
'ThreeMonthlyChart',
|
||||
'ThreeMonthlyAlbumChart', 'ThreeMonthlyArtistChart', 'ThreeMonthlyTrackChart', 'ThreeMonthlyTagChart',
|
||||
'SixMonthlyChart',
|
||||
'SixMonthlyAlbumChart', 'SixMonthlyArtistChart', 'SixMonthlyTrackChart', 'SixMonthlyTagChart',
|
||||
'QuaterlyChart',
|
||||
'QuaterlyAlbumChart', 'QuaterlyArtistChart', 'QuaterlyTrackChart', 'QuaterlyTagChart',
|
||||
'HalfYearlyChart',
|
||||
'HalfYearlyAlbumChart', 'HalfYearlyArtistChart', 'HalfYearlyTrackChart', 'HalfYearlyTagChart',
|
||||
'YearlyChart',
|
||||
'YearlyAlbumChart', 'YearlyArtistChart', 'YearlyTrackChart', 'YearlyTagChart'
|
||||
]
|
||||
|
@ -435,7 +587,7 @@ import calendar
|
|||
|
||||
from lastfm.album import Album
|
||||
from lastfm.artist import Artist
|
||||
from lastfm.error import InvalidParametersError
|
||||
from lastfm.error import InvalidParametersError, LastfmError
|
||||
from lastfm.stats import Stats
|
||||
from lastfm.track import Track
|
||||
from lastfm.tag import Tag
|
216
lastfm/group.py
216
lastfm/group.py
|
@ -7,11 +7,13 @@ __license__ = "GNU Lesser General Public License"
|
|||
__package__ = "lastfm"
|
||||
|
||||
from lastfm.base import LastfmBase
|
||||
from lastfm.mixins import Cacheable
|
||||
from lastfm.lazylist import lazylist
|
||||
from lastfm.mixins import (
|
||||
Cacheable, AlbumChartable, ArtistChartable,
|
||||
TrackChartable, TagChartable)
|
||||
from lastfm.decorators import cached_property, depaginate
|
||||
|
||||
class Group(LastfmBase, Cacheable):
|
||||
class Group(LastfmBase, Cacheable, AlbumChartable,
|
||||
ArtistChartable, TrackChartable, TagChartable):
|
||||
"""A class representing a group on last.fm."""
|
||||
def init(self, api, name = None, **kwargs):
|
||||
"""
|
||||
|
@ -27,6 +29,11 @@ class Group(LastfmBase, Cacheable):
|
|||
"""
|
||||
if not isinstance(api, Api):
|
||||
raise InvalidParametersError("api reference must be supplied as an argument")
|
||||
AlbumChartable.init(self, api)
|
||||
ArtistChartable.init(self, api)
|
||||
TrackChartable.init(self, api)
|
||||
TagChartable.init(self, api)
|
||||
|
||||
self._api = api
|
||||
self._name = name
|
||||
|
||||
|
@ -37,209 +44,6 @@ class Group(LastfmBase, Cacheable):
|
|||
@rtype: L{str}
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@cached_property
|
||||
def weekly_chart_list(self):
|
||||
"""
|
||||
a list of available weekly charts for this group
|
||||
@rtype: L{list} of L{WeeklyChart}
|
||||
"""
|
||||
params = self._default_params({'method': 'group.getWeeklyChartList'})
|
||||
data = self._api._fetch_data(params).find('weeklychartlist')
|
||||
return [
|
||||
WeeklyChart.create_from_data(self._api, self, c)
|
||||
for c in data.findall('chart')
|
||||
]
|
||||
|
||||
def get_weekly_album_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get an album chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent album chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: an album chart for the group
|
||||
@rtype: L{WeeklyAlbumChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
"""
|
||||
params = self._default_params({'method': 'group.getWeeklyAlbumChart'})
|
||||
params = WeeklyChart._check_chart_params(params, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklyalbumchart')
|
||||
return WeeklyAlbumChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_album_chart(self):
|
||||
"""
|
||||
most recent album chart for the group
|
||||
@rtype: L{WeeklyAlbumChart}
|
||||
"""
|
||||
return self.get_weekly_album_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_album_chart_list(self):
|
||||
"""
|
||||
a list of all album charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyAlbumChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
yield self.get_weekly_album_chart(wc.start, wc.end)
|
||||
return gen()
|
||||
|
||||
def get_weekly_artist_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get an artist chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent artist chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: an artist chart for the group
|
||||
@rtype: L{WeeklyArtistChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
"""
|
||||
params = self._default_params({'method': 'group.getWeeklyArtistChart'})
|
||||
params = WeeklyChart._check_chart_params(params, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklyartistchart')
|
||||
return WeeklyArtistChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_artist_chart(self):
|
||||
"""
|
||||
most recent artist chart for the group
|
||||
@rtype: L{WeeklyArtistChart}
|
||||
"""
|
||||
return self.get_weekly_artist_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_artist_chart_list(self):
|
||||
"""
|
||||
a list of all artist charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyArtistChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
yield self.get_weekly_artist_chart(wc.start, wc.end)
|
||||
return gen()
|
||||
|
||||
def get_weekly_track_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get a track chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent artist chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: a track chart for the group
|
||||
@rtype: L{WeeklyTrackChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
"""
|
||||
params = self._default_params({'method': 'group.getWeeklyTrackChart'})
|
||||
params = WeeklyChart._check_chart_params(params, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklytrackchart')
|
||||
return WeeklyTrackChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_track_chart(self):
|
||||
"""
|
||||
most recent track chart for the group
|
||||
@rtype: L{WeeklyTrackChart}
|
||||
"""
|
||||
return self.get_weekly_track_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_track_chart_list(self):
|
||||
"""
|
||||
a list of all track charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyTrackChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
yield self.get_weekly_track_chart(wc.start, wc.end)
|
||||
return gen()
|
||||
|
||||
def get_weekly_tag_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get a tag chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent tag chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: a tag chart for the group
|
||||
@rtype: L{WeeklyTagChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
|
||||
@note: This method is a composite method. It is not provided directly by the
|
||||
last.fm API. It uses other methods to collect the data, analyzes it and
|
||||
creates a chart. So this method is a little heavy to call, as it does
|
||||
mulitple calls to the API.
|
||||
"""
|
||||
WeeklyChart._check_chart_params({}, start, end)
|
||||
return WeeklyTagChart.create_from_data(self._api, self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_tag_chart(self):
|
||||
"""
|
||||
most recent tag chart for the group
|
||||
@rtype: L{WeeklyTagChart}
|
||||
"""
|
||||
return self.get_weekly_tag_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_tag_chart_list(self):
|
||||
"""
|
||||
a list of all tag charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyTagChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_tag_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
@cached_property
|
||||
@depaginate
|
||||
|
|
|
@ -10,5 +10,8 @@ from lastfm.mixins.searchable import Searchable
|
|||
from lastfm.mixins.sharable import Sharable
|
||||
from lastfm.mixins.shoutable import Shoutable
|
||||
from lastfm.mixins.taggable import Taggable
|
||||
from lastfm.mixins.chartable import (
|
||||
AlbumChartable, ArtistChartable, TrackChartable, TagChartable)
|
||||
|
||||
__all__ = ['Cacheable', 'Searchable', 'Sharable', 'Shoutable', 'Taggable']
|
||||
__all__ = ['Cacheable', 'Searchable', 'Sharable', 'Shoutable', 'Taggable'
|
||||
'AlbumChartable', 'ArtistChartable', 'TrackChartable', 'TagChartable']
|
|
@ -0,0 +1,432 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||
__version__ = "0.2"
|
||||
__license__ = "GNU Lesser General Public License"
|
||||
__package__ = "lastfm.mixins"
|
||||
|
||||
from lastfm.lazylist import lazylist
|
||||
from lastfm.decorators import cached_property
|
||||
|
||||
class Chartable(object):
|
||||
def init(self, api):
|
||||
self._api = api
|
||||
|
||||
@cached_property
|
||||
def weekly_chart_list(self):
|
||||
"""
|
||||
a list of available weekly charts for this group
|
||||
@rtype: L{list} of L{WeeklyChart}
|
||||
"""
|
||||
from lastfm.chart import WeeklyChart
|
||||
params = self._default_params(
|
||||
{'method': '%s.getWeeklyChartList' % self.__class__.__name__.lower()})
|
||||
data = self._api._fetch_data(params).find('weeklychartlist')
|
||||
return [
|
||||
WeeklyChart.create_from_data(self._api, self, c)
|
||||
for c in data.findall('chart')
|
||||
]
|
||||
|
||||
@cached_property
|
||||
def monthly_chart_list(self):
|
||||
from lastfm.chart import MonthlyChart
|
||||
return MonthlyChart.get_chart_list(self)
|
||||
|
||||
def _default_params(self, extra_params = None):
|
||||
if extra_params is not None:
|
||||
return extra_params
|
||||
else:
|
||||
return {}
|
||||
|
||||
class AlbumChartable(Chartable):
|
||||
def get_weekly_album_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get an album chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent album chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: an album chart for the group
|
||||
@rtype: L{WeeklyAlbumChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
"""
|
||||
from lastfm.chart import WeeklyChart, WeeklyAlbumChart
|
||||
params = self._default_params(
|
||||
{'method': '%s.getWeeklyAlbumChart' % self.__class__.__name__.lower()})
|
||||
params = WeeklyChart._check_chart_params(params, self, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklyalbumchart')
|
||||
return WeeklyAlbumChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_album_chart(self):
|
||||
"""
|
||||
most recent album chart for the group
|
||||
@rtype: L{WeeklyAlbumChart}
|
||||
"""
|
||||
return self.get_weekly_album_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_album_chart_list(self):
|
||||
"""
|
||||
a list of all album charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyAlbumChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_album_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_monthly_album_chart(self, start = None, end = None):
|
||||
from lastfm.chart import MonthlyAlbumChart
|
||||
return MonthlyAlbumChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_monthly_album_chart(self):
|
||||
return self.get_monthly_album_chart()
|
||||
|
||||
@cached_property
|
||||
def monthly_album_chart_list(self):
|
||||
mcl = list(self.monthly_chart_list)
|
||||
mcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for mc in mcl:
|
||||
try:
|
||||
yield self.get_monthly_album_chart(mc.start, mc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_quaterly_album_chart(self, start = None, end = None):
|
||||
from lastfm.chart import QuaterlyAlbumChart
|
||||
return QuaterlyAlbumChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_quaterly_album_chart(self):
|
||||
return self.get_quaterly_album_chart()
|
||||
|
||||
def get_half_yearly_album_chart(self, start = None, end = None):
|
||||
from lastfm.chart import HalfYearlyAlbumChart
|
||||
return HalfYearlyAlbumChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_half_yearly_album_chart(self):
|
||||
return self.get_half_yearly_album_chart()
|
||||
|
||||
def get_yearly_album_chart(self, start = None, end = None):
|
||||
from lastfm.chart import YearlyAlbumChart
|
||||
return YearlyAlbumChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_yearly_album_chart(self):
|
||||
return self.get_yearly_album_chart()
|
||||
|
||||
class ArtistChartable(Chartable):
|
||||
def get_weekly_artist_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get an artist chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent artist chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: an artist chart for the group
|
||||
@rtype: L{WeeklyArtistChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
"""
|
||||
from lastfm.chart import WeeklyChart, WeeklyArtistChart
|
||||
params = self._default_params(
|
||||
{'method': '%s.getWeeklyArtistChart' % self.__class__.__name__.lower()})
|
||||
params = WeeklyChart._check_chart_params(params, self, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklyartistchart')
|
||||
return WeeklyArtistChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_artist_chart(self):
|
||||
"""
|
||||
most recent artist chart for the group
|
||||
@rtype: L{WeeklyArtistChart}
|
||||
"""
|
||||
return self.get_weekly_artist_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_artist_chart_list(self):
|
||||
"""
|
||||
a list of all artist charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyArtistChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_artist_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_monthly_artist_chart(self, start = None, end = None):
|
||||
from lastfm.chart import MonthlyArtistChart
|
||||
return MonthlyArtistChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_monthly_artist_chart(self):
|
||||
return self.get_monthly_artist_chart()
|
||||
|
||||
@cached_property
|
||||
def monthly_artist_chart_list(self):
|
||||
mcl = list(self.monthly_chart_list)
|
||||
mcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for mc in mcl:
|
||||
try:
|
||||
yield self.get_monthly_artist_chart(mc.start, mc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_quaterly_artist_chart(self, start = None, end = None):
|
||||
from lastfm.chart import QuaterlyArtistChart
|
||||
return QuaterlyArtistChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_quaterly_artist_chart(self):
|
||||
return self.get_quaterly_artist_chart()
|
||||
|
||||
def get_half_yearly_artist_chart(self, start = None, end = None):
|
||||
from lastfm.chart import HalfYearlyArtistChart
|
||||
return HalfYearlyArtistChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_half_yearly_artist_chart(self):
|
||||
return self.get_half_yearly_artist_chart()
|
||||
|
||||
def get_yearly_artist_chart(self, start = None, end = None):
|
||||
from lastfm.chart import YearlyArtistChart
|
||||
return YearlyArtistChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_yearly_album_chart(self):
|
||||
return self.get_yearly_artist_chart()
|
||||
|
||||
class TrackChartable(Chartable):
|
||||
def get_weekly_track_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get a track chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent artist chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: a track chart for the group
|
||||
@rtype: L{WeeklyTrackChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
"""
|
||||
from lastfm.chart import WeeklyChart, WeeklyTrackChart
|
||||
params = self._default_params(
|
||||
{'method': '%s.getWeeklyTrackChart' % self.__class__.__name__.lower()})
|
||||
params = WeeklyChart._check_chart_params(params, self, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklytrackchart')
|
||||
return WeeklyTrackChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_track_chart(self):
|
||||
"""
|
||||
most recent track chart for the group
|
||||
@rtype: L{WeeklyTrackChart}
|
||||
"""
|
||||
return self.get_weekly_track_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_track_chart_list(self):
|
||||
"""
|
||||
a list of all track charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyTrackChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_track_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_monthly_track_chart(self, start = None, end = None):
|
||||
from lastfm.chart import MonthlyTrackChart
|
||||
return MonthlyTrackChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_monthly_track_chart(self):
|
||||
return self.get_monthly_track_chart()
|
||||
|
||||
@cached_property
|
||||
def monthly_track_chart_list(self):
|
||||
mcl = list(self.monthly_chart_list)
|
||||
mcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for mc in mcl:
|
||||
try:
|
||||
yield self.get_monthly_track_chart(mc.start, mc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_quaterly_track_chart(self, start = None, end = None):
|
||||
from lastfm.chart import QuaterlyTrackChart
|
||||
return QuaterlyTrackChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_quaterly_track_chart(self):
|
||||
return self.get_quaterly_track_chart()
|
||||
|
||||
def get_half_yearly_track_chart(self, start = None, end = None):
|
||||
from lastfm.chart import HalfYearlyTrackChart
|
||||
return HalfYearlyTrackChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_half_yearly_artist_chart(self):
|
||||
return self.get_half_yearly_track_chart()
|
||||
|
||||
def get_yearly_track_chart(self, start = None, end = None):
|
||||
from lastfm.chart import YearlyTrackChart
|
||||
return YearlyTrackChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_yearly_album_chart(self):
|
||||
return self.get_yearly_track_chart()
|
||||
|
||||
class TagChartable(Chartable):
|
||||
def get_weekly_tag_chart(self, start = None, end = None):
|
||||
"""
|
||||
Get a tag chart for the group, for a given date range.
|
||||
If no date range is supplied, it will return the most
|
||||
recent tag chart for the group.
|
||||
|
||||
@param start: the date at which the chart should start from (optional)
|
||||
@type start: C{datetime.datetime}
|
||||
@param end: the date at which the chart should end on (optional)
|
||||
@type end: C{datetime.datetime}
|
||||
|
||||
@return: a tag chart for the group
|
||||
@rtype: L{WeeklyTagChart}
|
||||
|
||||
@raise InvalidParametersError: Both start and end parameter have to be either
|
||||
provided or not provided. Providing only one of
|
||||
them will raise an exception.
|
||||
|
||||
@note: This method is a composite method. It is not provided directly by the
|
||||
last.fm API. It uses other methods to collect the data, analyzes it and
|
||||
creates a chart. So this method is a little heavy to call, as it does
|
||||
mulitple calls to the API.
|
||||
"""
|
||||
from lastfm.chart import WeeklyChart, WeeklyTagChart
|
||||
WeeklyChart._check_chart_params({}, self, start, end)
|
||||
return WeeklyTagChart.create_from_data(self._api, self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_tag_chart(self):
|
||||
"""
|
||||
most recent tag chart for the group
|
||||
@rtype: L{WeeklyTagChart}
|
||||
"""
|
||||
return self.get_weekly_tag_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_tag_chart_list(self):
|
||||
"""
|
||||
a list of all tag charts for this group in reverse-chronological
|
||||
order. (that means 0th chart is the most recent chart)
|
||||
@rtype: L{lazylist} of L{WeeklyTagChart}
|
||||
"""
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_tag_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_monthly_tag_chart(self, start = None, end = None):
|
||||
from lastfm.chart import MonthlyTagChart
|
||||
return MonthlyTagChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_monthly_tag_chart(self):
|
||||
return self.get_monthly_tag_chart()
|
||||
|
||||
@cached_property
|
||||
def monthly_tag_chart_list(self):
|
||||
mcl = list(self.monthly_chart_list)
|
||||
mcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for mc in mcl:
|
||||
try:
|
||||
yield self.get_monthly_tag_chart(mc.start, mc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_quaterly_tag_chart(self, start = None, end = None):
|
||||
from lastfm.chart import QuaterlyTagChart
|
||||
return QuaterlyTagChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_quaterly_tag_chart(self):
|
||||
return self.get_quaterly_tag_chart()
|
||||
|
||||
def get_half_yearly_tag_chart(self, start = None, end = None):
|
||||
from lastfm.chart import HalfYearlyTagChart
|
||||
return HalfYearlyTagChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_half_yearly_artist_chart(self):
|
||||
return self.get_half_yearly_tag_chart()
|
||||
|
||||
def get_yearly_tag_chart(self, start = None, end = None):
|
||||
from lastfm.chart import YearlyTagChart
|
||||
return YearlyTagChart.create_from_data(self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_yearly_album_chart(self):
|
||||
return self.get_yearly_tag_chart()
|
||||
|
||||
from lastfm.error import LastfmError
|
||||
|
|
@ -6,11 +6,11 @@ __license__ = "GNU Lesser General Public License"
|
|||
__package__ = "lastfm"
|
||||
|
||||
from lastfm.base import LastfmBase
|
||||
from lastfm.mixins import Cacheable, Searchable
|
||||
from lastfm.lazylist import lazylist
|
||||
from lastfm.mixins import (
|
||||
Cacheable, Searchable, ArtistChartable)
|
||||
from lastfm.decorators import cached_property, top_property
|
||||
|
||||
class Tag(LastfmBase, Cacheable, Searchable):
|
||||
class Tag(LastfmBase, Cacheable, Searchable, ArtistChartable):
|
||||
"""A class representing a tag."""
|
||||
def init(self,
|
||||
api,
|
||||
|
@ -21,6 +21,8 @@ class Tag(LastfmBase, Cacheable, Searchable):
|
|||
**kwargs):
|
||||
if not isinstance(api, Api):
|
||||
raise InvalidParametersError("api reference must be supplied as an argument")
|
||||
ArtistChartable.init(self, api)
|
||||
|
||||
self._api = api
|
||||
self._name = name
|
||||
self._url = url
|
||||
|
@ -172,44 +174,7 @@ class Tag(LastfmBase, Cacheable, Searchable):
|
|||
def playlist(self):
|
||||
return Playlist.fetch(self._api,
|
||||
"lastfm://playlist/tag/%s/freetracks" % self.name)
|
||||
|
||||
@cached_property
|
||||
def weekly_chart_list(self):
|
||||
params = self._default_params({'method': 'tag.getWeeklyChartList'})
|
||||
data = self._api._fetch_data(params).find('weeklychartlist')
|
||||
return [
|
||||
WeeklyChart.create_from_data(self._api, self, c)
|
||||
for c in data.findall('chart')
|
||||
]
|
||||
|
||||
def get_weekly_artist_chart(self,
|
||||
start = None,
|
||||
end = None,
|
||||
limit = None):
|
||||
params = self._default_params({'method': 'tag.getWeeklyArtistChart'})
|
||||
if limit is not None:
|
||||
params['limit'] = limit
|
||||
params = WeeklyArtistChart._check_chart_params(params, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklyartistchart')
|
||||
return WeeklyArtistChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_artist_chart(self):
|
||||
return self.get_weekly_artist_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_artist_chart_list(self):
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_artist_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_top_tags(api):
|
||||
params = {'method': 'tag.getTopTags'}
|
||||
|
|
125
lastfm/user.py
125
lastfm/user.py
|
@ -6,12 +6,16 @@ __license__ = "GNU Lesser General Public License"
|
|||
__package__ = "lastfm"
|
||||
|
||||
from lastfm.base import LastfmBase
|
||||
from lastfm.mixins import Cacheable, Shoutable
|
||||
from lastfm.lazylist import lazylist
|
||||
from lastfm.mixins import (
|
||||
Cacheable, Shoutable, AlbumChartable,
|
||||
ArtistChartable, TrackChartable, TagChartable)
|
||||
import lastfm.playlist
|
||||
from lastfm.decorators import cached_property, top_property, authentication_required, depaginate
|
||||
from lastfm.decorators import (
|
||||
cached_property, top_property, authentication_required, depaginate)
|
||||
|
||||
class User(LastfmBase, Cacheable, Shoutable):
|
||||
class User(LastfmBase, Cacheable, Shoutable,
|
||||
AlbumChartable, ArtistChartable,
|
||||
TrackChartable, TagChartable):
|
||||
"""A class representing an user."""
|
||||
def init(self,
|
||||
api,
|
||||
|
@ -24,6 +28,11 @@ class User(LastfmBase, Cacheable, Shoutable):
|
|||
if not isinstance(api, Api):
|
||||
raise InvalidParametersError("api reference must be supplied as an argument")
|
||||
Shoutable.init(self, api)
|
||||
AlbumChartable.init(self, api)
|
||||
ArtistChartable.init(self, api)
|
||||
TrackChartable.init(self, api)
|
||||
TagChartable.init(self, api)
|
||||
|
||||
self._api = api
|
||||
self._name = name
|
||||
self._real_name = real_name
|
||||
|
@ -478,113 +487,6 @@ class User(LastfmBase, Cacheable, Shoutable):
|
|||
"""top tag of the user"""
|
||||
pass
|
||||
|
||||
@cached_property
|
||||
def weekly_chart_list(self):
|
||||
params = self._default_params({'method': 'user.getWeeklyChartList'})
|
||||
data = self._api._fetch_data(params).find('weeklychartlist')
|
||||
return [
|
||||
WeeklyChart.create_from_data(self._api, self, c)
|
||||
for c in data.findall('chart')
|
||||
]
|
||||
|
||||
def get_weekly_album_chart(self,
|
||||
start = None,
|
||||
end = None):
|
||||
params = self._default_params({'method': 'user.getWeeklyAlbumChart'})
|
||||
params = WeeklyChart._check_chart_params(params, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklyalbumchart')
|
||||
return WeeklyAlbumChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_album_chart(self):
|
||||
return self.get_weekly_album_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_album_chart_list(self):
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_album_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_weekly_artist_chart(self,
|
||||
start = None,
|
||||
end = None):
|
||||
params = self._default_params({'method': 'user.getWeeklyArtistChart'})
|
||||
params = WeeklyChart._check_chart_params(params, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklyartistchart')
|
||||
return WeeklyArtistChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_artist_chart(self):
|
||||
return self.get_weekly_artist_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_artist_chart_list(self):
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_artist_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_weekly_track_chart(self,
|
||||
start = None,
|
||||
end = None):
|
||||
params = self._default_params({'method': 'user.getWeeklyTrackChart'})
|
||||
params = WeeklyChart._check_chart_params(params, start, end)
|
||||
data = self._api._fetch_data(params).find('weeklytrackchart')
|
||||
return WeeklyTrackChart.create_from_data(self._api, self, data)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_track_chart(self):
|
||||
return self.get_weekly_track_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_track_chart_list(self):
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_track_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def get_weekly_tag_chart(self,
|
||||
start = None,
|
||||
end = None):
|
||||
WeeklyChart._check_chart_params({}, start, end)
|
||||
return WeeklyTagChart.create_from_data(self._api, self, start, end)
|
||||
|
||||
@cached_property
|
||||
def recent_weekly_tag_chart(self):
|
||||
return self.get_weekly_tag_chart()
|
||||
|
||||
@cached_property
|
||||
def weekly_tag_chart_list(self):
|
||||
wcl = list(self.weekly_chart_list)
|
||||
wcl.reverse()
|
||||
@lazylist
|
||||
def gen(lst):
|
||||
for wc in wcl:
|
||||
try:
|
||||
yield self.get_weekly_tag_chart(wc.start, wc.end)
|
||||
except LastfmError:
|
||||
pass
|
||||
return gen()
|
||||
|
||||
def compare(self, other, limit = None):
|
||||
if isinstance(other, User):
|
||||
other = other.name
|
||||
|
@ -920,4 +822,3 @@ from lastfm.stats import Stats
|
|||
from lastfm.tag import Tag
|
||||
from lastfm.tasteometer import Tasteometer
|
||||
from lastfm.track import Track
|
||||
from lastfm.chart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart, WeeklyTagChart
|
||||
|
|
Loading…
Reference in New Issue