[Telepathy-commits] [telepathy-doc/master] Beginnings of a complete GTK+ chat client example
Davyd Madeley
davyd at madeley.id.au
Sun Mar 8 23:44:26 PDT 2009
---
docs/examples/pygtk_chat_client/example.py | 191 ++++++++++++++++++++++++++++
1 files changed, 191 insertions(+), 0 deletions(-)
create mode 100755 docs/examples/pygtk_chat_client/example.py
diff --git a/docs/examples/pygtk_chat_client/example.py b/docs/examples/pygtk_chat_client/example.py
new file mode 100755
index 0000000..72d50fd
--- /dev/null
+++ b/docs/examples/pygtk_chat_client/example.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+
+import sys
+
+import gtk
+import gobject
+import dbus.mainloop.glib
+dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
+
+import telepathy
+import telepathy.client
+from telepathy.interfaces import CONNECTION_MANAGER, \
+ CONNECTION, \
+ CONNECTION_INTERFACE_REQUESTS, \
+ CONNECTION_INTERFACE_CONTACTS, \
+ CONNECTION_INTERFACE_ALIASING, \
+ CONNECTION_INTERFACE_SIMPLE_PRESENCE, \
+ CHANNEL, \
+ CHANNEL_TYPE_CONTACT_LIST, \
+ CHANNEL_TYPE_TEXT, \
+ CHANNEL_INTERFACE_MESSAGES, \
+ CHANNEL_INTERFACE_GROUP
+from telepathy.constants import CONNECTION_STATUS_CONNECTED, \
+ CONNECTION_STATUS_DISCONNECTED, \
+ HANDLE_TYPE_CONTACT, \
+ HANDLE_TYPE_LIST, \
+ HANDLE_TYPE_GROUP
+
+DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties'
+
+def generic_reply(*args): pass
+
+class Connection(telepathy.client.Connection):
+ def __init__(self, sm, bus_name, object_path):
+ super(Connection, self).__init__(bus_name, object_path)
+
+ self.sm = sm
+
+ self[CONNECTION].connect_to_signal('StatusChanged', self.status_changed)
+ self[CONNECTION].Connect(reply_handler = generic_reply,
+ error_handler = self.sm.error)
+
+ def status_changed(self, status, reason):
+ if status == CONNECTION_STATUS_DISCONNECTED:
+ print 'Disconnected!'
+ # FIXME: signal disconnection with the SM
+ gtk.main_quit()
+ return
+
+ elif status != CONNECTION_STATUS_CONNECTED:
+ return
+
+ print 'Carrier Detected'
+ # NB. this should be a property eventually
+ self[CONNECTION].GetInterfaces(reply_handler = self._interfaces_cb,
+ error_handler = self.sm.error)
+
+ def _interfaces_cb(self, interfaces):
+ self.interfaces = interfaces
+
+ self.sm.connection_ready(self)
+
+ def disconnect(self):
+ self[CONNECTION].Disconnect(reply_handler = generic_reply,
+ error_handler = self.sm.error)
+
+ def ensure_channel(self, channel_obj, handle_type, target_id, props = {}):
+
+ d = {
+ CHANNEL + '.ChannelType' : channel_obj.channel_type,
+ CHANNEL + '.TargetHandleType' : handle_type,
+ CHANNEL + '.TargetID' : target_id,
+ }
+
+ d.update(props)
+
+ def _ensure_channel_error(self, error):
+ print 'Channel could not be created for dict: %s' % d
+
+ if CONNECTION_INTERFACE_REQUESTS in self.interfaces:
+ self[CONNECTION_INTERFACE_REQUESTS].EnsureChannel(d,
+ reply_handler = lambda a, b, c: channel_obj(self, b, a),
+ error_handler = self._ensure_channel_error)
+ else:
+ self.sm.error("Requests interface unavailable, get a better CM")
+
+class Channel(telepathy.client.Channel):
+ def __init__(self, conn, object_path, yours = False):
+ self.conn = conn
+ self.sm = conn.sm
+ self.yours = yours
+
+ print 'Channel came up... requesting interfaces'
+ super(Channel, self).__init__(conn.service_name, object_path)
+
+ self[DBUS_PROPERTIES].Get (CHANNEL, 'Interfaces',
+ reply_handler = self._interfaces_cb,
+ error_handler = self.sm.error)
+
+ def _interfaces_cb(self, interfaces):
+ self.interfaces = interfaces
+
+ self.ready()
+
+ def ready(self):
+ pass
+
+class ContactList(Channel):
+ channel_type = CHANNEL_TYPE_CONTACT_LIST
+
+ def ready(self):
+ # get the list of handles
+ if CHANNEL_INTERFACE_GROUP in self.interfaces:
+ self[DBUS_PROPERTIES].Get(CHANNEL_INTERFACE_GROUP, 'Members',
+ reply_handler = self._members_cb,
+ error_handler = self.sm.error)
+ else:
+ print 'Channel does not implement Group... strange'
+
+ def _members_cb(self, handles):
+ # look them up via the contacts interface
+ if CONNECTION_INTERFACE_CONTACTS in self.conn.interfaces:
+ self.conn[CONNECTION_INTERFACE_CONTACTS].GetContactAttributes(
+ handles,
+ [
+ CONNECTION,
+ CONNECTION_INTERFACE_ALIASING,
+ CONNECTION_INTERFACE_SIMPLE_PRESENCE,
+ ],
+ False,
+ reply_handler = self._attributes_cb,
+ error_handler = self.sm.error)
+
+ def _attributes_cb(self, map):
+ print 'Got contact list'
+
+class StateMachine(object):
+ def __init__(self, account, password):
+ """e.g. account = 'bob at example.com/test'
+ password = 'bigbob'
+ """
+
+ reg = telepathy.client.ManagerRegistry()
+ reg.LoadManagers()
+
+ # get the gabble Connection Manager
+ self.cm = cm = reg.GetManager('gabble')
+
+ print 'Connecting...'
+ cm[CONNECTION_MANAGER].RequestConnection('jabber',
+ {
+ 'account': account,
+ 'password': password,
+ },
+ reply_handler = lambda a, b: Connection (self, a, b),
+ error_handler = self.error)
+
+ def error(self, error):
+ print "Telepathy Error: %s" % error
+ print "Disconnecting..."
+ self.disconnect()
+
+ def connection_ready(self, conn):
+ print "Connection Ready"
+ self.conn = conn
+
+ # request the contact lists
+ print 'Requesting roster...'
+ self.conn.ensure_channel (ContactList, HANDLE_TYPE_LIST, 'subscribe')
+
+ def disconnect(self):
+ try:
+ self.conn.disconnect()
+ except:
+ gtk.main_quit()
+
+if __name__ == '__main__':
+ import getpass
+ account = sys.argv[1]
+ password = getpass.getpass()
+
+ sm = StateMachine(account, password)
+
+ try:
+ print 'Running...'
+ gtk.main()
+ except KeyboardInterrupt:
+ print "Terminating connection..."
+ sm.disconnect()
+ # reengage the mainloop so that we can disconnect cleanly
+ gtk.main()
--
1.5.6.5
More information about the telepathy-commits
mailing list