Zachciało mi się dzisiaj wygodnego powiadamiania o poczcie. Evolution udostępnia od jakiegoś czasu powiadomienia za pomocą interfejsu D-BUS, Python ma binding dla D-BUSa, czemu więc nie napisać appletu, który by słuchał tych powiadomień?
Szybko przekonałem się, że łatwo nie będzie, bo Evolution nie posiada dla interfejsu powiadomień nazwy kanonicznej. Znaczy to mniej-więcej tyle, że D-BUS przydziela mu przy każdym włączeniu programu losową nazwę postaci
(podobnie, jak X11 numeruje swoje sesje i ekrany). Nazwa oczywiście zmienia się z każdym restartem Evo.:X.Y
I tu pojawia się problem: binding Pythona pozwala bardzo wygodnie obsługiwać typowe przypadki użycia D-BUSa. Innymi słowy, wszystko byłoby pięknie, gdyby dało się zrobić tak:
#!/usr/bin/python
import gtk
import dbus
import gnomeapplet
import sys
class evoNotify:
def handleNewMail(self, int, sig, srv, pth, msg):
self.label.set_label('new mail')
print('test')
def handleReadingMail(self, int, sig, srv, pth, msg):
self.label.set_label('read mail')
print('test')
def __init__(self, applet):
label = gtk.Label('test')
self.label = label
bus = dbus.SessionBus()
evolution = bus.get_service(':1.0')
ifc = evolution.get_object('/org/gnome/evolution/mail/newmail',
'org.gnome.evolution.mail.dbus.Signal')
applet.iface = ifc
applet.iface.connect_to_signal('MessageReading',
self.handleReadingMail)
applet.iface.connect_to_signal('NewMail',
self.handleNewMail)
applet.add(self.label)
applet.show_all()
def appletFactory(applet, iid):
evoNotify(applet)
return gtk.TRUE
gnomeapplet.bonobo_factory('OAFIID:GNOME_evoMailApplet_Factory',
gnomeapplet.Applet.__gtype__,
'evoMailApplet', '0.1', appletFactory)
gtk.main()
Ale nie można, bo niby skąd znać wcześniej unikalny numerek serwisu przyznany przez demona? W C można to prosto obejść, tam można posłużyć się add_match i wyłapywać wiadomości po filtrach, niezależnie od nadawców (mam wszelkie powody, żeby założyć, że właśnie tak działa dbus-monitor, ale nie chce mi się teraz sprawdzać), w Pythonie nie można, bo nie jest eksportowana taka metoda.
Póki co, oznacza to śmierć projektu. Przynajmniej do czasu, kiedy naprawione zostaną pythonowe wrappery, bo w C pisać tego nie zamierzam.