Awesome D-Bus

posted by codders in code, python

I’ve been using a new window manager – Awesome WM. It’s pretty fine. At version 2.3, it doesn’t currently support window tabbing in the way Ion does, but I’m assured that that feature is on its way. Everything else works pretty swishly, and the desktop tagging features are particularly nice.

It doesn’t come with a system tray out of the box, so I’d managed to miss some incoming instant messages. Fortunately you can write your own widgets for Awesome – you just pipe your widget updates into ‘awesome-client’.

So all I needed was a way to get the new message notification out of Pidgin…

#!/usr/bin/env python

from BeautifulSoup import BeautifulSoup
import os
import dbus.glib
import gobject
import sys

class CheckedObject:
    def __init__(self, obj):
        self.obj = obj

    def __getattr__(self, attr):
        return CheckedAttribute(self, attr)

class CheckedAttribute:
    def __init__(self, cobj, attr):
        self.cobj = cobj
        self.attr = attr

    def __call__(self, *args):
        result = self.cobj.obj.__getattr__(self.attr)(*args)
        if result == 0:
            raise "Error: " + self.attr + " " + 
               str(args) + " returned " + 
               str(result)
        return result

def awesome_write(string):
    awesome = os.popen("awesome-client", "w")
    widget_message = "0 widget_tell widgetbar im text %s\n" % string
    awesome.write(widget_message)
    awesome.close()

def message_received(account, sender, message, conversation, flags):
    html = BeautifulSoup(message)
    try:
      message = html.font.font.string
    except Exception, e:
      pass
    awesome_write("%s <%s>" % (message, sender))

def message_sent(account, receiver, message):
    awesome_write("")

bus = dbus.SessionBus()

obj = None
try:
    obj = bus.get_object(
        "im.pidgin.purple.PurpleService",
        "/im/pidgin/purple/PurpleObject")
except:
    print "Couldn't find Pidgin on the Bus"
    sys.exit(1)

purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")

cpurple = CheckedObject(purple)

bus.add_signal_receiver(message_received, dbus_interface="im.pidgin.purple.PurpleInterface", signal_name="ReceivedImMsg")
bus.add_signal_receiver(message_sent, dbus_interface="im.pidgin.purple.PurpleInterface", signal_name="SentImMsg")

gobject.MainLoop().run()

D-Bus really seems to be coming along quite nicely. dbus-inspector shows that there are a bunch of applications enabled for it (including Pidgin and XChat), and the language support seems to be fairly polished. Can’t wait to see what else ends up on the bus.

Ars run-through (with code):
http://arstechnica.com/reviews/apps/pidgin-2-0.ars/4

Pidgin list of conversation signals:
http://developer.pidgin.im/doxygen/dev/html/conversation-signals.html#sent-im-msg

D-Bus Inspector:
http://www.vitavonni.de/projekte/dbus-inspector.html.en

Awesome WM:
http://awesome.naquadah.org/

Ion WM:
http://modeemi.fi/~tuomov/ion/