From ddbd063ade06c2816494bc5d2115ce19b1146d3c Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 9 May 2017 13:50:52 -0400 Subject: [PATCH 1/5] Initial file creation, copied cmus.py --- bumblebee/modules/moc.py | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 bumblebee/modules/moc.py diff --git a/bumblebee/modules/moc.py b/bumblebee/modules/moc.py new file mode 100644 index 0000000..4bc0e56 --- /dev/null +++ b/bumblebee/modules/moc.py @@ -0,0 +1,92 @@ +# pylint: disable=C0111,R0903 +# -*- coding: utf-8 -*- + +"""Displays information about the current song in cmus. + +Requires the following executable: + * cmus-remote + +Parameters: + * cmus.format: Format string for the song information. Tag values can be put in curly brackets (i.e. {artist}) +""" + +from collections import defaultdict + +import string + +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="cmus.prev"), + bumblebee.output.Widget(name="cmus.main", full_text=self.description), + bumblebee.output.Widget(name="cmus.next"), + bumblebee.output.Widget(name="cmus.shuffle"), + bumblebee.output.Widget(name="cmus.repeat"), + ] + super(Module, self).__init__(engine, config, widgets) + + engine.input.register_callback(widgets[0], button=bumblebee.input.LEFT_MOUSE, + cmd="cmus-remote -r") + engine.input.register_callback(widgets[1], button=bumblebee.input.LEFT_MOUSE, + cmd="cmus-remote -u") + engine.input.register_callback(widgets[2], button=bumblebee.input.LEFT_MOUSE, + cmd="cmus-remote -n") + engine.input.register_callback(widgets[3], button=bumblebee.input.LEFT_MOUSE, + cmd="cmus-remote -S") + engine.input.register_callback(widgets[4], button=bumblebee.input.LEFT_MOUSE, + cmd="cmus-remote -R") + + self._fmt = self.parameter("format", "{artist} - {title} {position}/{duration}") + self._status = None + self._shuffle = False + self._repeat = False + self._tags = defaultdict(lambda: '') + + @scrollable + def description(self, widget): + return string.Formatter().vformat(self._fmt, (), self._tags) + + def update(self, widgets): + self._load_song() + + def state(self, widget): + if widget.name == "cmus.shuffle": + return "shuffle-on" if self._shuffle else "shuffle-off" + if widget.name == "cmus.repeat": + return "repeat-on" if self._repeat else "repeat-off" + if widget.name == "cmus.prev": + return "prev" + if widget.name == "cmus.next": + return "next" + return self._status + + def _load_song(self): + info = "" + try: + info = bumblebee.util.execute("cmus-remote -Q") + except RuntimeError: + pass + self._tags = defaultdict(lambda: '') + for line in info.split("\n"): + if line.startswith("status"): + self._status = line.split(" ", 2)[1] + if line.startswith("tag"): + key, value = line.split(" ", 2)[1:] + self._tags.update({ key: value }) + for key in ["duration", "position"]: + if line.startswith(key): + dur = int(line.split(" ")[1]) + self._tags.update({key:bumblebee.util.durationfmt(dur)}) + if line.startswith("set repeat "): + self._repeat = False if "false" in line else True + if line.startswith("set shuffle "): + self._shuffle = False if "false" in line else True + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 From ae7a5bf7a9267210f33f693dd216333e13f6506a Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 9 May 2017 15:05:05 -0400 Subject: [PATCH 2/5] Adds moc.py module. Does not add icons --- bumblebee/modules/moc.py | 67 +++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/bumblebee/modules/moc.py b/bumblebee/modules/moc.py index 4bc0e56..fb1db53 100644 --- a/bumblebee/modules/moc.py +++ b/bumblebee/modules/moc.py @@ -1,13 +1,13 @@ # pylint: disable=C0111,R0903 # -*- coding: utf-8 -*- -"""Displays information about the current song in cmus. +"""Displays information about the current song in moc. Requires the following executable: - * cmus-remote + * mocp Parameters: - * cmus.format: Format string for the song information. Tag values can be put in curly brackets (i.e. {artist}) + * mocp.format: Format string for the song information. Tag values can be put in curly brackets (i.e. {artist}) """ from collections import defaultdict @@ -24,24 +24,24 @@ from bumblebee.output import scrollable class Module(bumblebee.engine.Module): def __init__(self, engine, config): widgets = [ - bumblebee.output.Widget(name="cmus.prev"), - bumblebee.output.Widget(name="cmus.main", full_text=self.description), - bumblebee.output.Widget(name="cmus.next"), - bumblebee.output.Widget(name="cmus.shuffle"), - bumblebee.output.Widget(name="cmus.repeat"), + bumblebee.output.Widget(name="moc.prev"), + bumblebee.output.Widget(name="moc.main", full_text=self.description), + bumblebee.output.Widget(name="moc.next"), + bumblebee.output.Widget(name="moc.shuffle"), + bumblebee.output.Widget(name="moc.repeat"), ] super(Module, self).__init__(engine, config, widgets) engine.input.register_callback(widgets[0], button=bumblebee.input.LEFT_MOUSE, - cmd="cmus-remote -r") + cmd="mocp -r") engine.input.register_callback(widgets[1], button=bumblebee.input.LEFT_MOUSE, - cmd="cmus-remote -u") + cmd="mocp -G") engine.input.register_callback(widgets[2], button=bumblebee.input.LEFT_MOUSE, - cmd="cmus-remote -n") + cmd="mocp -f") engine.input.register_callback(widgets[3], button=bumblebee.input.LEFT_MOUSE, - cmd="cmus-remote -S") + cmd=self._toggle_shuffle) engine.input.register_callback(widgets[4], button=bumblebee.input.LEFT_MOUSE, - cmd="cmus-remote -R") + cmd=self._toggle_repeat) self._fmt = self.parameter("format", "{artist} - {title} {position}/{duration}") self._status = None @@ -57,36 +57,47 @@ class Module(bumblebee.engine.Module): self._load_song() def state(self, widget): - if widget.name == "cmus.shuffle": + if widget.name == "moc.shuffle": return "shuffle-on" if self._shuffle else "shuffle-off" - if widget.name == "cmus.repeat": + if widget.name == "moc.repeat": return "repeat-on" if self._repeat else "repeat-off" - if widget.name == "cmus.prev": + if widget.name == "moc.prev": return "prev" - if widget.name == "cmus.next": + if widget.name == "moc.next": return "next" return self._status def _load_song(self): info = "" try: - info = bumblebee.util.execute("cmus-remote -Q") + info = bumblebee.util.execute("mocp -i") except RuntimeError: pass self._tags = defaultdict(lambda: '') for line in info.split("\n"): - if line.startswith("status"): - self._status = line.split(" ", 2)[1] - if line.startswith("tag"): - key, value = line.split(" ", 2)[1:] - self._tags.update({ key: value }) - for key in ["duration", "position"]: + if line.startswith("State"): + status = line.split(" ", 2)[1] + if status == "PAUSE": + self._status = "paused" + if status == "PLAY": + self._status = "playing" + if line.startswith("Title"): + value = line.split(" ", 2)[1:] + self._tags.update({ "title": value }) + if line.startswith("Artist"): + value = line.split(" ", 2)[1:] + self._tags.update({ "artist": value }) + for key in ["TotalSec", "CurrentSec"]: if line.startswith(key): dur = int(line.split(" ")[1]) self._tags.update({key:bumblebee.util.durationfmt(dur)}) - if line.startswith("set repeat "): - self._repeat = False if "false" in line else True - if line.startswith("set shuffle "): - self._shuffle = False if "false" in line else True + + def _toggle_shuffle(self, widget): + bumblebee.util.execute("mocp -t shuffle") + self._shuffle = False if self._shuffle else True + + def _toggle_repeat(self, widget): + bumblebee.util.execute("mocp -t repeat") + self._repeat = False if self._repeat else True # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 From 4007660c5883cacaee739cd6654b51fd99d9f06b Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 9 May 2017 15:06:12 -0400 Subject: [PATCH 3/5] Adds icons to themes using awesome-fonts for moc module --- themes/icons/awesome-fonts.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/themes/icons/awesome-fonts.json b/themes/icons/awesome-fonts.json index 4263a19..03139ef 100644 --- a/themes/icons/awesome-fonts.json +++ b/themes/icons/awesome-fonts.json @@ -24,6 +24,17 @@ "repeat-on": { "prefix": "" }, "repeat-off": { "prefix": "" } }, + "moc": { + "playing": { "prefix": "" }, + "paused": { "prefix": "" }, + "stopped": { "prefix": "" }, + "prev": { "prefix": "" }, + "next": { "prefix": "" }, + "shuffle-on": { "prefix": "" }, + "shuffle-off": { "prefix": "" }, + "repeat-on": { "prefix": "" }, + "repeat-off": { "prefix": "" } + }, "gpmdp": { "playing": { "prefix": "" }, "paused": { "prefix": "" }, From e89be5c224c936766e5143e4291a88662aaa1155 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 9 May 2017 15:08:08 -0400 Subject: [PATCH 4/5] Adds icons to themes using ascii for moc module --- themes/icons/ascii.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/themes/icons/ascii.json b/themes/icons/ascii.json index 9b03a46..540a475 100644 --- a/themes/icons/ascii.json +++ b/themes/icons/ascii.json @@ -18,6 +18,17 @@ "repeat-on": { "prefix": "R" }, "repeat-off": { "prefix": "[r]" } }, + "moc": { + "playing": { "prefix": ">" }, + "paused": { "prefix": "||" }, + "stopped": { "prefix": "[]" }, + "prev": { "prefix": "|<" }, + "next": { "prefix": ">|" }, + "shuffle-on": { "prefix": "S" }, + "shuffle-off": { "prefix": "[s]" }, + "repeat-on": { "prefix": "R" }, + "repeat-off": { "prefix": "[r]" } + }, "pasink": { "muted": { "prefix": "audio(mute)" }, "unmuted": { "prefix": "audio" } From 32ca76a8514d17c55d2d5394c80a33d4e03d5cf3 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 9 May 2017 15:34:58 -0400 Subject: [PATCH 5/5] Improves syncing between moc program and module. Still not perfect solution. --- bumblebee/modules/moc.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/bumblebee/modules/moc.py b/bumblebee/modules/moc.py index fb1db53..599b59a 100644 --- a/bumblebee/modules/moc.py +++ b/bumblebee/modules/moc.py @@ -93,11 +93,19 @@ class Module(bumblebee.engine.Module): self._tags.update({key:bumblebee.util.durationfmt(dur)}) def _toggle_shuffle(self, widget): - bumblebee.util.execute("mocp -t shuffle") - self._shuffle = False if self._shuffle else True + if self._shuffle: + bumblebee.util.execute("mocp -u shuffle") + self._shuffle = False + else: + bumblebee.util.execute("mocp -o shuffle") + self._shuffle = True def _toggle_repeat(self, widget): - bumblebee.util.execute("mocp -t repeat") - self._repeat = False if self._repeat else True + if self._repeat: + bumblebee.util.execute("mocp -u repeat") + self._repeat = False + else: + bumblebee.util.execute("mocp -o repeat") + self._repeat = True # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4