# pylint: disable=C0111,R0903 # -*- coding: utf-8 -*- """Displays information about the current song in mpd. If mpd is not running or mpc fails for some reason, it will show "n/a". Requires the following executable: * mpc Parameters: * mpd.format: Format string for the song information. Supported tags (see `man mpc` for additional information) * {name} * {artist} * {album} * {albumartist} * {comment} * {composer} * {date} * {originaldate} * {disc} * {genre} * {performer} * {title} * {track} * {time} * {file} * {id} * {prio} * {mtime} * {mdate} Additional tags: * {position} - position of currently playing song not to be confused with %position% mpc tag * {duration} - duration of currently playing song * {file1} - song file name without path prefix if {file} = '/foo/bar.baz', then {file1} = 'bar.baz' * {file2} - song file name without path prefix and extension suffix if {file} = '/foo/bar.baz', then {file2} = 'bar' * mpd.host: MPD host to connect to. (mpc behaviour by default) """ from collections import defaultdict import string import os import bumblebee.util import bumblebee.input import bumblebee.output import bumblebee.engine from bumblebee.output import scrollable class Module(bumblebee.engine.Module): def __init__(self, engine, config): widgets = [ bumblebee.output.Widget(name="mpd.prev"), bumblebee.output.Widget(name="mpd.main", full_text=self.description), bumblebee.output.Widget(name="mpd.next"), bumblebee.output.Widget(name="mpd.shuffle"), bumblebee.output.Widget(name="mpd.repeat"), ] super(Module, self).__init__(engine, config, widgets) self._mpd_running = False if not self.parameter("host"): self._hostcmd = "" else: self._hostcmd = " -h " + self.parameter("host") engine.input.register_callback(widgets[0], button=bumblebee.input.LEFT_MOUSE, cmd="mpc prev" + self._hostcmd) engine.input.register_callback(widgets[1], button=bumblebee.input.LEFT_MOUSE, cmd="mpc toggle" + self._hostcmd) engine.input.register_callback(widgets[2], button=bumblebee.input.LEFT_MOUSE, cmd="mpc next" + self._hostcmd) engine.input.register_callback(widgets[3], button=bumblebee.input.LEFT_MOUSE, cmd="mpc random" + self._hostcmd) engine.input.register_callback(widgets[4], button=bumblebee.input.LEFT_MOUSE, cmd="mpc repeat" + self._hostcmd) self._fmt = self.parameter("format", "{artist} - {title} {position}/{duration}") self._status = None self._shuffle = False self._repeat = False self._tags = defaultdict(lambda: '') def hidden(self): if self._mpd_running == True and return self._mpd_running is True and self._status is None @scrollable def description(self, widget): if not self._mpd_running: return "n/a" return string.Formatter().vformat(self._fmt, (), self._tags) def update(self, widgets): self._load_song() def state(self, widget): if widget.name == "mpd.shuffle": return "shuffle-on" if self._shuffle else "shuffle-off" if widget.name == "mpd.repeat": return "repeat-on" if self._repeat else "repeat-off" if widget.name == "mpd.prev": return "prev" if widget.name == "mpd.next": return "next" return self._status def _load_song(self): info = "" self._mpd_running = True try: tags = ['name', 'artist', 'album', 'albumartist', 'comment', 'composer', 'date', 'originaldate', 'disc', 'genre', 'performer', 'title', 'track', 'time', 'file', 'id', 'prio', 'mtime', 'mdate'] joinedtags = "\n".join(["tag {0} %{0}%".format(tag) for tag in tags]) info = bumblebee.util.execute('mpc -f ' + '"' + joinedtags + '"' + self._hostcmd) except Exception: self._mpd_running = False self._tags = defaultdict(lambda: '') self._status = None for line in info.split("\n"): if line.startswith("[playing]"): self._status = "playing" elif line.startswith("[paused]"): self._status = "paused" if line.startswith("["): timer = line.split()[2] position = timer.split("/")[0] dur = timer.split("/")[1] duration = dur.split(" ")[0] self._tags.update({'position': position}) self._tags.update({'duration': duration}) if line.startswith("volume"): value = line.split(" ", 2)[1:] for option in value: if option.startswith("repeat: on"): self._repeat = True elif option.startswith("repeat: off"): self._repeat = False elif option.startswith("random: on"): self._shuffle = True elif option.startswith("random: off"): self._shuffle = False if line.startswith("tag"): key, value = line.split(" ", 2)[1:] self._tags.update({key: value}) if key == "file": self._tags.update({"file1": os.path.basename(value)}) self._tags.update( {"file2": os.path.splitext(os.path.basename(value))[0]}) # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4