From e09e76d41b2f041de935e9e884009e3187005ab9 Mon Sep 17 00:00:00 2001 From: kaliko Date: Thu, 3 Oct 2013 20:44:59 +0200 Subject: [PATCH] Random fallback plugin, honoring MPD/host, more robust plugin --- doc/examples/all_settings.cfg | 8 ++++++ launch | 5 ++-- sima/core.py | 18 +++++++++++-- sima/lib/plugin.py | 11 +++++++- sima/plugins/lastfm.py | 11 ++++---- sima/plugins/randomfallback.py | 46 ++++++++++++++++++++++++++++++++++ sima/utils/config.py | 8 ++++-- 7 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 sima/plugins/randomfallback.py diff --git a/doc/examples/all_settings.cfg b/doc/examples/all_settings.cfg index 1d0fb6f..c08c1c9 100644 --- a/doc/examples/all_settings.cfg +++ b/doc/examples/all_settings.cfg @@ -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 bf84129..e4c44b5 100755 --- 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): diff --git a/sima/core.py b/sima/core.py index 2d8b960..ad21db6 100644 --- a/sima/core.py +++ b/sima/core.py @@ -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) diff --git a/sima/lib/plugin.py b/sima/lib/plugin.py index 999255f..d44abaf 100644 --- a/sima/lib/plugin.py +++ b/sima/lib/plugin.py @@ -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 diff --git a/sima/plugins/lastfm.py b/sima/plugins/lastfm.py index 01e8cd9..7f2397a 100644 --- a/sima/plugins/lastfm.py +++ b/sima/plugins/lastfm.py @@ -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 index 0000000..37d57af --- /dev/null +++ b/sima/plugins/randomfallback.py @@ -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 diff --git a/sima/utils/config.py b/sima/utils/config.py index 0676525..c11d2e1 100644 --- a/sima/utils/config.py +++ b/sima/utils/config.py @@ -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", } } # -- 2.39.5