From 4912fcc57b05018cdb4578a18e63ca24ac5e2d13 Mon Sep 17 00:00:00 2001 From: Smitajit Biswal Date: Wed, 3 Jun 2020 21:39:27 +0200 Subject: [PATCH 1/2] [module] playerctl to displays information about the current song in vlc, audacious, bmp, xmms2, spotify and others --- bumblebee_status/modules/contrib/playerctl.py | 61 ++++++++++++++++++ docs/modules.rst | 12 ++++ screenshots/playerctl.png | Bin 0 -> 5686 bytes themes/icons/awesome-fonts.json | 7 ++ themes/icons/ionicons.json | 7 ++ 5 files changed, 87 insertions(+) create mode 100755 bumblebee_status/modules/contrib/playerctl.py create mode 100644 screenshots/playerctl.png diff --git a/bumblebee_status/modules/contrib/playerctl.py b/bumblebee_status/modules/contrib/playerctl.py new file mode 100755 index 0000000..e3a964a --- /dev/null +++ b/bumblebee_status/modules/contrib/playerctl.py @@ -0,0 +1,61 @@ +# pylint: disable=C0111,R0903 + +"""Displays information about the current song in vlc, audacious, bmp, xmms2, spotify and others + +Requires the following executable: + * playerctl + +contributed by `smitajit `_ - many thanks! + +""" + +import bumblebee.util +import bumblebee.input +import bumblebee.output +import bumblebee.engine + +class Module(bumblebee.engine.Module): + def __init__(self, engine, config): + widgets = [ + bumblebee.output.Widget(name="playerctl.prev"), + bumblebee.output.Widget(name="playerctl.main", full_text=self.description), + bumblebee.output.Widget(name="playerctl.next"), + ] + super(Module, self).__init__(engine, config, widgets) + + engine.input.register_callback(widgets[0], button=bumblebee.input.LEFT_MOUSE, + cmd="playerctl previous") + engine.input.register_callback(widgets[1], button=bumblebee.input.LEFT_MOUSE, + cmd="playerctl play-pause") + engine.input.register_callback(widgets[2], button=bumblebee.input.LEFT_MOUSE, + cmd="playerctl next") + + self._status = None + self._tags = None + + def description(self, widget): + return self._tags if self._tags else "..." + + def update(self, widgets): + self._load_song() + + def state(self, widget): + if widget.name == "playerctl.prev": + return "prev" + if widget.name == "playerctl.next": + return "next" + return self._status + + def _load_song(self): + info = "" + try: + status = bumblebee.util.execute("playerctl status") + info = bumblebee.util.execute("playerctl metadata xesam:title") + except : + self._status = None + self._tags = None + return + self._status = status.split("\n")[0].lower() + self._tags = info.split("\n")[0][:20] + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/docs/modules.rst b/docs/modules.rst index a99c452..3afc95d 100644 --- a/docs/modules.rst +++ b/docs/modules.rst @@ -149,6 +149,18 @@ Parameters: .. image:: ../screenshots/ping.png +playerctl +~~~~~~~~~~ +Displays information about the current song in vlc, audacious, bmp, xmms2, spotify and others + +Requires the following executable: + * playerctl + +contributed by `smitajit `_ - many thanks! + +.. image:: ../screenshots/playerctl.png + + pulseaudio ~~~~~~~~~~ diff --git a/screenshots/playerctl.png b/screenshots/playerctl.png new file mode 100644 index 0000000000000000000000000000000000000000..588e74556adb98c0365d86e057eef7216312b3ba GIT binary patch literal 5686 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 literal 0 HcmV?d00001 diff --git a/themes/icons/awesome-fonts.json b/themes/icons/awesome-fonts.json index e660c1d..5a5269c 100644 --- a/themes/icons/awesome-fonts.json +++ b/themes/icons/awesome-fonts.json @@ -65,6 +65,13 @@ "prev": { "prefix": "" }, "next": { "prefix": "" } }, + "playerctl": { + "playing": { "prefix": "" }, + "paused": { "prefix": "" }, + "stopped": { "prefix": "" }, + "prev": { "prefix": "" }, + "next": { "prefix": "" } + }, "pasink": { "muted": { "prefix": "" }, "unmuted": { "prefix": "" } diff --git a/themes/icons/ionicons.json b/themes/icons/ionicons.json index 4b90133..3e577bf 100644 --- a/themes/icons/ionicons.json +++ b/themes/icons/ionicons.json @@ -47,6 +47,13 @@ "prev": { "prefix": "\uf4ab" }, "next": { "prefix": "\uf4ad" } }, + "playerctl": { + "playing": { "prefix": "\uf488" }, + "paused": { "prefix": "\uf210" }, + "stopped": { "prefix": "\uf24f" }, + "prev": { "prefix": "\uf4ab" }, + "next": { "prefix": "\uf4ad" } + }, "pasink": { "muted": { "prefix": "\uf3b9" }, "unmuted": { "prefix": "\uf3ba" } From 2dff5e2de7987b020ec937a5e71f3b4a16e69d45 Mon Sep 17 00:00:00 2001 From: smitajit Date: Sat, 6 Jun 2020 14:39:50 +0200 Subject: [PATCH 2/2] migrated playerctl script to new bumblebee_status APIs --- bumblebee_status/modules/contrib/playerctl.py | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/bumblebee_status/modules/contrib/playerctl.py b/bumblebee_status/modules/contrib/playerctl.py index e3a964a..b145500 100755 --- a/bumblebee_status/modules/contrib/playerctl.py +++ b/bumblebee_status/modules/contrib/playerctl.py @@ -9,25 +9,25 @@ contributed by `smitajit `_ - many thanks! """ -import bumblebee.util -import bumblebee.input -import bumblebee.output -import bumblebee.engine +import core.module +import core.widget +import core.input +import util.cli -class Module(bumblebee.engine.Module): - def __init__(self, engine, config): +class Module(core.module.Module): + def __init__(self,config , theme): widgets = [ - bumblebee.output.Widget(name="playerctl.prev"), - bumblebee.output.Widget(name="playerctl.main", full_text=self.description), - bumblebee.output.Widget(name="playerctl.next"), + core.widget.Widget(name="playerctl.prev"), + core.widget.Widget(name="playerctl.main", full_text=self.description), + core.widget.Widget(name="playerctl.next"), ] - super(Module, self).__init__(engine, config, widgets) + super(Module, self).__init__(config, theme , widgets) - engine.input.register_callback(widgets[0], button=bumblebee.input.LEFT_MOUSE, + core.input.register(widgets[0], button=core.input.LEFT_MOUSE, cmd="playerctl previous") - engine.input.register_callback(widgets[1], button=bumblebee.input.LEFT_MOUSE, + core.input.register(widgets[1], button=core.input.LEFT_MOUSE, cmd="playerctl play-pause") - engine.input.register_callback(widgets[2], button=bumblebee.input.LEFT_MOUSE, + core.input.register(widgets[2], button=core.input.LEFT_MOUSE, cmd="playerctl next") self._status = None @@ -36,7 +36,7 @@ class Module(bumblebee.engine.Module): def description(self, widget): return self._tags if self._tags else "..." - def update(self, widgets): + def update(self): self._load_song() def state(self, widget): @@ -49,8 +49,8 @@ class Module(bumblebee.engine.Module): def _load_song(self): info = "" try: - status = bumblebee.util.execute("playerctl status") - info = bumblebee.util.execute("playerctl metadata xesam:title") + status = util.cli.execute("playerctl status").lower() + info = util.cli.execute("playerctl metadata xesam:title") except : self._status = None self._tags = None