Pidgin Nachrichtenweiterleitung mit DBus

Eigentlich hat alles damit angefangen, dass ich mir ein “Googlephone” G1 gekauft habe. Dieses hat echt gute Features und durch eine gewisse Anbindung an die Googledienste auch Push-Funktionen, wie Googlemail. Ich bin mir nicht sicher, aber ich vermute, dass auch Google Talk auf dem G1 als Push-Dienst funktioniert. Beim Hören eines Podcasts kam ich auf die Idee, mir Systemnachrichten über Google Talk auf das Handy schicken zu lassen. Als erstes ist mir dann aber etwas Anderes eingefallen. Es wäre schön, dass, wenn man sich vom Rechner entfernt, die eintreffenden IMs weitergeleitet werden würden. Wenn man dann dringend erreicht werden muss, merkt man das auch. Eigentlich gleicht man damit nur nicht vorhandene Fähigkeiten der proprietären Protokolle gegenüber jabber aus. Aber wer nutzt schon jabber... (leider) Lange Rede, kurze Zusammenfassung: Ich wollte eine Weiterleitung von IMs auf jabber (Google Talk). Von DBus hatte ich schon mal gehört, daher hab ich über die DBus-Anbindung von Pidgin versucht. Im Netz habe ich einige passende Codefragmente gefunden, die allesamt in Python geschrieben waren. Ich hab es dann auch mit Python versucht, obwohl ich davon nicht viel Ahnung habe. Und hier ist das zusammengestückelte Skript zur Nachrichtenweiterleitung:

#!/usr/bin/env python

# Version: 0.2

import sys
import os
import xmpp
import time
import urllib
import urllib2
import dbus
import gobject
import dbus.glib
from dbus.mainloop.glib import DBusGMainLoop

def sendToJabber(text):
        tojid = 'Empfängeradresse'
        jidparams={}
        jid=xmpp.protocol.JID('Benutzername@server.domain')
        cl=xmpp.Client(jid.getDomain(),debug=[])
        jidparams['username']="Benutzername Sender"
        jidparams['password']="Passwort"
        jidparams['resource']="away-forward"


        con=cl.connect()
        if not con:
                print 'could not connect!'
                sys.exit()
        print 'connected with',con
        auth=cl.auth(jidparams['username'],jidparams['password'],resource=jidparams['resource'])
        if not auth:
                print 'could not authenticate!'
                sys.exit()
        print 'authenticated using',auth

        id=cl.send(xmpp.protocol.Message(tojid,text))
        print 'sent message with id',id

        time.sleep(1)


def onSessionIdleChanged(state):
    global away
    if state:
        away=1
    else:
        away=0

def receivedMessage(account, sender, message, conversation, flags):
    buddy = purple.PurpleFindBuddy(account, sender)
    alias = purple.PurpleBuddyGetAlias(buddy)
    text = alias + ": " + message
    if away == 1:
        sendToJabber(text)




away=0
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_signal_receiver(receivedMessage, dbus_interface="im.pidgin.purple.PurpleInterface", signal_name="ReceivedImMsg")
bus.add_signal_receiver(onSessionIdleChanged, 'SessionIdleChanged', 'org.gnome.ScreenSaver')
obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")


loop = gobject.MainLoop()
loop.run()

Der Knackpunkt bei der Sache ist die Abfrage, ob der Benutzer abwesend ist. Der Rest ist recht selbsterklärend, man benötigt nur die Adresse des Ziel-Google-Talk-Kontos und die Zugangsdaten eines zweiten jabber-Kontos zum Nachrichten senden.

Leider gibt es in Google Talk einen Bug beim Nachrichtenempfang (nicht alle werden angezeigt), aber man erhält jede Nachricht als Benachrichtigung. Und hoffentlich wird der Fehler in Android bald behoben!

Update: Das mit den Statusnummern hat sich als unzuverlässig erwiesen. Daher hab ich auf den Idle-Status von Gnome umgeschwenkt (schon im Code ergänzt).