Accessing DeviceKit with DBus and Python

Posted by on January 8, 2010

Under the impression of loosing some really important data because of a damaged partition table on a USB flash drive I am developing a backup strategy for my system.
I know myself and so I decided that I need to automate this. While trying to figure out how one can run a script as soon as a specific drive is mounted, I came across DeviceKit. It’s the planned replacement of HAL and is used in Ubuntu Karmic. Udev is not an option for me, because I don’t want to mess around with mounting myself (and I hate running stuff as root…).
So here is what I found out about using DBus and DeviceKit in Python:

import dbus
 
bus = dbus.SystemBus()
 
proxy = bus.get_object("org.freedesktop.DeviceKit.Disks", 
                       "/org/freedesktop/DeviceKit/Disks")
iface = dbus.Interface(proxy, "org.freedesktop.DeviceKit.Disks")
#enumerates all devices
print iface.EnumerateDevices()
 
#gets the device kit path of a specific device
path = iface.FindDeviceByDeviceFile("/dev/sdc1") 
#= "/org/freedesktop/DeviceKit/Disks/devices/sdc"
 
#gets an object representing the device specified by the path
device = bus.get_object("org.freedesktop.DeviceKit.Disks", path) 
 
#prints some XML that shows you the available methods, signals and properties
print device.Introspect()
 
#gets a proxy for getting properties
device_prop = dbus.Interface(device, "org.freedesktop.DBus.Properties")
 
#you need to specify an interface (properties could be ambiguous)
print device_prop.Get("org.freedesktop.DeviceKit.Disks.Device", "device-mount-paths")
 
#gets a proxy you can call methods on
device_iface = dbus.Interface(device, "org.freedesktop.DeviceKit.Disks.Device")
 
#unmounts the partition
device_iface.FilesystemUnmount(dbus.Array([], 's'))

The DBus API of DeviceKit is documented here.
Now we want to be notified when a drive is mounted:

import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
 
def device_added_callback(device):
    print 'Device %s was added' % (device)
 
def device_changed_callback(device):
    print 'Device %s was changed' % (device)
 
#must be done before connecting to DBus
DBusGMainLoop(set_as_default=True)
 
bus = dbus.SystemBus()
 
proxy = bus.get_object("org.freedesktop.DeviceKit.Disks", 
                       "/org/freedesktop/DeviceKit/Disks")
iface = dbus.Interface(proxy, "org.freedesktop.DeviceKit.Disks")
 
#addes two signal listeners
iface.connect_to_signal('DeviceAdded', device_added_callback)
iface.connect_to_signal('DeviceChanged', device_changed_callback)
 
#start the main loop
mainloop = gobject.MainLoop()
mainloop.run()

A typical output when a flash drive is plugged in looks like this:

Device /org/freedesktop/DeviceKit/Disks/devices/sdc was added
Device /org/freedesktop/DeviceKit/Disks/devices/sdc1 was added
Device /org/freedesktop/DeviceKit/Disks/devices/sdc1 was changed

With this knowledge I’m currently working on a little python script that runs in background and executes a shell script when a file system is mounted. I’ll post it, when it’s finished :-)

Comments

Respond | Trackback

  1. Becky February 9, 2010 4:02 pm

    This has to be the easiest article of starting to use the DeviceKit API I’ve seen so far. I’ve been using HAL + DBus for some time but have to migrate due to it being completely dropped in the upcoming Ubuntu Lucid release. Thanks for taking the time to post this article up!

Comments

Comments: