]> kaliko git repositories - mpd-sima.git/commitdiff
Random fallback plugin, honoring MPD/host, more robust plugin
authorkaliko <efrim@azylum.org>
Thu, 3 Oct 2013 18:44:59 +0000 (20:44 +0200)
committerkaliko <efrim@azylum.org>
Thu, 3 Oct 2013 18:44:59 +0000 (20:44 +0200)
doc/examples/all_settings.cfg
launch
sima/core.py
sima/lib/plugin.py
sima/plugins/lastfm.py
sima/plugins/randomfallback.py [new file with mode: 0644]
sima/utils/config.py

index 1d0fb6ff44fad4eec21790ab4bda43c8c052f602..c08c1c9f303bb26c6090e56dfaed0374d96317e9 100644 (file)
@@ -58,6 +58,14 @@ verbosity = info
 [placeholder]
 key = Value
 
+[RandomFallback]
+# random falvour :
+#  * pure:     complete ramdom choice among all tracks available in the player media library
+#  * sensible: use play history to filter chosen tracks
+#  * genre:    chose among the same genre as current track (tagged genre). If
+#              no genre tag is available "sensible" flavour is used instead
+flavour=pure
+
 [lastfm]
 
 depth = 3
diff --git a/launch b/launch
index bf841291a345b87afe03cd4914e35be2b819fe6d..e4c44b5c8207fcd30c70024ecb73fab985e2cb9f 100755 (executable)
--- a/launch
+++ b/launch
@@ -8,7 +8,7 @@ import logging
 import sys
 
 from importlib import __import__
-from os.path import isfile, basename
+from os.path import isfile
 ##
 
 # third parties components
@@ -27,10 +27,11 @@ from sima.plugins.crop import Crop
 from sima.plugins.addhist import History
 from sima.plugins.lastfm import Lastfm
 from sima.plugins.mpd import MpdOptions
+from sima.plugins.randomfallback import RandomFallBack
 
 # official plugins to start
 PLUGINS = (Crop, History, MpdOptions,
-           Lastfm)
+           Lastfm, RandomFallBack)
 
 
 def load_contrib_plugins(sima):
index 2d8b960b23e876351a9e234358028d0951f81f2b..ad21db6f16da571b46d7f8b7ac68253c04421f7c 100644 (file)
@@ -26,13 +26,20 @@ class Sima(object):
         self.sdb = SimaDB(db_path=dbfile)
         self.log = getLogger('sima')
         self.plugins = list()
-        self.player = PlayerClient()  # Player client
+        self.player = self._get_player()  # Player client
         try:
             self.player.connect()
         except (PlayerError, PlayerUnHandledError) as err:
             self.log.error('Fails to connect player: {}'.format(err))
             self.shutdown()
-        self.short_history = deque(maxlen=40)
+        self.short_history = deque(maxlen=60)
+
+    def _get_player(self):
+        """Instanciate the player"""
+        host = self.config.get('MPD', 'host')
+        port = self.config.get('MPD', 'port')
+        pswd = self.config.get('MPD', 'password', fallback=None)
+        return PlayerClient(host, port, pswd)
 
     def add_history(self):
         self.short_history.appendleft(self.player.current)
@@ -65,6 +72,13 @@ class Sima(object):
             pl_callback =  getattr(plugin, 'callback_need_track')()
             if pl_callback:
                 to_add.extend(pl_callback)
+        if not to_add:
+            self.log.warning('Queue plugins returned anything!')
+            for plugin in self.plugins:
+                self.log.info('calling fb for {}'.format(plugin))
+                pl_callback =  getattr(plugin, 'callback_need_track_fb')()
+                if pl_callback:
+                    to_add.extend(pl_callback)
         for track in to_add:
             self.player.add(track)
 
index 999255f956ce0ff6e0c23ab8230a38129aaf7cc6..d44abafda47cd6eb142233c97d0d29252d47dedd 100644 (file)
@@ -15,8 +15,11 @@ class Plugin():
     def info(cls):
         """self documenting class method
         """
+        doc = 'Undocumented plugin! Fill "{}" docstring'.format(cls.__name__)
+        if cls.__doc__:
+            doc = cls.__doc__.strip(' \n').splitlines()[0]
         return {'name': cls.__name__,
-                'doc': cls.__doc__.strip(' \n').splitlines()[0]
+                'doc': doc,
                 }
 
     def __init__(self, daemon):
@@ -70,6 +73,12 @@ class Plugin():
         """
         pass
 
+    def callback_need_track_fb(self):
+        """Called when callback_next_song failled to find tracks to queue
+        Returns a list of Track objects to add
+        """
+        pass
+
     def shutdown(self):
         pass
 
index 01e8cd98160625bf7905d4479e4376c1ff07a690..7f2397a8eb13f38f81f6c90b08a940b234abec15 100644 (file)
@@ -79,12 +79,11 @@ class Lastfm(Plugin):
         """
         for _ , val in self._cache.items():
             if isinstance(val, dict):
-                while len(val) > 100:
+                while len(val) > 150:
                     val.popitem()
 
     def get_history(self, artist):
-        """Check against history for tracks already in history for a specific
-        artist.
+        """Constructs list of Track for already played titles for an artist.
         """
         duration = self.daemon_conf.getint('sima', 'history_duration')
         tracks_from_db = self.sdb.get_history(duration=duration, artist=artist)
@@ -311,12 +310,14 @@ class Lastfm(Plugin):
     def _album(self):
         """Get albums for album queue mode
         """
-        artists = self.get_local_similar_artists()
+        #artists = self.get_local_similar_artists()
+        pass
 
     def _top(self):
         """Get some tracks for top track queue mode
         """
-        artists = self.get_local_similar_artists()
+        #artists = self.get_local_similar_artists()
+        pass
 
     def callback_need_track(self):
         self._cleanup_cache()
diff --git a/sima/plugins/randomfallback.py b/sima/plugins/randomfallback.py
new file mode 100644 (file)
index 0000000..37d57af
--- /dev/null
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+"""
+Fetching similar artists from last.fm web services
+"""
+
+# standart library import
+import random
+
+# third parties componants
+
+# local import
+from ..lib.plugin import Plugin
+from ..lib.track import Track
+
+
+class RandomFallBack(Plugin):
+
+    def __init__(self, daemon):
+        Plugin.__init__(self, daemon)
+        self.player = daemon.player
+        self.daemon = daemon
+        ##
+        self.to_add = list()
+
+    def get_history(self):
+        """Constructs list of Track for already played titles.
+        """
+        duration = self.daemon.config.getint('sima', 'history_duration')
+        tracks_from_db = self.daemon.sdb.get_history(duration=duration,)
+        # Construct Track() objects list from database history
+        played_tracks = [Track(artist=tr[-1], album=tr[1], title=tr[2],
+                               file=tr[3]) for tr in tracks_from_db]
+        return played_tracks
+
+    def callback_need_track_fb(self):
+        mode = self.plugin_conf.get('flavour')
+        art = random.choice(self.player.list('artist'))
+        self.log.debug('Random art: {}'.format(art))
+        trk  = random.choice(self.player.find_track(art))
+        self.log.info('random fallback ({}): {}'.format(mode, trk))
+        return [trk]
+
+
+
+# VIM MODLINE
+# vim: ai ts=4 sw=4 sts=4 expandtab
index 06765254da21b24e7d1765921ccfd7181494f2bb..c11d2e16bb82073dd972f920f5e90e08876b317b 100644 (file)
@@ -42,7 +42,7 @@ CONF_FILE = 'sima.cfg'
 DEFAULT_CONF = {
         'MPD': {
             'host': "localhost",
-            'password': "false",
+            #'password': "",
             'port': "6600"},
         'sima': {
             'user_db': "false",
@@ -56,12 +56,16 @@ DEFAULT_CONF = {
             'verbosity': "info"},
         'lastfm': {
             'dynamic': "10",
-            'similarity': "18",
+            'similarity': "20",
             'queue_mode': "track", #TODO control values
             'single_album': "false",
             'track_to_add': "1",
             'album_to_add': "1",
             'depth': "1",
+            },
+        'randomfallback': {
+            'flavour': "sensible", # in pure, sensible, genre
+            'track_to_add': "1",
             }
         }
 #