diff --git a/README.md b/README.md index 409ecb4..0175958 100644 --- a/README.md +++ b/README.md @@ -272,10 +272,10 @@ Grabs a piece of text from a URL based on a css or xpath selector. Optionally op Both the `${OFF}` and `${ON}` buttons allow additional button specific behaviours to be configured. The supported options are: | Option | Description | -| `B` | Brightness. Value between `0` and `255`. -| `H` | Hue. Value between `0` and `65535`. -| `A` | Alert. Value of either `select` (for a single flash) or `lselect` (for 30s of flashing) -| `T` | Button Text. Any character string that will be shown as the button's text. +| `B` | Brightness. Value between `0` and `255`. | +| `H` | Hue. Value between `0` and `65535`. | +| `A` | Alert. Value of either `select` (for a single flash) or `lselect` (for 30s of flashing) | +| `T` | Button Text. Any character string that will be shown as the button's text. | These can be applied to the Block's `format` string options by appending them with a colon and passing the option with a hyphen: @@ -299,16 +299,18 @@ See the [hue.rb](https://github.com/OkayDave/barr/blob/develop/examples/hue.rb) | `format` | string | Configurable format for choosing the buttons and their behaviours. See table below for options | `"${OFF} ${ON}"`| | Option | Description | +| --- | --- | | `${OFF}` | Adds a button to turn the selected light off. Can be configured with custom text | -| `${ON}` | Adss a button to turn the selected light on. Several buttons can be added with individual behaviours | +| `${ON}` | Adds a button to turn the selected light on. Several buttons can be added with individual behaviours | Both the `${OFF}` and `${ON}` buttons allow additional button specific behaviours to be configured. The supported options are: | Option | Description | -| `B` | Brightness. Value between `0` and `255`. -| `H` | Hue. Value between `0` and `65535`. -| `A` | Alert. Value of either `select` (for a single flash) or `lselect` (for 30s of flashing) -| `T` | Button Text. Any character string that will be shown as the button's text. +| --- | --- | +| `B` | Brightness. Value between `0` and `255`. | +| `H` | Hue. Value between `0` and `65535`. | +| `A` | Alert. Value of either `select` (for a single flash) or `lselect` (for 30s of flashing) | +| `T` | Button Text. Any character string that will be shown as the button's text. | These can be applied to the Block's `format` string options by appending them with a colon and passing the option with a hyphen: @@ -350,6 +352,24 @@ Shows current RAM usage. There are no `Mem` block specific configurable options. +#### Playerctl + +**Requires [Playerctl](https://github.com/acrisci/playerctl)**. Shows configurable information about currently playing track on a variety of players. Option to include control buttons. + +`pctl = Barr::Blocks::Playerctl.new player: "spotify", format: "${ARTIST} - ${TITLE} - ${BUTTONS}` + +| Option | Value | Description | Default | +| --- | --- | --- | --- | +| `format` | string | Configurable format for defining how the information is displayed. See table below for options | `"${ARTIST} - ${TRACK}"` | +| `player` | string | ID of the media app you want to control. Run `playerctl -l` to see what is available | '' | + +| Format Option | Description | +| --- | --- | +| `${ARTIST}` | Artist of currently playing track | +| `${ALBUM}` | Album of currently playing track | +| `${TITLE}` | Title of currently playing track | +| `${BUTTONS}` | Buttons to control playback | + #### Processes Shows the number of currently active processes on your system. @@ -359,7 +379,7 @@ Shows the number of currently active processes on your system. There are no `Processes` block specific configurable options. #### Rhythmbox - +**DEPRECATED** It's reccommended to use the `Playerctl` block instead of this. It's compatible with Rhythmbox and many other players, including Spotify. **Requires Rhythmbox and rhythmbox-client**. Shows currently playing artist and/or track, as well as control buttons. Control buttons use FontAwesome. `rb = Barr::Blocks::Rhythmbox.new buttons: false` diff --git a/barr.gemspec b/barr.gemspec index 2cdb0dd..513cc03 100644 --- a/barr.gemspec +++ b/barr.gemspec @@ -42,4 +42,5 @@ Gem::Specification.new do |spec| spec.requirements << "(Optional) Bspwm for Bspwm desktop support" spec.requirements << "(Optional) RhythmBox & rhythmbox-client" spec.requirements << "(Optional) FontAwesome font" + spec.requirements << "(Optional) playerctl" end diff --git a/lib/barr.rb b/lib/barr.rb index e435300..57342e3 100644 --- a/lib/barr.rb +++ b/lib/barr.rb @@ -16,6 +16,7 @@ require 'barr/blocks/i3' require 'barr/blocks/ip' require 'barr/blocks/mem' +require 'barr/blocks/playerctl' require 'barr/blocks/processes' require 'barr/blocks/rhythmbox' require 'barr/blocks/mpd' @@ -25,6 +26,7 @@ require 'barr/controllers/bbc_weather' require 'barr/controllers/http_grab' +require 'barr/controllers/playerctl' module Barr end diff --git a/lib/barr/blocks/playerctl.rb b/lib/barr/blocks/playerctl.rb new file mode 100644 index 0000000..7a439ab --- /dev/null +++ b/lib/barr/blocks/playerctl.rb @@ -0,0 +1,43 @@ +module Barr + module Blocks + class Playerctl < Block + attr_accessor :location + + def initialize opts={} + super + @format = opts[:format] || "${ARTIST} - ${TITLE}" + @player = opts[:player] || false + @btns = nil + end + + def config + opts = {id: @player, player: @player } + @controller = @manager.controller :Playerctl, opts + end + + def update! + op = @controller.output.merge buttons + @output = "#{format_string_from_hash(op)}" + end + + def buttons + if @btns.nil? + @btns = { + play_pause: wrap_button("\uf04b", "playerctl #{'-p #{@player} ' if @player}play-pause"), + next: wrap_button("\uf051", "playerctl #{'-p #{@player} ' if @player}next"), + previous: wrap_button("\uf048", "playerctl #{'-p #{@player} ' if @player}previous"), + } + + @btns.merge!(buttons: [ + @btns[:previous], + @btns[:play_pause], + @btns[:previous] + ].join(" ") + ) + end + + @btns + end + end + end +end diff --git a/lib/barr/controllers/playerctl.rb b/lib/barr/controllers/playerctl.rb new file mode 100644 index 0000000..629498e --- /dev/null +++ b/lib/barr/controllers/playerctl.rb @@ -0,0 +1,46 @@ +require 'json' + +module Barr + module Controllers + class Playerctl < Controller + + def initialize opts={} + super + @player = opts[:player] || "" + end + + def run! + @thread = Thread.new do + loop do + begin + op = {} + + op[:album] = sys_cmd 'album' + op[:artist] = sys_cmd 'artist' + op[:title] = sys_cmd 'title' + + File.write(filename, op.to_json) + + sleep 5 + rescue StandardError => e + STDERR.puts "thread error!" + STDERR.puts e.message + STDERR.puts e.backtrace + end + + end + end + @thread.run + end + + def sys_cmd key + if !@player.empty? + `playerctl -p #{@player} metadata #{key}` + else + `playerctl metadata #{key}` + end + end + + end + end +end diff --git a/spec/blocks/playerctl_spec.rb b/spec/blocks/playerctl_spec.rb new file mode 100644 index 0000000..fa3656f --- /dev/null +++ b/spec/blocks/playerctl_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' +require './spec/mocks/playerctl' + +RSpec.describe Barr::Blocks::PlayerctlBlockMock do + + describe '#initialize' do + it "sets default format" do + expect(subject.format).to eq("${ARTIST} - ${TITLE}") + end + end + + describe 'config' do + it "sets the controller" do + subject.config + expect(subject.controller).to be_a(Barr::Controllers::PlayerctlControllerMock) + end + end + + describe 'update' do + it "sets the output correctly" do + subject.format = "${ARTIST} - ${ALBUM} - ${NEXT}" + subject.config + subject.controller.update! + subject.update! + expect(subject.output).to eq("Slayer - Reign in Blood - %{A:playerctl next:}\uf051%{A}") + end + end + +end diff --git a/spec/mocks/playerctl.rb b/spec/mocks/playerctl.rb new file mode 100644 index 0000000..572bb70 --- /dev/null +++ b/spec/mocks/playerctl.rb @@ -0,0 +1,36 @@ +# coding: utf-8 +require 'barr/block' +require 'barr/controller' +require 'barr/blocks/playerctl' +require 'barr/controllers/playerctl' + +module Barr + module Controllers + class PlayerctlControllerMock < Barr::Controllers::Playerctl + def document + end + + def run! + end + + def update! + @output ||= {} + @output[:artist] = "Slayer" + @output[:title] = "Angel of Death" + @output[:album] = "Reign in Blood" + end + + end + end + + + module Blocks + class PlayerctlBlockMock < Barr::Blocks::Playerctl + def config + @controller = Barr::Controllers::PlayerctlControllerMock.new {} + end + end + end +end + +