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.