Banshee Widgets

banshee.py
banshee.py is a script which uses DBus to talk to Banshee. The script is capable of displaying Banshee's current track and controlling its playback.

The status format defaults to artist - trackname, but can easily be customized and extended through commandline arguments. See the python code for details.

DBus Conduit Method
This involves running banshee.py in the background, where it will act as a conduit between Banshee's DBus and Awesome's DBus. However, no polling is involved, so cycles won't be wasted when Banshee is inactive. Additionally, this method will immediately update a widget, rather than at the next refresh.

Run banshee.py separately with arguments like this:

$ banshee.py listen_dbus "musicwidget.text=\"%(artist)s - %(name)s\"" "musicwidget.text=\"%s\""

Then put something like this in your rc.lua:

-- Status widget (matches name specified in banshee.py args) musicwidget = widget({type = "textbox" }) function banshee(cmd) return awful.util.pread("python " .. awful.util.getdir("config") .. "/banshee.py " .. cmd) end -- Initialize widget to banshee's current state musicwidget.text = banshee("status") -- Keyboard shortcuts globalkeys = awful.util.table.join(  ...   awful.key({ }, "XF86AudioPlay", function  banshee("play") end),   awful.key({ }, "XF86AudioNext", function  banshee("next") end),   awful.key({ }, "XF86AudioPrev", function  banshee("prev") end),   awful.key({ }, "XF86AudioStop", function  banshee("stop") end),   ... )

banshee.py will sleep until notified of a state change by Banshee, at which point it'll retrieve the current track information and send the command musicwidget.text="artist - trackname" to Awesome. Awesome will then update the music widget for us.

Polling Method
Put something like this in your rc.lua to have a widget which refreshes periodically. You'll be wasting cycles on the refreshes and there will be a delay between Banshee and the widget, but you won't need to run banshee.py in the background.

-- Status widget musicwidget = widget({type = "textbox" }) function banshee(cmd) -- Run the command and update the widget with the new state musicwidget.text = awful.util.pread("python " .. awful.util.getdir("config") .. "/banshee.py " .. cmd) end -- Initialize widget to banshee's current state banshee("status") -- 3.4: bansheetimer = timer({ timeout = 5 }) bansheetimer:add_signal("timeout", function banshee("status") end) bansheetimer:start -- 3.3: -- awful.hooks.timer.register(5, function banshee("status") end) -- Keyboard shortcuts (same as in DBus example) globalkeys = awful.util.table.join(  ...   awful.key({ }, "XF86AudioPlay", function  banshee("play") end),   awful.key({ }, "XF86AudioNext", function  banshee("next") end),   awful.key({ }, "XF86AudioPrev", function  banshee("prev") end),   awful.key({ }, "XF86AudioStop", function  banshee("stop") end),   ... )

This version will automatically run the script every 5 seconds, and will also update the status whenever one of the keyboard shortcuts is executed.

Using DBus Directly
Due to the fact that awesome has built-in dbus support, timer-based polling may be unnecessary if you do not like the idea.

However the dbus module in awesome often doesn't work (according to Elv13 in IRC), so don't be surprised if the following proves fruitless.

Awesome 3.4
Use capi.dbus.add_signal? This didn't work for me:

local capi = { dbus = dbus } capi.dbus.add_match("session", "interface='org.bansheeproject.Banshee.PlayerEngine',member='EventChanged'") capi.dbus.add_signal("org.bansheeproject.PlayerEngine", function print(":)\n") end)

Awesome 3.5 and greater
Just use capi.dbus.connect_signal and listen for "startofstream" and "endofstream" EventChanged signals on org.bansheeproject.PlayerEngine.

With Bashets (awesome 3.5 and greater only)
You can also use Bashets to register for a dbus signal with a callback. But note that Bashets uses the same "capi.dbus" module as the above, so if the above didn't work, this probably won't either:

bashets.register("org.bansheeproject.Banshee.PlayerEngine", {dbus = true, busname = "session", callback = function(data)    --data is array of variables, here you need sixth variable; to know why sixth, plz read documentation ;) if data[6] == "startofstream" then datew:set_markup(awful.util.pread("python " .. awful.util.getdir("config") .. "/banshee.py " .. cmd)) end end})

This would cause the script to only be called on track change.