From 45a5522be025d1fe62ab94cba8684c32c7e48d3f Mon Sep 17 00:00:00 2001 From: Abhinav Sarkar Date: Thu, 2 Apr 2009 18:12:44 +0000 Subject: [PATCH] added 'get_all' method in Album, Artist, Event, Tag, Track, User and LastfmBase classes. minor fixes. --- lastfm/album.py | 10 ++++++++++ lastfm/artist.py | 5 +++++ lastfm/base.py | 23 +++++++++++++++++++++++ lastfm/event.py | 11 +++++++++++ lastfm/mixins/_cacheable.py | 2 +- lastfm/objectcache.py | 2 +- lastfm/tag.py | 5 +++++ lastfm/track.py | 10 ++++++++++ lastfm/user.py | 16 ++++++++++++---- 9 files changed, 78 insertions(+), 6 deletions(-) diff --git a/lastfm/album.py b/lastfm/album.py index e05f770..fae347c 100644 --- a/lastfm/album.py +++ b/lastfm/album.py @@ -236,6 +236,16 @@ class Album(LastfmBase): ) a._fill_info() return a + + @classmethod + def get_all(cls, seed_album): + def gen(): + for artist in Artist.get_all(seed_album.artist): + for album in artist.top_albums: + yield album + + return super(Album, cls).get_all(seed_album, ['name', 'artist'], + lambda api, hsh: gen()) def _default_params(self, extra_params = {}): if not (self.artist and self.name): diff --git a/lastfm/artist.py b/lastfm/artist.py index d36df00..22da854 100644 --- a/lastfm/artist.py +++ b/lastfm/artist.py @@ -369,6 +369,11 @@ class Artist(LastfmBase): a = Artist(api, name = data.findtext('name')) a._fill_info() return a + + @classmethod + def get_all(cls,seed_artist): + return super(Artist, cls).get_all(seed_artist, ['name'], + lambda api, hsh: Artist(api, **hsh).similar) def _default_params(self, extra_params = None): if not self.name: diff --git a/lastfm/base.py b/lastfm/base.py index 3bbe7b9..30f65c2 100644 --- a/lastfm/base.py +++ b/lastfm/base.py @@ -6,9 +6,32 @@ __version__ = "0.2" __license__ = "GNU Lesser General Public License" __package__ = "lastfm" +from lastfm.lazylist import lazylist + class LastfmBase(object): """Base class for all the classes in this package""" + @classmethod + def get_all(cls, seed, hash_attrs, spider_func): + if cls == LastfmBase: + raise NotImplementedError("the subclass must implement this method") + @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() + def __eq__(self, other): raise NotImplementedError("The subclass must override this method") diff --git a/lastfm/event.py b/lastfm/event.py index a402118..e4a6354 100644 --- a/lastfm/event.py +++ b/lastfm/event.py @@ -288,6 +288,17 @@ class Event(LastfmBase): tag = data.findtext('tag') ) + @classmethod + def get_all(cls, seed_event): + def gen(): + for artist in Artist.get_all(seed_event.artists[0]): + for event in artist.events: + yield event + + return super(Event, cls).get_all(seed_event, ['id'], + lambda api, hsh: gen()) + + def _default_params(self, extra_params = None): if not self.id: raise InvalidParametersError("id has to be provided.") diff --git a/lastfm/mixins/_cacheable.py b/lastfm/mixins/_cacheable.py index 3100cc2..e74c04c 100644 --- a/lastfm/mixins/_cacheable.py +++ b/lastfm/mixins/_cacheable.py @@ -18,7 +18,7 @@ def cacheable(cls): def __new__(cls, *args, **kwds): args = args[1:] subject = None - if 'subject' in kwds and not cls.__name__.startswith('Weekly'): + if 'subject' in kwds and not 'Weekly' in cls.__name__: subject = kwds['subject'] #del kwds['subject'] diff --git a/lastfm/objectcache.py b/lastfm/objectcache.py index dafd448..e35d6f6 100644 --- a/lastfm/objectcache.py +++ b/lastfm/objectcache.py @@ -57,7 +57,7 @@ class ObjectCache(object): return [] def __repr__(self): - return "" + return "" % sum(self.stats.values()) from weakref import WeakValueDictionary from lastfm.error import InvalidParametersError \ No newline at end of file diff --git a/lastfm/tag.py b/lastfm/tag.py index 30454fc..7c5451d 100644 --- a/lastfm/tag.py +++ b/lastfm/tag.py @@ -193,6 +193,11 @@ class Tag(LastfmBase): for t in data.findall('tag') ] + @classmethod + def get_all(cls, seed_tag): + return super(Tag, cls).get_all(seed_tag, ['name'], + lambda api, hsh: Tag(api, **hsh).similar) + def _default_params(self, extra_params = None): if not self.name: raise InvalidParametersError("tag has to be provided.") diff --git a/lastfm/track.py b/lastfm/track.py index db6bb33..eb33f9e 100644 --- a/lastfm/track.py +++ b/lastfm/track.py @@ -272,6 +272,16 @@ class Track(LastfmBase): ) t._fill_info() return t + + @classmethod + def get_all(cls, seed_track): + def gen(): + for artist in Artist.get_all(seed_track.artist): + for track in artist.top_tracks: + yield track + + return super(Track, cls).get_all(seed_track, ['name', 'artist'], + lambda api, hsh: gen()) def _default_params(self, extra_params = None): if not (self.artist and self.name): diff --git a/lastfm/user.py b/lastfm/user.py index 3c13d24..48f3929 100644 --- a/lastfm/user.py +++ b/lastfm/user.py @@ -202,7 +202,7 @@ class User(LastfmBase): @top_property("neighbours") def nearest_neighbour(self): - """nearest neightbour of the user""" + """nearest neighbour of the user""" pass @cached_property @@ -450,7 +450,7 @@ class User(LastfmBase): @top_property("top_tracks") def top_track(self): """top track of the user""" - return (len(self.top_tracks) and self.top_tracks[0] or None) + pass def get_top_tags(self, limit = None): params = self._default_params({'method': 'user.getTopTags'}) @@ -500,8 +500,11 @@ class User(LastfmBase): return user else: f = friends[0] - user = [a for a in f.friends if a.name == user.name][0] - return user + try: + user = [a for a in f.friends if a.name == user.name][0] + return user + except IndexError: + return user @staticmethod def get_authenticated_user(api): @@ -518,6 +521,11 @@ class User(LastfmBase): user._subscriber = (data.findtext('subscriber') == "1") user._stats = Stats(subject = user, playcount = data.findtext('playcount')) return user + + @classmethod + def get_all(cls,seed_user): + return super(User, cls).get_all(seed_user, ['name'], + lambda api, hsh: User(api, **hsh).neighbours) def _default_params(self, extra_params = None): if not self.name: