D-Bus Growl Listener for the Gnome Desktop

Since the Gnome folk and the folk never got around to agreeing on the same kind of desktop notifications or how to exchange them over a network, I finally decided to roll my own after a year or so of not having a more or less permanent box.

Basically I sat down one day and hacked a daemon in 15 minutes or so that listens for notifications and maps them to D-Bus for display on any recent Gnome system. This allows me to get desktop notifications when my router goes down or my server feels lonely regardless of the platform I'm using.

The code below is fairly "dumb" and makes no attempt at handling application registration, priorities or any niceties, but it works fine for me.

I have removed the calls to that allow my local relay (which listens for notifications from my machines out on the Internet and relays them to the LAN) to find all -enabled machines, but this will work fine by itself (provided you also get , of course).

A Windows variant of this is forthcoming - in a year or so.

#!/usr/bin/env python

"""Growl 0.6 DBUS Glue"""
__version__ = "0.1"
__author__ = "Rui Carmo (http://the.taoofmac.com)"
__copyright__ = "(C) 2006 Rui Carmo. Code under BSD License."

import sys, os
import dbus
import dbus.glib
import gobject
from regrowl import GrowlPacket
from netgrowl import *
from SocketServer import *


class GrowlListener(UDPServer):
  """Growl Notification Listener"""
  allow_reuse_address = True
  
  def __init__(self, inpassword = None, outpassword = None):
    """Initializes the relay and launches the resolver thread"""
    self.inpassword = inpassword
    self.outpassword = outpassword
    bus = dbus.SessionBus()
    bus.get_object("org.freedesktop.DBus","/org/freedesktop/DBus")
    notify_service = bus.get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications')
    self.interface = dbus.Interface(notify_service, 'org.freedesktop.Notifications')
    UDPServer.__init__(self,('localhost', GROWL_UDP_PORT), _RequestHandler)
  # end def
  
  def server_close(self):
    self.resolver.shutdown()
  # end def
# end class


class _RequestHandler(DatagramRequestHandler):
  """Processes and each incoming notification packet"""
        
  def handle(self):
    """Handles each request"""
    p = GrowlPacket(self.rfile.read(), self.server.inpassword,self.server.outpassword)
    if p.type() == 'NOTIFY':
      notification,title,description,app = p.info()
      self.server.interface.Notify(app,0,'/usr/share/icons/gnome/scalable/categories/stock_internet.svg',title,notification,[],{},-1)

if __name__ == "__main__":
  r = GrowlListener('password','password') 
  try:
    r.serve_forever()
  except KeyboardInterrupt:
    r.server_close()

This page is referenced in: