self.plugins = list()
self.player = self.__get_player() # Player client
try:
+ self.log.info('Connecting MPD: {0}:{1}'.format(*self.player._mpd))
self.player.connect()
except (PlayerError, PlayerUnHandledError) as err:
self.log.warning('Player: {}'.format(err))
self.short_history.appendleft(self.player.current)
def register_plugin(self, plugin_class):
- """Registers plubin in Sima instance..."""
+ """Registers plugin in Sima instance..."""
self.plugins.append(plugin_class(self))
def foreach_plugin(self, method, *args, **kwds):
"""General shutdown method
"""
self.log.warning('Starting shutdown.')
- self.player.disconnect()
self.foreach_plugin('shutdown')
+ self.player.disconnect()
self.log.info('The way is shut, it was made by those who are dead. '
'And the dead keep it…')
# core plugins
from .plugins.core.history import History
from .plugins.core.mpdoptions import MpdOptions
+from .plugins.core.uniq import Uniq
##
sima = core.Sima(config)
# required core plugins
- sima.register_plugin(History)
- sima.register_plugin(MpdOptions)
+ core_plugins = [History, MpdOptions, Uniq]
+ for cplgn in core_plugins:
+ logger.debug('Register core {name} ({doc})'.format(**cplgn.info()))
+ sima.register_plugin(cplgn)
# Loading internal plugins
load_plugins(sima, 'internal')
First non-empty line of the docstring is used as description
Rest of the docstring at your convenience.
- The plugin Name MUST be the same as the module (file name), case
- insensitive: for instance plugin.py → Plugin
+ The lowercased plugin Name MUST be the same as the module (file name),
+ for instance Plugin → plugin.py
It eases plugins discovery and simplifies the code to handle them,
IMHO, it's a fair trade-off.
"""
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, 2014 Jack Kaliko <kaliko@azylum.org>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+#
+"""
+ Deal with MPD options ‑ idle and repeat mode
+"""
+
+# standard library import
+from os import getpid
+from socket import getfqdn
+
+# third parties components
+
+# local import
+from ...lib.plugin import Plugin
+
+
+class Uniq(Plugin):
+ """
+ Publish presence on the MPD host message bus
+ """
+
+ def __init__(self, daemon):
+ Plugin.__init__(self, daemon)
+ self.capable = False
+ self.chan = 'mpd_sima:{0}.{1}'.format(getfqdn(), getpid())
+ self.channels = []
+ self.uniq = True
+ self.is_capable()
+ if not self.capable:
+ return
+ self.is_uniq()
+ self.sub_chan()
+
+ def is_capable(self):
+ if 'channels' in self.player.commands():
+ self.capable = True
+ return
+ self.log.warning('MPD does not provide client to client')
+
+ def get_channels(self):
+ return [chan for chan in self.player.channels() if
+ chan.startswith('mpd_sima') and chan != self.chan]
+
+ def is_uniq(self):
+ channels = self.get_channels()
+ if channels:
+ self.log.warning('Another instance is queueing on this MPD host')
+ self.log.warning(' '.join(channels))
+ self.uniq = False
+
+ def sub_chan(self):
+ self.log.debug('Registering as {}'.format(self.chan))
+ self.player.subscribe(self.chan)
+
+ def callback_need_track(self):
+ if self.capable:
+ self.is_uniq()
+
+
+# VIM MODLINE
+# vim: ai ts=4 sw=4 sts=4 expandtab