Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-02-26 00:24:48 (GMT)
committer Dan Williams <dcbw@redhat.com>2007-02-26 00:24:48 (GMT)
commita72175ff68de54fac9f50136b29f9d156400a5a7 (patch)
tree356850eb7029a81a411abcf42aa6d7686f0c5e7f /services
parent1f91f7f7afd34143721ac66936546e4444950369 (diff)
Create separate plugins for connection methods
Diffstat (limited to 'services')
-rw-r--r--services/presence2/Makefile.am4
-rw-r--r--services/presence2/buddy.py4
-rw-r--r--services/presence2/presenceservice.py58
-rw-r--r--services/presence2/server_plugin.py225
-rw-r--r--services/presence2/telepathyclient.py194
5 files changed, 247 insertions, 238 deletions
diff --git a/services/presence2/Makefile.am b/services/presence2/Makefile.am
index b0942db..fbd3125 100644
--- a/services/presence2/Makefile.am
+++ b/services/presence2/Makefile.am
@@ -4,7 +4,9 @@ sugar_PYTHON = \
activity.py \
buddy.py \
buddyiconcache.py \
- presenceservice.py
+ linklocal_plugin.py \
+ presenceservice.py \
+ server_plugin.py
bin_SCRIPTS = sugar-presence-service2
diff --git a/services/presence2/buddy.py b/services/presence2/buddy.py
index 63f6da9..e010d19 100644
--- a/services/presence2/buddy.py
+++ b/services/presence2/buddy.py
@@ -32,7 +32,7 @@ class Buddy(dbus.service.Object):
"""Represents another person on the network and keeps track of the
activities and resources they make available for sharing."""
- def __init__(self, bus_name, object_id, icon_cache):
+ def __init__(self, bus_name, object_id, icon_cache, handle=None):
if not bus_name:
raise ValueError("DBus bus name must be valid")
if not object_id or not isinstance(object_id, int):
@@ -48,6 +48,8 @@ class Buddy(dbus.service.Object):
self._icon_cache = icon_cache
+ self._handle = handle
+
self._nick_name = None
self._color = None
self._key = None
diff --git a/services/presence2/presenceservice.py b/services/presence2/presenceservice.py
index 49a4dc6..b5626c4 100644
--- a/services/presence2/presenceservice.py
+++ b/services/presence2/presenceservice.py
@@ -21,11 +21,12 @@ from telepathy.interfaces import (CONN_MGR_INTERFACE, CONN_INTERFACE)
from telepathy.constants import (CONNECTION_STATUS_CONNECTING, CONNECTION_STATUS_CONNECTED,
CONNECTION_STATUS_DISCONNECTED, CONNECTION_HANDLE_TYPE_CONTACT)
-import telepathyclient
+from server_plugin import ServerPlugin
+from linklocal_plugin import LinkLocalPlugin
+
from buddy import Buddy, Owner
from activity import Activity
import buddyiconcache
-from sugar import profile
_PRESENCE_SERVICE = "org.laptop.Sugar.Presence"
@@ -60,50 +61,23 @@ class PresenceService(dbus.service.Object):
self._registry = ManagerRegistry()
self._registry.LoadManagers()
- self._server_client = self._connect_to_server()
- self._handles[self._server_client] = {}
+ # Set up the server connection
+ self._server_plugin = ServerPlugin(self._registry)
+ self._handles[self._server_plugin] = {}
- # Telepathy link local connection
- self._ll_client = None
+ self._server_plugin.connect('status', self._server_status_cb)
+ self._server_plugin.connect('contact-online', self._contact_online)
+ self._server_plugin.connect('contact-offline', self._contact_offline)
+ self._server_plugin.start()
- self._server_client.connect('contact-online', self._contact_online)
- self._server_client.connect('contact-offline', self._contact_offline)
- self._server_client.run()
+ # Set up the link local connection
+ self._ll_plugin = LinkLocalPlugin(self._registry)
+ self._handles[self._ll_plugin] = {}
dbus.service.Object.__init__(self, self._bus_name, _PRESENCE_PATH)
- def _connect_to_server(self):
- protocol = 'jabber'
- account = {
- 'account': 'blah@collabora.co.uk',
- 'password': 'learn',
- 'server': 'light.bluelinux.co.uk'
- }
-
- mgr = self._registry.GetManager('gabble')
- conn = None
-
- # Search existing connections, if any, that we might be able to use
- connections = Connection.get_connections()
- for item in connections:
- if item[CONN_INTERFACE].GetProtocol() != protocol:
- continue
- if not item.object_path.startswith("/org/freedesktop/Telepathy/Connection/gabble/jabber/"):
- continue
- if item[CONN_INTERFACE].GetStatus() == CONNECTION_STATUS_CONNECTED:
- self_name = account['account']
- test_handle = item[CONN_INTERFACE].RequestHandles(CONNECTION_HANDLE_TYPE_CONTACT, [self_name])[0]
- if item[CONN_INTERFACE].GetSelfHandle() != test_handle:
- continue
- conn = item
-
- if not conn:
- # Create a new connection
- conn_bus_name, conn_object_path = \
- mgr[CONN_MGR_INTERFACE].RequestConnection(protocol, account)
- conn = Connection(conn_bus_name, conn_object_path)
-
- return telepathyclient.TelepathyClient(conn)
+ def _server_status_cb(self, plugin, status):
+ pass
def _contact_online(self, tp, handle, key):
buddy = self._buddies.get(key)
@@ -111,7 +85,7 @@ class PresenceService(dbus.service.Object):
if not buddy:
# we don't know yet this buddy
objid = self._get_next_object_id()
- buddy = Buddy(self._bus_name, objid, self._icon_cache)
+ buddy = Buddy(self._bus_name, objid, self._icon_cache, handle=handle)
buddy.set_key(key)
print "create buddy"
self._buddies[key] = buddy
diff --git a/services/presence2/server_plugin.py b/services/presence2/server_plugin.py
new file mode 100644
index 0000000..2a977f7
--- /dev/null
+++ b/services/presence2/server_plugin.py
@@ -0,0 +1,225 @@
+# Copyright (C) 2007, Red Hat, Inc.
+# Copyright (C) 2007, Collabora Ltd.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gobject
+from sugar import profile
+from sugar import util
+import logging
+
+from telepathy.client import ConnectionManager, ManagerRegistry, Connection, Channel
+from telepathy.interfaces import (
+ CONN_MGR_INTERFACE, CONN_INTERFACE, CHANNEL_TYPE_CONTACT_LIST, CHANNEL_INTERFACE_GROUP, CONN_INTERFACE_ALIASING,
+ CONN_INTERFACE_AVATARS, CONN_INTERFACE_PRESENCE)
+from telepathy.constants import (
+ CONNECTION_HANDLE_TYPE_NONE, CONNECTION_HANDLE_TYPE_CONTACT,
+ CONNECTION_STATUS_CONNECTED, CONNECTION_STATUS_DISCONNECTED, CONNECTION_STATUS_CONNECTING,
+ CONNECTION_HANDLE_TYPE_LIST, CONNECTION_HANDLE_TYPE_CONTACT)
+
+
+class ServerPlugin(gobject.GObject):
+ __gsignals__ = {
+ 'contact-online': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])),
+ 'contact-offline': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'status': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_INT]))
+ }
+
+ def __init__(self, registry):
+ gobject.GObject.__init__(self)
+
+ self._registry = registry
+ self._online_contacts = set()
+ self._account = self._get_account_info()
+
+ self._conn = self._init_connection()
+
+ def _get_account_info(self):
+ account_info = {'server': 'olpc.collabora.co.uk'}
+
+ pubkey = profile.get_pubkey()
+ khash = util.printable_hash(util._sha_data(pubkey))
+ account_info['account'] = "%s@%s" % (khash, account_info['server'])
+
+ account_info['password'] = profile.get_private_key_hash()
+ return account_info
+
+ def _get_connection(self):
+ protocol = 'jabber'
+
+ mgr = self._registry.GetManager('gabble')
+
+ # Search existing connections, if any, that we might be able to use
+ connections = Connection.get_connections()
+ conn = None
+ for item in connections:
+ if not item.object_path.startswith("/org/freedesktop/Telepathy/Connection/gabble/jabber/"):
+ continue
+ if item[CONN_INTERFACE].GetStatus() == CONNECTION_STATUS_DISCONNECTED:
+ item[CONN_INTERFACE].Disconnect()
+ continue
+ if item[CONN_INTERFACE].GetProtocol() != protocol:
+ continue
+ if item[CONN_INTERFACE].GetStatus() == CONNECTION_STATUS_CONNECTED:
+ self_name = self._account['account']
+ test_handle = item[CONN_INTERFACE].RequestHandles(CONNECTION_HANDLE_TYPE_CONTACT, [self_name])[0]
+ if item[CONN_INTERFACE].GetSelfHandle() != test_handle:
+ continue
+ conn = item
+ break
+
+ if not conn:
+ # Create a new connection
+ conn_bus_name, conn_object_path = \
+ mgr[CONN_MGR_INTERFACE].RequestConnection(protocol,
+ self._account)
+ conn = Connection(conn_bus_name, conn_object_path)
+
+ conn[CONN_INTERFACE].connect_to_signal('StatusChanged', self._status_changed_cb)
+
+ # hack
+ conn._valid_interfaces.add(CONN_INTERFACE_PRESENCE)
+ conn[CONN_INTERFACE_PRESENCE].connect_to_signal('PresenceUpdate',
+ self._presence_update_cb)
+
+ return conn
+
+ def _request_list_channel(self, name):
+ handle = self._conn[CONN_INTERFACE].RequestHandles(
+ CONNECTION_HANDLE_TYPE_LIST, [name])[0]
+ chan_path = self._conn[CONN_INTERFACE].RequestChannel(
+ CHANNEL_TYPE_CONTACT_LIST, CONNECTION_HANDLE_TYPE_LIST,
+ handle, True)
+ channel = Channel(self._conn._dbus_object._named_service, chan_path)
+ # hack
+ channel._valid_interfaces.add(CHANNEL_INTERFACE_GROUP)
+ return channel
+
+ def _connected_cb(self):
+ # the group of contacts who may receive your presence
+ publish = self._request_list_channel('publish')
+ publish_handles, local_pending, remote_pending = publish[CHANNEL_INTERFACE_GROUP].GetAllMembers()
+
+ # the group of contacts for whom you wish to receive presence
+ subscribe = self._request_list_channel('subscribe')
+ subscribe_handles = subscribe[CHANNEL_INTERFACE_GROUP].GetMembers()
+
+ if local_pending:
+ # accept pending subscriptions
+ #print 'pending: %r' % local_pending
+ publish[CHANNEL_INTERFACE_GROUP].AddMembers(local_pending, '')
+
+ not_subscribed = list(set(publish_handles) - set(subscribe_handles))
+ self_handle = self._conn[CONN_INTERFACE].GetSelfHandle()
+ self._online_contacts.add(self_handle)
+
+ for handle in not_subscribed:
+ # request subscriptions from people subscribed to us if we're not subscribed to them
+ subscribe[CHANNEL_INTERFACE_GROUP].AddMembers([self_handle], '')
+
+ # hack
+ self._conn._valid_interfaces.add(CONN_INTERFACE_ALIASING)
+
+ if CONN_INTERFACE_ALIASING in self._conn:
+ aliases = self._conn[CONN_INTERFACE_ALIASING].RequestAliases(subscribe_handles)
+ else:
+ aliases = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, subscribe_handles)
+
+ #for handle, alias in zip(subscribe_handles, aliases):
+ # print alias
+ # self.buddies[handle].alias = alias
+
+ # hack
+ self._conn._valid_interfaces.add(CONN_INTERFACE_AVATARS)
+
+ #if CONN_INTERFACE_AVATARS in self._conn:
+ # #tokens = self._conn[CONN_INTERFACE_AVATARS].RequestAvatarTokens(subscribe_handles)
+
+ # #for handle, token in zip(subscribe_handles, tokens):
+ # for handle in subscribe_handles:
+ # avatar, mime_type = self._conn[CONN_INTERFACE_AVATARS].RequestAvatar(handle)
+ # self.buddies[handle].avatar = ''.join(map(chr, avatar))
+
+ # import gtk
+ # window = gtk.Window()
+ # window.set_title(self.buddies[handle].alias)
+ # loader = gtk.gdk.PixbufLoader()
+ # loader.write(self.buddies[handle].avatar)
+ # loader.close()
+ # image = gtk.Image()
+ # image.set_from_pixbuf(loader.get_pixbuf())
+ # window.add(image)
+ # window.show_all()
+
+ def _status_changed_cb(self, state, reason):
+ if state == CONNECTION_STATUS_CONNECTING:
+ print 'connecting: %r' % reason
+ elif state == CONNECTION_STATUS_CONNECTED:
+ print 'connected: %r' % reason
+ self.emit('status', state)
+ self._connected_cb()
+ elif state == CONNECTION_STATUS_DISCONNECTED:
+ print 'disconnected: %r' % reason
+ self.emit('status', state, int(reason))
+
+ def start(self):
+ # If the connection is already connected query initial contacts
+ conn_status = self._conn[CONN_INTERFACE].GetStatus()
+ if conn_status == CONNECTION_STATUS_CONNECTED:
+ self._connected_cb()
+ subscribe = self._request_list_channel('subscribe')
+ subscribe_handles = subscribe[CHANNEL_INTERFACE_GROUP].GetMembers()
+ self._conn[CONN_INTERFACE_PRESENCE].RequestPresence(subscribe_handles)
+ elif conn_status == CONNECTION_STATUS_CONNECTING:
+ pass
+ else:
+ self._conn[CONN_INTERFACE].Connect()
+
+ def disconnect(self):
+ self._conn[CONN_INTERFACE].Disconnect()
+
+ def _contact_go_offline(self, handle):
+ name = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0]
+ print name, "offline"
+
+ self._online_contacts.remove(handle)
+ self.emit("contact-offline", handle)
+
+ def _contact_go_online(self, handle):
+ name = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0]
+ print name, "online"
+
+ # TODO: use the OLPC interface to get the key
+ key = handle
+
+ self._online_contacts.add(handle)
+ self.emit("contact-online", handle, key)
+
+ def _presence_update_cb(self, presence):
+ for handle in presence:
+ timestamp, statuses = presence[handle]
+
+ name = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0]
+ online = handle in self._online_contacts
+
+ for status, params in statuses.items():
+ if not online and status in ["available", "away", "brb", "busy", "dnd", "xa"]:
+ self._contact_go_online(handle)
+ elif online and status in ["offline", "invisible"]:
+ self._contact_go_offline(handle)
+
diff --git a/services/presence2/telepathyclient.py b/services/presence2/telepathyclient.py
deleted file mode 100644
index 34843bd..0000000
--- a/services/presence2/telepathyclient.py
+++ /dev/null
@@ -1,194 +0,0 @@
-
-import dbus.glib
-import gobject
-
-from telepathy.client import ConnectionManager, ManagerRegistry, Connection, Channel
-from telepathy.interfaces import (
- CONN_MGR_INTERFACE, CONN_INTERFACE, CHANNEL_TYPE_CONTACT_LIST, CHANNEL_INTERFACE_GROUP, CONN_INTERFACE_ALIASING,
- CONN_INTERFACE_AVATARS, CONN_INTERFACE_PRESENCE)
-from telepathy.constants import (
- CONNECTION_HANDLE_TYPE_NONE, CONNECTION_HANDLE_TYPE_CONTACT,
- CONNECTION_STATUS_CONNECTED, CONNECTION_STATUS_DISCONNECTED, CONNECTION_STATUS_CONNECTING,
- CONNECTION_HANDLE_TYPE_LIST, CONNECTION_HANDLE_TYPE_CONTACT)
-
-loop = None
-
-import buddy
-
-class TelepathyClient(gobject.GObject):
- __gsignals__ = {
- 'contact-online':(gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])),
- 'contact-offline':(gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- }
-
- def __init__(self, conn):
- gobject.GObject.__init__(self)
-
- self._online_contacts = set()
-
- conn[CONN_INTERFACE].connect_to_signal('StatusChanged',
- self._status_changed_cb)
-
- # hack
- conn._valid_interfaces.add(CONN_INTERFACE_PRESENCE)
- conn[CONN_INTERFACE_PRESENCE].connect_to_signal('PresenceUpdate',
- self._presence_update_cb)
-
- self.conn = conn
-
- def _request_list_channel(self, name):
- handle = self.conn[CONN_INTERFACE].RequestHandles(
- CONNECTION_HANDLE_TYPE_LIST, [name])[0]
- chan_path = self.conn[CONN_INTERFACE].RequestChannel(
- CHANNEL_TYPE_CONTACT_LIST, CONNECTION_HANDLE_TYPE_LIST,
- handle, True)
- channel = Channel(self.conn._dbus_object._named_service, chan_path)
- # hack
- channel._valid_interfaces.add(CHANNEL_INTERFACE_GROUP)
- return channel
-
- def _connected_cb(self):
- # the group of contacts who may receive your presence
- publish = self._request_list_channel('publish')
- publish_handles, local_pending, remote_pending = publish[CHANNEL_INTERFACE_GROUP].GetAllMembers()
-
- # the group of contacts for whom you wish to receive presence
- subscribe = self._request_list_channel('subscribe')
- subscribe_handles = subscribe[CHANNEL_INTERFACE_GROUP].GetMembers()
-
- if local_pending:
- # accept pending subscriptions
- #print 'pending: %r' % local_pending
- publish[CHANNEL_INTERFACE_GROUP].AddMembers(local_pending, '')
-
- not_subscribed = list(set(publish_handles) - set(subscribe_handles))
- self_handle = self.conn[CONN_INTERFACE].GetSelfHandle()
- self._online_contacts.add(self_handle)
-
- for handle in not_subscribed:
- # request subscriptions from people subscribed to us if we're not subscribed to them
- subscribe[CHANNEL_INTERFACE_GROUP].AddMembers([self_handle], '')
-
- # hack
- self.conn._valid_interfaces.add(CONN_INTERFACE_ALIASING)
-
- if CONN_INTERFACE_ALIASING in self.conn:
- aliases = self.conn[CONN_INTERFACE_ALIASING].RequestAliases(subscribe_handles)
- else:
- aliases = self.conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, subscribe_handles)
-
- #for handle, alias in zip(subscribe_handles, aliases):
- # print alias
- # self.buddies[handle].alias = alias
-
- # hack
- self.conn._valid_interfaces.add(CONN_INTERFACE_AVATARS)
-
- #if CONN_INTERFACE_AVATARS in self.conn:
- # #tokens = self.conn[CONN_INTERFACE_AVATARS].RequestAvatarTokens(subscribe_handles)
-
- # #for handle, token in zip(subscribe_handles, tokens):
- # for handle in subscribe_handles:
- # avatar, mime_type = self.conn[CONN_INTERFACE_AVATARS].RequestAvatar(handle)
- # self.buddies[handle].avatar = ''.join(map(chr, avatar))
-
- # import gtk
- # window = gtk.Window()
- # window.set_title(self.buddies[handle].alias)
- # loader = gtk.gdk.PixbufLoader()
- # loader.write(self.buddies[handle].avatar)
- # loader.close()
- # image = gtk.Image()
- # image.set_from_pixbuf(loader.get_pixbuf())
- # window.add(image)
- # window.show_all()
-
- def _status_changed_cb(self, state, reason):
- if state == CONNECTION_STATUS_CONNECTING:
- print 'connecting'
- elif state == CONNECTION_STATUS_CONNECTED:
- print 'connected'
- self._connected_cb()
- elif state == CONNECTION_STATUS_DISCONNECTED:
- print 'disconnected'
- loop.quit()
-
- def run(self):
- # If the connection is already connected query initial contacts
- conn_status = self.conn[CONN_INTERFACE].GetStatus()
- if conn_status == CONNECTION_STATUS_CONNECTED:
- self._connected_cb()
- subscribe = self._request_list_channel('subscribe')
- subscribe_handles = subscribe[CHANNEL_INTERFACE_GROUP].GetMembers()
- self.conn[CONN_INTERFACE_PRESENCE].RequestPresence(subscribe_handles)
- elif conn_status == CONNECTION_STATUS_CONNECTING:
- pass
- else:
- self.conn[CONN_INTERFACE].Connect()
-
- def disconnect(self):
- self.conn[CONN_INTERFACE].Disconnect()
-
-
- def _contact_go_offline(self, handle):
- name = self.conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0]
- print name, "offline"
-
- self._online_contacts.remove(handle)
- self.emit("contact-offline", handle)
-
- def _contact_go_online(self, handle):
- name = self.conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0]
- print name, "online"
-
- # TODO: use the OLPC interface to get the key
- key = handle
-
- self._online_contacts.add(handle)
- self.emit("contact-online", handle, key)
-
- def _presence_update_cb(self, presence):
- for handle in presence:
- timestamp, statuses = presence[handle]
-
- name = self.conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0]
- online = handle in self._online_contacts
-
- for status, params in statuses.items():
- if not online and status in ["available", "away", "brb", "busy", "dnd", "xa"]:
- self._contact_go_online(handle)
- elif online and status in ["offline", "invisible"]:
- self._contact_go_offline(handle)
-
-if __name__ == '__main__':
- import logging
- logging.basicConfig()
-
- registry = ManagerRegistry()
- registry.LoadManagers()
- mgr = registry.GetManager('gabble')
- protocol = 'jabber'
- account = {
- 'account': 'olpc@collabora.co.uk',
- 'password': 'learn',
- 'server': 'light.bluelinux.co.uk'
- }
- loop = gobject.MainLoop()
- conn_bus_name, conn_object_path = \
- mgr[CONN_MGR_INTERFACE].RequestConnection(protocol, account)
- print conn_bus_name
- print conn_object_path
- conn = Connection(conn_bus_name, conn_object_path)
- client = TelepathyClient(conn)
-
- try:
- loop.run()
- finally:
- try:
- #conn[CONN_INTERFACE].Disconnect()
- client.disconnect()
- except:
- pass
-