]> kaliko git repositories - mpd-sima.git/blobdiff - sima/plugins/lastfm.py
Some hesitation regarding blacklist decorator…
[mpd-sima.git] / sima / plugins / lastfm.py
index 0bbddbd33f0e8ae8b767692877a1cdc0fb8e1715..679aaa6a78f52156972b8f4f6396ce625dd41a28 100644 (file)
@@ -7,6 +7,7 @@ Fetching similar artists from last.fm web services
 import random
 
 from collections import deque
+from itertools import dropwhile
 from hashlib import md5
 
 # third parties componants
@@ -35,6 +36,36 @@ def cache(func):
     return wrapper
 
 
+def blacklist(artist=False, album=False, track=False):
+    #pylint: disable=C0111,W0212
+    field = (artist, album, track)
+    def decorated(func):
+        def wrapper(*args, **kwargs):
+            cls = args[0]
+            boolgen = (bl for bl in field)
+            bl_fun = (cls._Plugin__daemon.sdb.get_bl_artist,
+                      cls._Plugin__daemon.sdb.get_bl_album,
+                      cls._Plugin__daemon.sdb.get_bl_track,)
+            #bl_getter = next(fn for fn, bl in zip(bl_fun, boolgen) if bl is True)
+            bl_getter = next(dropwhile(lambda _: not next(boolgen), bl_fun))
+            cls.log.debug('using {0} as bl filter'.format(bl_getter.__name__))
+            if artist:
+                results = func(*args, **kwargs)
+                for elem in results:
+                    if bl_getter(elem, add_not=True):
+                        cls.log.info('Blacklisted: {0}'.format(elem))
+                        results.remove(elem)
+                return results
+            if track:
+                for elem in args[1]:
+                    if bl_getter(elem, add_not=True):
+                        cls.log.info('Blacklisted: {0}'.format(elem))
+                        args[1].remove(elem)
+                return func(*args, **kwargs)
+        return wrapper
+    return decorated
+
+
 class Lastfm(Plugin):
     """last.fm similar artists
     """
@@ -73,7 +104,6 @@ class Lastfm(Plugin):
     def _cleanup_cache(self):
         """Avoid bloated cache
         """
-        # TODO: call cleanup once its dict instance are used somewhere XXX
         for _ , val in self._cache.items():
             if isinstance(val, dict):
                 while len(val) > 150:
@@ -89,11 +119,13 @@ class Lastfm(Plugin):
                                file=tr[3]) for tr in tracks_from_db]
         return played_tracks
 
+    #@blacklist(track=True)
     def filter_track(self, tracks):
         """
         Extract one unplayed track from a Track object list.
             * not in history
             * not already in the queue
+            * not blacklisted
         """
         artist = tracks[0].artist
         black_list = self.player.queue + self.to_add
@@ -101,12 +133,27 @@ class Lastfm(Plugin):
         if not not_in_hist:
             self.log.debug('All tracks already played for "{}"'.format(artist))
         random.shuffle(not_in_hist)
-        candidate = [ trk for trk in not_in_hist if trk not in black_list ]
+        #candidate = [ trk for trk in not_in_hist if trk not in black_list 
+                      #if not self.sdb.get_bl_track(trk, add_not=True)]
+        candidate = []
+        for trk in [_ for _ in not_in_hist if _ not in black_list]:
+            if self.sdb.get_bl_track(trk, add_not=True):
+                self.log.info('Blacklisted: {0}: '.format(trk))
+                continue
+            if self.sdb.get_bl_album(trk, add_not=True):
+                self.log.info('Blacklisted album: {0}: '.format(trk))
+                continue
+            candidate.append(trk)
         if not candidate:
             self.log.debug('Unable to find title to add' +
-                          ' for "%s".' % artist)
+                           ' for "%s".' % artist)
             return None
+        #@blacklist(track=True)
+        #def deco(self, args):
+            #return args
+        #candidate = deco(self, candidate)
         self.to_add.append(random.choice(candidate))
+        return self.to_add
 
     def _get_artists_list_reorg(self, alist):
         """
@@ -128,6 +175,7 @@ class Lastfm(Plugin):
                        ' / '.join(art_not_in_hist)))
         return art_not_in_hist
 
+    @blacklist(artist=True)
     @cache
     def get_artists_from_player(self, similarities):
         """
@@ -238,7 +286,7 @@ class Lastfm(Plugin):
             self.log.debug('Trying to find titles to add for "{}"'.format(
                            artist))
             found = self.player.find_track(artist)
-            # find tracks not in history
+            # find tracks not in history for artist
             self.filter_track(found)
             if len(self.to_add) == nbtracks_target:
                 break