* renamed lastfm.mixins module to lastfm.mixin
* group utility modules in lastfm.util module * made related changesmaster
parent
2219c5b0ad
commit
e0c0277336
|
@ -23,7 +23,7 @@ from lastfm.event import Event
|
||||||
from lastfm.geo import Location, Country
|
from lastfm.geo import Location, Country
|
||||||
from lastfm.group import Group
|
from lastfm.group import Group
|
||||||
from lastfm.playlist import Playlist
|
from lastfm.playlist import Playlist
|
||||||
from lastfm.objectcache import ObjectCache
|
from lastfm.util import ObjectCache
|
||||||
from lastfm.tag import Tag
|
from lastfm.tag import Tag
|
||||||
from lastfm.tasteometer import Tasteometer
|
from lastfm.tasteometer import Tasteometer
|
||||||
from lastfm.track import Track
|
from lastfm.track import Track
|
||||||
|
|
|
@ -7,7 +7,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, searchable, taggable, crawlable
|
from lastfm.mixin import cacheable, searchable, taggable, crawlable
|
||||||
from lastfm.decorators import cached_property, top_property
|
from lastfm.decorators import cached_property, top_property
|
||||||
|
|
||||||
@crawlable
|
@crawlable
|
||||||
|
|
|
@ -656,10 +656,7 @@ class Api(object):
|
||||||
self._last_fetch_time = datetime.now()
|
self._last_fetch_time = datetime.now()
|
||||||
return url_data
|
return url_data
|
||||||
|
|
||||||
def _fetch_url(self,
|
def _fetch_url(self, url, parameters = None, no_cache = False):
|
||||||
url,
|
|
||||||
parameters = None,
|
|
||||||
no_cache = False):
|
|
||||||
# Add key/value parameters to the query string of the url
|
# Add key/value parameters to the query string of the url
|
||||||
url = self._build_url(url, extra_params=parameters)
|
url = self._build_url(url, extra_params=parameters)
|
||||||
if self._debug:
|
if self._debug:
|
||||||
|
@ -780,7 +777,7 @@ from lastfm.artist import Artist
|
||||||
from lastfm.error import error_map, LastfmError, OperationFailedError, AuthenticationFailedError,\
|
from lastfm.error import error_map, LastfmError, OperationFailedError, AuthenticationFailedError,\
|
||||||
InvalidParametersError
|
InvalidParametersError
|
||||||
from lastfm.event import Event
|
from lastfm.event import Event
|
||||||
from lastfm.filecache import FileCache
|
from lastfm.util import FileCache
|
||||||
from lastfm.geo import Location, Country
|
from lastfm.geo import Location, Country
|
||||||
from lastfm.group import Group
|
from lastfm.group import Group
|
||||||
from lastfm.playlist import Playlist
|
from lastfm.playlist import Playlist
|
||||||
|
|
|
@ -7,7 +7,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, searchable, sharable, shoutable, taggable, crawlable
|
from lastfm.mixin import cacheable, searchable, sharable, shoutable, taggable, crawlable
|
||||||
from lastfm.decorators import cached_property, top_property
|
from lastfm.decorators import cached_property, top_property
|
||||||
|
|
||||||
@crawlable
|
@crawlable
|
||||||
|
|
|
@ -6,8 +6,6 @@ __version__ = "0.2"
|
||||||
__license__ = "GNU Lesser General Public License"
|
__license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.lazylist import lazylist
|
|
||||||
|
|
||||||
class LastfmBase(object):
|
class LastfmBase(object):
|
||||||
"""Base class for all the classes in this package"""
|
"""Base class for all the classes in this package"""
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ __package__ = "lastfm"
|
||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable
|
from lastfm.mixin import cacheable
|
||||||
from operator import xor
|
from operator import xor
|
||||||
|
|
||||||
@cacheable
|
@cacheable
|
||||||
|
|
|
@ -112,7 +112,7 @@ def depaginate(func, *args, **kwargs):
|
||||||
a L{lazylist} of all search results (all pages)
|
a L{lazylist} of all search results (all pages)
|
||||||
@rtype: C{function}
|
@rtype: C{function}
|
||||||
"""
|
"""
|
||||||
from lastfm.lazylist import lazylist
|
from lastfm.util import lazylist
|
||||||
@lazylist
|
@lazylist
|
||||||
def generator(lst):
|
def generator(lst):
|
||||||
gen = func(*args, **kwargs)
|
gen = func(*args, **kwargs)
|
||||||
|
|
|
@ -7,7 +7,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, sharable, shoutable, crawlable
|
from lastfm.mixin import cacheable, sharable, shoutable, crawlable
|
||||||
|
|
||||||
@crawlable
|
@crawlable
|
||||||
@shoutable
|
@shoutable
|
||||||
|
|
|
@ -8,7 +8,7 @@ __package__ = "lastfm"
|
||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, crawlable
|
from lastfm.mixin import cacheable, crawlable
|
||||||
from lastfm.decorators import cached_property, top_property, depaginate
|
from lastfm.decorators import cached_property, top_property, depaginate
|
||||||
|
|
||||||
class Geo(object):
|
class Geo(object):
|
||||||
|
|
|
@ -7,7 +7,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, chartable
|
from lastfm.mixin import cacheable, chartable
|
||||||
from lastfm.decorators import cached_property, depaginate
|
from lastfm.decorators import cached_property, depaginate
|
||||||
|
|
||||||
@chartable(['album', 'artist', 'track', 'tag'])
|
@chartable(['album', 'artist', 'track', 'tag'])
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
from lastfm.mixin._cacheable import cacheable
|
||||||
|
from lastfm.mixin._searchable import searchable
|
||||||
|
from lastfm.mixin._sharable import sharable
|
||||||
|
from lastfm.mixin._shoutable import shoutable
|
||||||
|
from lastfm.mixin._taggable import taggable
|
||||||
|
from lastfm.mixin._chartable import chartable
|
||||||
|
from lastfm.mixin._crawlable import crawlable
|
||||||
|
|
||||||
|
__all__ = ['cacheable', 'searchable', 'sharable', 'shoutable', 'taggable'
|
||||||
|
'chartable','crawlable']
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
try:
|
||||||
|
from threading import Lock
|
||||||
|
except ImportError:
|
||||||
|
from dummy_threading import Lock
|
||||||
|
from lastfm.util import ObjectCache
|
||||||
|
|
||||||
|
_lock = Lock()
|
||||||
|
|
||||||
|
def cacheable(cls):
|
||||||
|
@classmethod
|
||||||
|
def __new__(cls, *args, **kwds):
|
||||||
|
args = args[1:]
|
||||||
|
subject = None
|
||||||
|
if 'subject' in kwds and not 'Weekly' in cls.__name__:
|
||||||
|
subject = kwds['subject']
|
||||||
|
#del kwds['subject']
|
||||||
|
|
||||||
|
if 'bypass_registry' in kwds:
|
||||||
|
del kwds['bypass_registry']
|
||||||
|
inst = object.__new__(cls)
|
||||||
|
inst.init(*args, **kwds)
|
||||||
|
return inst
|
||||||
|
|
||||||
|
key = cls._hash_func(*args, **kwds)
|
||||||
|
if subject is not None:
|
||||||
|
key = (hash(subject), key)
|
||||||
|
|
||||||
|
with _lock:
|
||||||
|
inst, already_registered = ObjectCache.register(object.__new__(cls), key)
|
||||||
|
if not already_registered:
|
||||||
|
inst.init(*args, **kwds)
|
||||||
|
return inst
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _hash_func(*args, **kwds):
|
||||||
|
raise NotImplementedError("The subclass must override this method")
|
||||||
|
|
||||||
|
cls.__new__ = __new__
|
||||||
|
if not hasattr(cls, '_hash_func'):
|
||||||
|
cls._hash_func = _hash_func
|
||||||
|
|
||||||
|
if not hasattr(cls, '_mixins'):
|
||||||
|
cls._mixins = []
|
||||||
|
cls._mixins.append('__new__')
|
||||||
|
|
||||||
|
return cls
|
|
@ -0,0 +1,451 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
from lastfm.util import lazylist
|
||||||
|
from lastfm.decorators import cached_property
|
||||||
|
|
||||||
|
def chartable(chart_types):
|
||||||
|
def wrapper(cls):
|
||||||
|
@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 {}
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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_artist_chart(self):
|
||||||
|
return self.get_yearly_artist_chart()
|
||||||
|
|
||||||
|
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_track_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_track_chart(self):
|
||||||
|
return self.get_yearly_track_chart()
|
||||||
|
|
||||||
|
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_tag_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_tag_chart(self):
|
||||||
|
return self.get_yearly_tag_chart()
|
||||||
|
|
||||||
|
cls.weekly_chart_list = weekly_chart_list
|
||||||
|
cls.monthly_chart_list = monthly_chart_list
|
||||||
|
|
||||||
|
if not hasattr(cls, '_default_params'):
|
||||||
|
cls._default_params = _default_params
|
||||||
|
|
||||||
|
if not hasattr(cls, '_mixins'):
|
||||||
|
cls._mixins = []
|
||||||
|
cls._mixins.extend(['weekly_chart_list', 'monthly_chart_list'])
|
||||||
|
|
||||||
|
method_names = [
|
||||||
|
'get_weekly_%s_chart', 'recent_weekly_%s_chart', 'weekly_%s_chart_list',
|
||||||
|
'get_monthly_%s_chart', 'recent_monthly_%s_chart', 'monthly_%s_chart_list',
|
||||||
|
'get_quaterly_%s_chart', 'recent_quaterly_%s_chart',
|
||||||
|
'get_half_yearly_%s_chart', 'recent_half_yearly_%s_chart',
|
||||||
|
'get_yearly_%s_chart', 'recent_yearly_%s_chart'
|
||||||
|
]
|
||||||
|
for chart_type in chart_types:
|
||||||
|
for method_name in method_names:
|
||||||
|
setattr(cls, method_name % chart_type, locals()[method_name % chart_type])
|
||||||
|
cls._mixins.append(method_name % chart_type)
|
||||||
|
|
||||||
|
return cls
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
from lastfm.error import LastfmError
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
from lastfm.util import lazylist
|
||||||
|
|
||||||
|
def crawlable(cls):
|
||||||
|
_get_all = cls._get_all
|
||||||
|
@staticmethod
|
||||||
|
def get_all(seed):
|
||||||
|
seed, hash_attrs, spider_func = _get_all(seed)
|
||||||
|
@lazylist
|
||||||
|
def gen(lst):
|
||||||
|
seen = []
|
||||||
|
api = seed._api
|
||||||
|
|
||||||
|
def hash_dict(item):
|
||||||
|
return dict((a, getattr(item, a)) for a in hash_attrs)
|
||||||
|
|
||||||
|
seen.append(hash_dict(seed))
|
||||||
|
yield seed
|
||||||
|
for hsh in seen:
|
||||||
|
for n in spider_func(api, hsh):
|
||||||
|
if hash_dict(n) not in seen:
|
||||||
|
seen.append(hash_dict(n))
|
||||||
|
yield n
|
||||||
|
return gen()
|
||||||
|
|
||||||
|
cls.get_all = get_all
|
||||||
|
delattr(cls, '_get_all')
|
||||||
|
|
||||||
|
if not hasattr(cls, '_mixins'):
|
||||||
|
cls._mixins = []
|
||||||
|
cls._mixins.append('get_all')
|
||||||
|
return cls
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
from lastfm.decorators import depaginate
|
||||||
|
|
||||||
|
def searchable(cls):
|
||||||
|
@classmethod
|
||||||
|
@depaginate
|
||||||
|
def search(cls,
|
||||||
|
api,
|
||||||
|
search_item,
|
||||||
|
limit = None,
|
||||||
|
page = None,
|
||||||
|
**kwds):
|
||||||
|
from lastfm.api import Api
|
||||||
|
cls_name = cls.__name__.lower()
|
||||||
|
params = {
|
||||||
|
'method': '%s.search'%cls_name,
|
||||||
|
cls_name: search_item
|
||||||
|
}
|
||||||
|
for kwd in kwds:
|
||||||
|
if kwds[kwd] is not None:
|
||||||
|
params[kwd] = kwds[kwd]
|
||||||
|
|
||||||
|
if limit:
|
||||||
|
params.update({'limit': limit})
|
||||||
|
if page is not None:
|
||||||
|
params.update({'page': page})
|
||||||
|
|
||||||
|
data = api._fetch_data(params).find('results')
|
||||||
|
total_pages = int(data.findtext("{%s}totalResults" % Api.SEARCH_XMLNS))/ \
|
||||||
|
int(data.findtext("{%s}itemsPerPage" % Api.SEARCH_XMLNS)) + 1
|
||||||
|
yield total_pages
|
||||||
|
for a in data.findall('%smatches/%s'%(cls_name, cls_name)):
|
||||||
|
yield cls._search_yield_func(api, a)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _search_yield_func(api, search_term):
|
||||||
|
raise NotImplementedError("the subclass should implement this method")
|
||||||
|
|
||||||
|
cls.search = search
|
||||||
|
if not hasattr(cls, '_search_yield_func'):
|
||||||
|
cls._search_yield_func = _search_yield_func
|
||||||
|
|
||||||
|
if not hasattr(cls, '_mixins'):
|
||||||
|
cls._mixins = []
|
||||||
|
cls._mixins.append('search')
|
||||||
|
|
||||||
|
return cls
|
|
@ -0,0 +1,38 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
def sharable(cls):
|
||||||
|
def share(self, recipient, message = None):
|
||||||
|
from lastfm.user import User
|
||||||
|
params = self._default_params({'method': '%s.share' % self.__class__.__name__.lower()})
|
||||||
|
if message is not None:
|
||||||
|
params['message'] = message
|
||||||
|
|
||||||
|
if not isinstance(recipient, list):
|
||||||
|
recipient = [recipient]
|
||||||
|
|
||||||
|
for i in xrange(len(recipient)):
|
||||||
|
if isinstance(recipient[i], User):
|
||||||
|
recipient[i] = recipient[i].name
|
||||||
|
params['recipient'] = ",".join(recipient)
|
||||||
|
self._api._post_data(params)
|
||||||
|
|
||||||
|
def _default_params(self, extra_params = None):
|
||||||
|
if extra_params is not None:
|
||||||
|
return extra_params
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
cls.share = share
|
||||||
|
if not hasattr(cls, '_default_params'):
|
||||||
|
cls._default_params = _default_params
|
||||||
|
|
||||||
|
if not hasattr(cls, '_mixins'):
|
||||||
|
cls._mixins = []
|
||||||
|
cls._mixins.append('share')
|
||||||
|
|
||||||
|
return cls
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
from lastfm.decorators import cached_property, top_property
|
||||||
|
|
||||||
|
def shoutable(cls):
|
||||||
|
@cached_property
|
||||||
|
def shouts(self):
|
||||||
|
"""shouts for this %s""" % cls.__name__.lower()
|
||||||
|
from lastfm.shout import Shout
|
||||||
|
from lastfm.user import User
|
||||||
|
params = self._default_params({'method': '%s.getShouts' % self.__class__.__name__.lower()})
|
||||||
|
data = self._api._fetch_data(params).find('shouts')
|
||||||
|
return [
|
||||||
|
Shout(
|
||||||
|
body = s.findtext('body'),
|
||||||
|
author = User(self._api, name = s.findtext('author')),
|
||||||
|
date = s.findtext('date') and s.findtext('date').strip() and \
|
||||||
|
datetime(*(time.strptime(s.findtext('date').strip(), '%a, %d %b %Y %H:%M:%S')[0:6]))
|
||||||
|
)
|
||||||
|
for s in data.findall('shout')
|
||||||
|
]
|
||||||
|
|
||||||
|
@top_property("shouts")
|
||||||
|
def recent_shout(self):
|
||||||
|
"""recent shout for this %s""" % cls.__name__.lower()
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _default_params(self, extra_params = None):
|
||||||
|
if extra_params is not None:
|
||||||
|
return extra_params
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
cls.shouts = shouts
|
||||||
|
cls.recent_shout = recent_shout
|
||||||
|
if not hasattr(cls, '_default_params'):
|
||||||
|
cls._default_params = _default_params
|
||||||
|
|
||||||
|
if not hasattr(cls, '_mixins'):
|
||||||
|
cls._mixins = []
|
||||||
|
cls._mixins.extend(['shouts', 'recent_shout'])
|
||||||
|
|
||||||
|
return cls
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
import time
|
|
@ -0,0 +1,81 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.mixin"
|
||||||
|
|
||||||
|
from lastfm.util import SafeList
|
||||||
|
from lastfm.decorators import cached_property, authentication_required
|
||||||
|
|
||||||
|
def taggable(cls):
|
||||||
|
@cached_property
|
||||||
|
@authentication_required
|
||||||
|
def tags(self):
|
||||||
|
from lastfm.tag import Tag
|
||||||
|
params = self._default_params({'method': '%s.getTags' % self.__class__.__name__.lower()})
|
||||||
|
data = self._api._fetch_data(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.add_tags, self.remove_tag)
|
||||||
|
|
||||||
|
@authentication_required
|
||||||
|
def add_tags(self, tags):
|
||||||
|
from lastfm.tag import Tag
|
||||||
|
while(len(tags) > 10):
|
||||||
|
section = tags[0:9]
|
||||||
|
tags = tags[9:]
|
||||||
|
self.add_tags(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._default_params({
|
||||||
|
'method': '%s.addTags' % self.__class__.__name__.lower(),
|
||||||
|
'tags': ",".join(tagnames)
|
||||||
|
})
|
||||||
|
self._api._post_data(params)
|
||||||
|
self._tags = None
|
||||||
|
|
||||||
|
@authentication_required
|
||||||
|
def remove_tag(self, tag):
|
||||||
|
from lastfm.tag import Tag
|
||||||
|
if isinstance(tag, Tag):
|
||||||
|
tag = tag.name
|
||||||
|
|
||||||
|
params = self._default_params({
|
||||||
|
'method': '%s.removeTag' % self.__class__.__name__.lower(),
|
||||||
|
'tag': tag
|
||||||
|
})
|
||||||
|
self._api._post_data(params)
|
||||||
|
self._tags = None
|
||||||
|
|
||||||
|
def _default_params(self, extra_params = None):
|
||||||
|
if extra_params is not None:
|
||||||
|
return extra_params
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
cls.tags = tags
|
||||||
|
cls.add_tags = add_tags
|
||||||
|
cls.remove_tag = remove_tag
|
||||||
|
if not hasattr(cls, '_default_params'):
|
||||||
|
cls._default_params = _default_params
|
||||||
|
|
||||||
|
if not hasattr(cls, '_mixins'):
|
||||||
|
cls._mixins = []
|
||||||
|
cls._mixins.extend(['tags', 'add_tags', 'remove_tag'])
|
||||||
|
|
||||||
|
return cls
|
|
@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable
|
from lastfm.mixin import cacheable
|
||||||
from lastfm.decorators import cached_property
|
from lastfm.decorators import cached_property
|
||||||
|
|
||||||
@cacheable
|
@cacheable
|
||||||
|
|
|
@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable
|
from lastfm.mixin import cacheable
|
||||||
from lastfm.decorators import cached_property
|
from lastfm.decorators import cached_property
|
||||||
|
|
||||||
@cacheable
|
@cacheable
|
||||||
|
|
|
@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, searchable, chartable, crawlable
|
from lastfm.mixin import cacheable, searchable, chartable, crawlable
|
||||||
from lastfm.decorators import cached_property, top_property
|
from lastfm.decorators import cached_property, top_property
|
||||||
|
|
||||||
@crawlable
|
@crawlable
|
||||||
|
|
|
@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, searchable, sharable, taggable, crawlable
|
from lastfm.mixin import cacheable, searchable, sharable, taggable, crawlable
|
||||||
from lastfm.decorators import cached_property, top_property
|
from lastfm.decorators import cached_property, top_property
|
||||||
|
|
||||||
@crawlable
|
@crawlable
|
||||||
|
|
|
@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, shoutable, chartable, crawlable
|
from lastfm.mixin import cacheable, shoutable, chartable, crawlable
|
||||||
import lastfm.playlist
|
import lastfm.playlist
|
||||||
from lastfm.decorators import (
|
from lastfm.decorators import (
|
||||||
cached_property, top_property, authentication_required, depaginate)
|
cached_property, top_property, authentication_required, depaginate)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
|
__version__ = "0.2"
|
||||||
|
__license__ = "GNU Lesser General Public License"
|
||||||
|
__package__ = "lastfm.util"
|
||||||
|
|
||||||
|
from lastfm.util.wormhole import Wormhole
|
||||||
|
from lastfm.util.lazylist import lazylist
|
||||||
|
from lastfm.util.safelist import SafeList
|
||||||
|
from lastfm.util.filecache import FileCache
|
||||||
|
from lastfm.util.objectcache import ObjectCache
|
||||||
|
|
||||||
|
__all__ = ['Wormhole', 'lazylist', 'SafeList',
|
||||||
|
'FileCache', 'ObjectCache']
|
|
@ -4,7 +4,7 @@
|
||||||
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
__version__ = "0.2"
|
__version__ = "0.2"
|
||||||
__license__ = "GNU Lesser General Public License"
|
__license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm.util"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
if sys.version < '2.6':
|
if sys.version < '2.6':
|
|
@ -8,6 +8,7 @@ Backport to python 2.5 by Michael Pust
|
||||||
|
|
||||||
__author__ = 'Dan Spitz'
|
__author__ = 'Dan Spitz'
|
||||||
__all__ = ('LazyList', 'RecursiveLazyList', 'lazylist')
|
__all__ = ('LazyList', 'RecursiveLazyList', 'lazylist')
|
||||||
|
__package__ = "lastfm.util"
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
__version__ = "0.2"
|
__version__ = "0.2"
|
||||||
__license__ = "GNU Lesser General Public License"
|
__license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm.util"
|
||||||
|
|
||||||
_registry = {}
|
_registry = {}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||||
__version__ = "0.2"
|
__version__ = "0.2"
|
||||||
__license__ = "GNU Lesser General Public License"
|
__license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm.util"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
class SafeList(object):
|
class SafeList(object):
|
|
@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
||||||
__package__ = "lastfm"
|
__package__ = "lastfm"
|
||||||
|
|
||||||
from lastfm.base import LastfmBase
|
from lastfm.base import LastfmBase
|
||||||
from lastfm.mixins import cacheable, searchable, crawlable
|
from lastfm.mixin import cacheable, searchable, crawlable
|
||||||
from lastfm.decorators import cached_property, depaginate
|
from lastfm.decorators import cached_property, depaginate
|
||||||
|
|
||||||
@crawlable
|
@crawlable
|
||||||
|
|
Loading…
Reference in New Issue