So I googled my head off trying to find out if there is a way to make it so that Linux can play a short sound file when a USB drive/device is added or removed. I couldn't find anything, so I figured I'd write a python script to do it.
It uses the apparently deprecated DBUS api, because I couldn't figure ut how to install half the crap the "new" method wanted (pynotify's installation scripts had broken shebangs and crashed seemingly randomly when I tried to install it, and I have no idea how to get libnotify working). Also, so far it only seems to work for adding volumes, since dbus won't let me inspect the removed device in the remove hook to determine if it's a volume, and I got weird behaviour when I just played the removal sound for any removal without inspecting.
For sound, I tried about a dozen different APIs and packages, which either refused to install, had issues during ./configure that I couldn't resolve (particularly the one where it complained that I didn't have the header to compile python extensions which made sense except it was integrated into the core python includes and thus was extraneous and I wasn't able to find the part in the shell script to remove so I gave up). I had luck with pygame, mostly because I was able to simply apt-get it, but it crashed with audio errors when I tried to use pygame.mixer.init(). the Python-standard ossaudiodev was promising but OSS is outdated and I couldn't get it to even pretend to work.
I basically ended up just shelling out to mplayer to play the sound. Which works, I guess.
Anyway, here is the script. I now have it running off in another desktop so I get the standard windows USB add sound whenever I plug in a USB drive, heh.
#!/usr/bin/python
#by BC_Programming
import dbus
import gobject
import time
import subprocess
print "BASeCamp 'USBSounds' Simple USB Volume notification sound."
#playsound merely shells out to mplayer. I would have preferred an integrated solution but... meh.
def playsound(soundfile):
subprocess.call(["mplayer", "hardwareinsert.wav"], stdout=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'))
class DeviceAddedListener:
def __init__(self):
#get the system bus...
self.bus = dbus.SystemBus()
#get the manager
self.hal_manager_obj = self.bus.get_object(
'org.freedesktop.Hal',
'/org/freedesktop/Hal/Manager')
#get the interface for the manager
self.hal_manager = dbus.Interface(self.hal_manager_obj,'org.freedesktop.Hal.Manager')
#connect to the appropriate signals.
self.hal_manager.connect_to_signal('DeviceAdded', self._filteradd)
self.hal_manager.connect_to_signal("DeviceRemoved",self._filterremove)
#note: I couldn't get DeviceRemoval sounds to work since it doesn't let you #inspect whether the removed device is a volume via "QueryCapability"... since it's gone.
def _filteradd(self, udi):
device_obj = self.bus.get_object ('org.freedesktop.Hal', udi)
device = dbus.Interface(device_obj, 'org.freedesktop.Hal.Device')
#if it is a volume, call the do_add function...
if device.QueryCapability("volume"):
return self.do_add(device)
def _filterremove(self,udi):
try:
#device_obj = self.bus.get_object('org.freedesktop.Hal',udi)
#device = dbus.Interface(device_obj,'org.freedesktop.Hal.Device')
#if device.QueryCapability("volume"):
# return self.do_remove(device)
except:
return
#unused....
def do_remove(self,volume):
playsound("hardwareremove.wav")
#displays some info about the added device to the console (maybe future changes can pop stuff like volume label, device file, size, etc into a Notification box?)
def do_add(self, volume):
device_file = volume.GetProperty("block.device")
label = volume.GetProperty("volume.label")
fstype = volume.GetProperty("volume.fstype")
mounted = volume.GetProperty("volume.is_mounted")
mount_point = volume.GetProperty("volume.mount_point")
try:
size = volume.GetProperty("volume.size")
except:
size = 0
print "New storage device detected:"
print " device_file: %s" % device_file
print " label: %s" % label
print " fstype: %s" % fstype
if mounted:
print " mount_point: %s" % mount_point
else:
print " not mounted"
print " size: %s (%.2fGB)" % (size, float(size) / 1024**3)
#and play a sound.
playsound("hardwareinsert.wav")
#main loop...
if __name__ == '__main__':
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
print "in __main__..."
DeviceAddedListener()
loop.run()