From 1a4c721f3d564dcb7d395196130c0299a4ec1fd4 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 12 Jul 2010 20:33:19 +0200 Subject: [PATCH] Identify buddies and activities by their account and ids instead of connection and handle. --- src/sugar/presence/activity.py | 44 ++++++++++++++++++--------- src/sugar/presence/buddy.py | 16 +++++----- src/sugar/presence/presenceservice.py | 18 ++++++++--- src/sugar/presence/util.py | 14 +++++++-- 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/sugar/presence/activity.py b/src/sugar/presence/activity.py index 7b26ecd8..6882d3b8 100644 --- a/src/sugar/presence/activity.py +++ b/src/sugar/presence/activity.py @@ -35,6 +35,7 @@ from telepathy.interfaces import CHANNEL, \ PROPERTIES_INTERFACE from telepathy.constants import CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES, \ HANDLE_TYPE_ROOM, \ + HANDLE_TYPE_CONTACT, \ PROPERTY_FLAG_WRITE from sugar.presence.buddy import Buddy @@ -79,7 +80,7 @@ class Activity(gobject.GObject): 'joined': (bool, None, None, False, gobject.PARAM_READABLE), } - def __init__(self, connection, room_handle=None, properties=None): + def __init__(self, account_path, connection, room_handle=None, properties=None): if room_handle is None and properties is None: raise ValueError('Need to pass one of room_handle or properties') @@ -88,6 +89,7 @@ class Activity(gobject.GObject): gobject.GObject.__init__(self) + self._account_path = account_path self.telepathy_conn = connection self.telepathy_text_chan = None self.telepathy_tubes_chan = None @@ -121,8 +123,8 @@ class Activity(gobject.GObject): 'GetProperties', 'u', (self._room_handle,), - reply_handler=self._got_properties_cb, - error_handler=self._error_handler_cb, + reply_handler=self.__got_properties_cb, + error_handler=self.__error_handler_cb, utf8_strings=True) # As only one Activity instance is needed per activity process, @@ -136,13 +138,13 @@ class Activity(gobject.GObject): _logger.debug('%r: Activity properties changed to %r', self, properties) self._update_properties(properties) - def _got_properties_cb(self, properties): - _logger.debug('_got_properties_cb %r', properties) + def __got_properties_cb(self, properties): + _logger.debug('__got_properties_cb %r', properties) self._get_properties_call = None self._update_properties(properties) - def _error_handler_cb(self, error): - _logger.debug('_error_handler_cb %r', error) + def __error_handler_cb(self, error): + _logger.debug('__error_handler_cb %r', error) def _update_properties(self, new_props): val = new_props.get('name', self._name) @@ -227,7 +229,7 @@ class Activity(gobject.GObject): self.emit('buddy-joined', self._ps_new_object(object_path)) return False - def _buddy_handle_joined_cb(self, object_path, handle): + def __buddy_handle_joined_cb(self, object_path, handle): _logger.debug('%r: buddy %s joined with handle %u', self, object_path, handle) gobject.idle_add(self._emit_buddy_joined_signal, object_path) @@ -242,7 +244,7 @@ class Activity(gobject.GObject): self.emit('buddy-left', self._ps_new_object(object_path)) return False - def _buddy_left_cb(self, object_path): + def __buddy_left_cb(self, object_path): _logger.debug('%r: buddy %s left', self, object_path) gobject.idle_add(self._emit_buddy_left_signal, object_path) handle = self._buddy_path_to_handle.pop(object_path, None) @@ -257,7 +259,7 @@ class Activity(gobject.GObject): self.emit('new-channel', object_path) return False - def _new_channel_cb(self, object_path): + def __new_channel_cb(self, object_path): _logger.debug('%r: new channel created at %s', self, object_path) gobject.idle_add(self._emit_new_channel_signal, object_path) @@ -327,11 +329,25 @@ class Activity(gobject.GObject): _logger.debug('__text_channel_members_changed_cb %r', [added, message, added, removed, local_pending, remote_pending, actor, reason]) - for contact_handle in added: - self.emit('buddy-joined', Buddy(self.telepathy_conn, contact_handle)) + if added: + self.telepathy_conn.InspectHandles(HANDLE_TYPE_CONTACT, added, + reply_handler=self.__members_added_cb, + error_handler=self.__error_handler_cb, + dbus_interface=CONNECTION) - for contact_handle in removed: - self.emit('buddy-left', Buddy(self.telepathy_conn, contact_handle)) + if removed: + self.telepathy_conn.InspectHandles(HANDLE_TYPE_CONTACT, removed, + reply_handler=self.__members_removed_cb, + error_handler=self.__error_handler_cb, + dbus_interface=CONNECTION) + + def __members_added_cb(self, contact_ids): + for contact_id in contact_ids: + self.emit('buddy-joined', Buddy(self._account_path, contact_id)) + + def __members_removed_cb(self, contact_ids): + for contact_id in contact_ids: + self.emit('buddy-left', Buddy(self._account_path, contact_id)) def join(self): """Join this activity. diff --git a/src/sugar/presence/buddy.py b/src/sugar/presence/buddy.py index d9f5fb35..865e6632 100644 --- a/src/sugar/presence/buddy.py +++ b/src/sugar/presence/buddy.py @@ -33,6 +33,8 @@ from telepathy.interfaces import ACCOUNT, \ CONNECTION_INTERFACE_CONTACTS from telepathy.constants import HANDLE_TYPE_CONTACT +from sugar.presence.util import get_connection_manager + ACCOUNT_MANAGER_SERVICE = 'org.freedesktop.Telepathy.AccountManager' CONN_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo' @@ -261,20 +263,20 @@ class Buddy(BaseBuddy): self.contact_handle = None _logger.info('KILL_PS Handle the connection going away and coming back') + connection_manager = get_connection_manager() + connection = connection_manager.get_connection(account_path) - bus = dbus.Bus() - obj = bus.get_object(ACCOUNT_MANAGER_SERVICE, account_path) - connection_path = obj.Get(ACCOUNT, 'Connection') - connection_name = connection_path.replace('/', '.')[1:] + connection_name = connection.object_path.replace('/', '.')[1:] - obj = bus.get_object(connection_name, connection_path) + bus = dbus.SessionBus() + obj = bus.get_object(connection_name, connection.object_path) handles = obj.RequestHandles(HANDLE_TYPE_CONTACT, [self.contact_id], dbus_interface=CONNECTION) self.contact_handle = handles[0] self._get_properties_call = bus.call_async( connection_name, - connection_path, + connection.object_path, CONN_INTERFACE_BUDDY_INFO, 'GetProperties', 'u', @@ -286,7 +288,7 @@ class Buddy(BaseBuddy): self._get_attributes_call = bus.call_async( connection_name, - connection_path, + connection.object_path, CONNECTION_INTERFACE_CONTACTS, 'GetContactAttributes', 'auasb', diff --git a/src/sugar/presence/presenceservice.py b/src/sugar/presence/presenceservice.py index d561d942..8e509808 100644 --- a/src/sugar/presence/presenceservice.py +++ b/src/sugar/presence/presenceservice.py @@ -27,15 +27,21 @@ import gobject import dbus import dbus.exceptions import dbus.glib +from dbus import PROPERTIES_IFACE from sugar.presence.buddy import Buddy, Owner from sugar.presence.activity import Activity from sugar.presence.util import get_connection_manager +from telepathy.interfaces import ACCOUNT, \ + ACCOUNT_MANAGER, \ + CONNECTION from telepathy.constants import HANDLE_TYPE_CONTACT _logger = logging.getLogger('sugar.presence.presenceservice') +ACCOUNT_MANAGER_SERVICE = 'org.freedesktop.Telepathy.AccountManager' +ACCOUNT_MANAGER_PATH = '/org/freedesktop/Telepathy/AccountManager' class PresenceService(gobject.GObject): """UI-side interface to the dbus presence service @@ -352,7 +358,9 @@ class PresenceService(gobject.GObject): if connection_path == tp_conn_path: connection_name = connection_path.replace('/', '.')[1:] connection = bus.get_object(connection_name, connection_path) - contact_ids = connection.InspectHandles(HANDLE_TYPE_CONTACT, [handle]) + contact_ids = connection.InspectHandles(HANDLE_TYPE_CONTACT, + [handle], + dbus_interface=CONNECTION) return self.get_buddy(account_path, contact_ids[0]) raise ValueError('Unknown buddy in connection %s with handle %d', tp_conn_path, handle) @@ -392,8 +400,9 @@ class PresenceService(gobject.GObject): if self._activity_cache is not None: raise ValueError('Activity %s is already tracked', activity.get_id()) - connection = get_connection_manager().get_preferred_connection() - shared_activity = Activity(connection, properties=properties) + connection_manager = get_connection_manager() + account_path, connection = connection_manager.get_preferred_connection() + shared_activity = Activity(account_path, connection, properties=properties) self._activity_cache = shared_activity """ @@ -411,7 +420,8 @@ class PresenceService(gobject.GObject): returns the bus name and the object path of the Telepathy connection """ - connection = get_connection_manager().get_preferred_connection() + connection_manager = get_connection_manager() + account_path, connection = connection_manager.get_preferred_connection() if connection is None: return None else: diff --git a/src/sugar/presence/util.py b/src/sugar/presence/util.py index 265e3902..f00228f3 100644 --- a/src/sugar/presence/util.py +++ b/src/sugar/presence/util.py @@ -10,7 +10,7 @@ ACCOUNT_MANAGER_PATH = '/org/freedesktop/Telepathy/AccountManager' class ConnectionManager(object): def __init__(self): - self.connections_per_account = [] + self._connections_per_account = {} bus = dbus.SessionBus() obj = bus.get_object(ACCOUNT_MANAGER_SERVICE, ACCOUNT_MANAGER_PATH) @@ -32,11 +32,11 @@ class ConnectionManager(object): connection_name = connection_path.replace('/', '.')[1:] connection = bus.get_object(connection_name, connection_path) - self.connections[account_path] = connection + self._connections_per_account[account_path] = connection def get_preferred_connection(self): best_connection = None, None - for account_path, connection in self.connections.items(): + for account_path, connection in self._connections_per_account.items(): if 'salut' in connection.object_path: best_connection = account_path, connection elif 'gabble' in connection.object_path: @@ -44,6 +44,14 @@ class ConnectionManager(object): break return best_connection + def get_connection(self, account_path): + return self._connections_per_account[account_path] + + def get_connections(self): + return self._connections_per_account.values() + + connections = property(get_connections) + _connection_manager = None def get_connection_manager():