1.

Solve : USB Drive sounds (Linux Mint 10)?

Answer»

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.

Code: [Select]#!/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()
You'd think there'd be some kind of hook out of automount, wouldn't you?  Probably introducing such a feature into the code and recompiling would be the most elegant solution.  Heave you heard of inotifyincron builds on inotify and there's even an example of playing a sound on the basis of a change within the file system.I wanted a solution that I could share easily, most of the others, even assuming I was able to get them working, would generally need somebody to go off and download some other package (for example, pyinotify). I might explore that for a more robust solution, at least for myself, but this script has been working well enough for me.Ah, I see.  In that case, well done!Why do you need a sound for that? Quote from: Raptor on January 08, 2012, 05:44:23 PM

Why do you need a sound for that?

So that I know the drive was detected. Quote from: BC_Programmer on January 08, 2012, 06:50:57 PM
So that I know the drive was detected.

Can't you just look?

If I recall correctly, the default behavior for Linux Mint is to auto-mount usb drives and show an icon on the desktop.

By the way, good job on the script!  Quote from: JJ 3000 on January 08, 2012, 07:00:56 PM
Can't you just look?
If I recall correctly, the default behavior for Linux Mint is to auto-mount usb drives and show an icon on the desktop.
It doesn't always show up and OPENING nautilus or showing the desktop is a big pain in the *censored* compared to just being able to hear a sound.
It's pretty cool that you wrote an entire script for that. I still think Firefox is the best browser, though. Quote from: Raptor on January 09, 2012, 08:13:55 AM
It's pretty cool that you wrote an entire script for that. I still think Firefox is the best browser, though.
What does firefox have to do with any of this? Quote from: BC_Programmer on January 09, 2012, 11:19:44 PM
What does firefox have to do with any of this?

At least it's not "or alternatively you could just install Windows, which plays the USB-add sound". Quote from: Veltas on January 10, 2012, 04:05:57 AM
At least it's not "or alternatively you could just install Windows, which plays the USB-add sound".

Windows is installed in a dual boot with it, so I can properly test my programs installers without fiddling with a VM

the Apache/MySQL/PHP stack  is a lot easier to install & administer via on Linux, and it is the primary role of the laptop. Quote from: BC_Programmer on January 10, 2012, 04:14:38 AM
the Apache/MySQL/PHP stack  is a lot easier to install & administer via on Linux, and it is the primary role of the laptop.

Is it running a website? Quote from: BC_Programmer on January 09, 2012, 11:19:44 PM
What does firefox have to do with any of this?

Nothing. Just trolling! Quote from: Raptor on January 10, 2012, 04:31:47 AM
Nothing. Just trolling!

Oh Raptor...


Discussion

No Comment Found