Controlling Rhythmbox using DBus and Python

So I wanted the ability to map a key combination that would accomplish the following:

        if (Rhythmbox is running) then
                if (Rhythmbox is visible) then
                        hide Rhythmbox
                else
                        show Rhythmbox
                endif
        else
                start Rhythmbox
                show Rhythmbox
        endif

In other words, a Rhythmbox toggle. Rhythmbox already has a show/hide check option in the tray icon UI, and the rhythmbox-client remote control program that comes with the source package exposes a hide option, so I figured it couldn’t be that hard.

Turns out the DBus Python bindings make this very straightforward. But I ran into an previously unfiled bug in the Python bindings; namely that they define the values for some random constants incorrectly.

[Update: The bug has been fixed.]

It’s funny how all these IPC messaging systems - DBus, COM, VMOMI/VMODL - always end up looking pretty much the same. There are no new ideas, or so goes the saying.

Anyway, here’s the code:

#!/usr/bin/python
import dbus

# These are defined incorrectly in dbus.dbus_bindings
DBUS_START_REPLY_SUCCESS = 1
DBUS_START_REPLY_ALREADY_RUNNING = 2

# Get the current session bus
bus = dbus.SessionBus()

# Explicitly try to start Rhythmbox.
(success, status) = bus.start_service_by_name('org.gnome.Rhythmbox')

# If we started it, make sure we explicitly show it
force_visible = (status == DBUS_START_REPLY_SUCCESS)

# Open the Rhythmbox shell object and get its properties
rbshellobj = bus.get_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Shell')
rbprops = dbus.Interface(rbshellobj, 'org.freedesktop.DBus.Properties')

# Toggle the visibility value from its current setting
is_visible = rbprops.Get('org.gnome.Rhythmbox.Shell', 'visibility')
rbprops.Set('org.gnome.Rhythmbox.Shell', 'visibility', force_visible or (not is_visible))