Usually I intro with some inane comment like:
There are two types of people - those who love Amarok, and those that don't matter.
But now I get to say:
I use Amarok, as recommended (and generally given fan-boy loving) by Wil Wheaton.
Anyway, I use Amarok (formerly amaroK), and I love that it makes exploring my music fun. My noisy work environment (grr!) means that I'm spending almost all my time listening to music, which has certainly made me appreciate Amarok more. But occasionally I'm summoned from my other, productive world by real-world "needs" like food, drink, the toilet, and having to find out what someone means when there's no spec to consult (grr!).
Being a former systems administrator (and, indeed, a former card-carrying security specialist - the card is now a bookmark...), I lock my console for even the smallest interruption. After the first few hundred interruptions (ie, the first two or three days), I got irritated by not having paused my music and having locked my screen and having to unlock it, pause my music, and lock again. So, I wrote something to automatically pause when I lock my screen - I'm using GNOME's screensaver (aka gnome-screensaver) on Ubuntu.
Unlike xscreensaver, it doesn't have a -watch option - you have to listen to dbus events. Hint to gnome-screensaver people - dbus is a nice behind-the-scenes way of doing things, but sometimes it is nice to have a specific way to watch for things. Even if it just runs dbus-monitor with the right commands for you. Let's not forget our Unix heritage...
Getting the pausing working from dbus messages was actually quite simple - I just combined a Perl regex from one source, and Amarok command line options from another, in a simple Python program:
#!/usr/bin/env python
import subprocess
import re
DBUS_MONITOR = ["dbus-monitor", "--session",
"type='signal',interface='org.gnome.ScreenSaver',member='SessionIdleChanged'"]
PAUSE_AMAROK = ["amarok", "--pause"]
PLAY_AMAROK = ["amarok", "--play-pause"]
screensaver_on = re.compile("boolean true")
screensaver_off = re.compile("boolean false")
def main():
a = subprocess.Popen(DBUS_MONITOR, bufsize=1,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
close_fds=True)
out = a.stdout
while a.poll() is None:
line = out.readline()
if screensaver_on.search(line):
subprocess.Popen(PAUSE_AMAROK).communicate()
if screensaver_off.search(line):
subprocess.Popen(PLAY_AMAROK).communicate()
Simply, dbus-monitor watches the dbus events and delivers the events that are asked for (otherwise all of them), and send them to stdout. When the screen saver turns on, I tell Amarok to pause. When it turns back off, I tell Amarok to unpause. To be utterly random, I used the subprocess module to call dbus-monitor and Amarok's command line.
Amarok also offers a DCOP interface to tell it what to do and find out what it is doing. Between the dbus and dcop Python modules, we could get rid of all the silly command line stuff. But it works fine now. (And since dbus is replacing DCOP in KDE4, there will almost certainly be a Amarok plugin built-in to do this.)
I also added simple Python daemonising code, stolen from the ActiveState Python Cookbook, so that I can just fire-and-forget it:
def daemonize(func):
import os
import sys
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent, print eventual PID before
print "Daemon PID %d" % pid
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
# start the daemon main loop
func()
if __name__ == "__main__":
daemonize(main)
Actually, there are two kinds of people: Those who love Amarok, and those who use systems on which iTunes runs natively. :-) The general concept of "type managers" (http://www.icefox.net/articles/typemanager.php) is very interesting, though. I think we'll see more of their kind as we head off into metadata-indexed filesystems on ever-bigger hard drives. Oh, yes, and I love Amarok too. (The album, not the software package.)
Why do you use regular expressions for simple substring matching?
This could be easily done with the "in" operator as well:
Also, did you know that there are Python bindings for dbus (though they are probably overkill for the taks at hand):
Another why question: why use subprocess and call dbus-monitor instead of python's D-BUS bindings?
A much neater solution (for rhythmbox, of course):