From 29cca9ed73ed4bd87b909398ccc80bceddc89c73 Mon Sep 17 00:00:00 2001 From: kaliko Date: Thu, 7 May 2020 16:28:21 +0200 Subject: [PATCH] Start work on new tags plugin --- sima/plugins/internal/tags.py | 117 ++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 sima/plugins/internal/tags.py diff --git a/sima/plugins/internal/tags.py b/sima/plugins/internal/tags.py new file mode 100644 index 0000000..cd1a4fe --- /dev/null +++ b/sima/plugins/internal/tags.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020 kaliko +# +# This file is part of sima +# +# sima is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# sima is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with sima. If not, see . +# +# +""" +Add titles based on tags +""" + +# standard library import +import random + +# third parties components + +# local import +from ...lib.plugin import Plugin +from ...lib.track import Track +from ...utils.utils import PluginConfException + +def forge_filter(cfg): + tags = set(cfg.keys()) & Tags.supported_tags + cfg_filter = cfg.get('filter', None) + mpd_filter = [] + if cfg_filter: + mpd_filter.append(cfg_filter) + for tag in tags: + if ',' in cfg[tag]: + patt = '|'.join(cfg[tag].split(',')) + mpd_filter.append(f"({tag} =~ '({patt})')") + else: + mpd_filter.append(f"({tag} == '{cfg[tag].strip()}')") + mpd_filter = ' AND '.join(mpd_filter) + if 'AND' in mpd_filter: + mpd_filter = f'({mpd_filter})' + return mpd_filter + + +class Tags(Plugin): + """Add track based on tags content + """ + supported_tags = {'comment', 'date', 'genre', 'label', 'originaldate'} + + def __init__(self, daemon): + super().__init__(daemon) + self.daemon = daemon + self._control_conf() + #self._control_server() + self._setup_tagsneeded() + self.mpd_filter = forge_filter(self.plugin_conf) + self.log.debug('mpd filter: %s', self.mpd_filter) + + def _control_conf(self): + sup_tags = Tags.supported_tags + if not self.plugin_conf.get('filter', None) and \ + self.plugin_conf.keys().isdisjoint(sup_tags): + self.log.error( + 'Found no config for %s plugin! Need at least "filter" or a supported tag' % self) + self.log.info('Supported Tags are : %s', ', '.join(sup_tags)) + raise PluginConfException('plugin misconfiguration') + + def _control_server(self): + #TODO: + # * control tags used are available + # * filters are available mpd version >= 0.21 + raise NotImplemented + + def _setup_tagsneeded(self): + tags = set(self.plugin_conf.keys()) & Tags.supported_tags + self.player.needed_tags |= tags + + def _get_history(self): + """Constructs list of already played artists. + """ + duration = self.daemon.config.getint('sima', 'history_duration') + tracks_from_db = self.daemon.sdb.get_history(duration=duration) + hist = [Track(file=tr[3], artist=tr[0]) for tr in tracks_from_db] + return hist + + def callback_need_track(self): + candidates = [] + target = self.plugin_conf.getint('track_to_add') + tracks = self.player.find(self.mpd_filter) + random.shuffle(tracks) + history = self._get_history() + while tracks: + trk = tracks.pop() + if trk in self.player.queue or \ + trk in candidates: + self.log.debug('%s already queued', trk) + continue + if trk in history: + self.log.debug('%s in history', trk) + continue + candidates.append(trk) + self.log.info('Tags candidate: {}'.format(trk)) + if len(candidates) >= target: + break + if not candidates: + self.log.info('Tags plugin failed to find some tracks') + return candidates + +# VIM MODLINE +# vim: ai ts=4 sw=4 sts=4 expandtab -- 2.39.2