From fb106d40de0c49e1ec33347e15b290d29cce5ba5 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 11 Jun 2007 15:11:20 +0000 Subject: Have Buddy track their own Telepathy handles and JIDs --- diff --git a/src/buddy.py b/src/buddy.py index 766fdfb..6199342 100644 --- a/src/buddy.py +++ b/src/buddy.py @@ -112,8 +112,8 @@ class Buddy(ExportedGObject): _activities -- dictionary mapping activity ID to activity.Activity objects - handles -- dictionary mapping Telepathy client plugin to - contact handle (an integer representing the JID or unique ID); + _handles -- dictionary mapping Telepathy client plugin to + tuples (contact handle, corresponding unique ID); channel-specific handles do not appear here """ @@ -169,7 +169,8 @@ class Buddy(ExportedGObject): #: activity ID -> activity self._activities = {} self._activity_sigids = {} - self.handles = {} # tp client -> handle + #: Telepathy plugin -> (handle, identifier e.g. JID) + self._handles = {} self._valid = False self._owner = False @@ -288,11 +289,11 @@ class Buddy(ExportedGObject): full set of properties, just the changes. """ - def add_telepathy_handle(self, tp_client, handle): + def add_telepathy_handle(self, tp_client, handle, uid): """Add a Telepathy handle.""" conn = tp_client.get_connection() + self._handles[tp_client] = (handle, uid) self.TelepathyHandleAdded(conn.service_name, conn.object_path, handle) - self.handles[tp_client] = handle @dbus.service.signal(_BUDDY_INTERFACE, signature='sou') def TelepathyHandleAdded(self, tp_conn_name, tp_conn_path, handle): @@ -308,21 +309,19 @@ class Buddy(ExportedGObject): newly associated with the buddy """ - def remove_telepathy_handle(self, tp_client, handle): + def remove_telepathy_handle(self, tp_client): """Remove a Telepathy handle.""" conn = tp_client.get_connection() - my_handle = self.handles.get(tp_client, 0) - if my_handle == handle: - del self.handles[tp_client] - self.TelepathyHandleRemoved(conn.service_name, conn.object_path, - handle) - # the Owner can't disappear - that would be silly - if not self.handles and not self._owner: - self.emit('disappeared') - else: - _logger.debug('Telepathy handle %u supposedly removed, but ' - 'my handle on that connection is %u - ignoring', - handle, my_handle) + try: + handle, identifier = self._handles.pop(tp_client) + except KeyError: + return + + self.TelepathyHandleRemoved(conn.service_name, conn.object_path, + handle) + # the Owner can't disappear - that would be silly + if not self._handles and not self._owner: + self.emit('disappeared') @dbus.service.signal(_BUDDY_INTERFACE, signature='sou') def TelepathyHandleRemoved(self, tp_conn_name, tp_conn_path, handle): @@ -401,10 +400,10 @@ class Buddy(ExportedGObject): object path, handle). """ ret = [] - for plugin in self.handles: + for plugin in self._handles: conn = plugin.get_connection() ret.append((str(conn.service_name), conn.object_path, - self.handles[plugin])) + self._handles[plugin][0])) # methods def object_path(self): @@ -633,7 +632,7 @@ class GenericOwner(Buddy): _logger.warning("setting current activity failed: %s", e)) def _set_self_alias(self, tp): - self_handle = self.handles[tp] + self_handle = self._handles[tp][0] conn = tp.get_connection() conn[CONN_INTERFACE_ALIASING].SetAliases({self_handle: self._nick}, reply_handler=_noop, @@ -654,8 +653,8 @@ class GenericOwner(Buddy): # Hack so we can use this as a timeout handler return False - def add_telepathy_handle(self, tp_client, handle): - Buddy.add_telepathy_handle(self, tp_client, handle) + def add_telepathy_handle(self, tp_client, handle, uid): + Buddy.add_telepathy_handle(self, tp_client, handle, uid) self._set_self_olpc_properties(tp_client) self._set_self_alias(tp_client) @@ -671,7 +670,7 @@ class GenericOwner(Buddy): # As well as emitting the D-Bus signal, prod the Telepathy # connection manager Buddy.IconChanged(self, icon_data) - for tp in self.handles.iterkeys(): + for tp in self._handles.iterkeys(): self._set_self_avatar(tp) def _set_self_avatar(self, tp): @@ -682,7 +681,7 @@ class GenericOwner(Buddy): m.update(icon_data) digest = m.hexdigest() - self_handle = self.handles[tp] + self_handle = self._handles[tp][0] token = conn[CONN_INTERFACE_AVATARS].GetAvatarTokens( [self_handle])[0] @@ -708,7 +707,7 @@ class GenericOwner(Buddy): _logger.warning('Error setting avatar: %s', e)) def _property_changed(self, changed_props): - for tp in self.handles.iterkeys(): + for tp in self._handles.iterkeys(): if changed_props.has_key("current-activity"): self._set_self_current_activity(tp) diff --git a/src/presenceservice.py b/src/presenceservice.py index 5a57a3c..2a1e795 100644 --- a/src/presenceservice.py +++ b/src/presenceservice.py @@ -158,7 +158,8 @@ class PresenceService(ExportedGObject): def _tp_connected(self, tp): self._handles_buddies[tp][tp.self_handle] = self._owner - self._owner.add_telepathy_handle(tp, tp.self_handle) + self._owner.add_telepathy_handle(tp, tp.self_handle, + tp.self_identifier) conn = tp.get_connection() @@ -181,7 +182,7 @@ class PresenceService(ExportedGObject): if tp.self_handle is not None: self._handles_buddies.setdefault(tp, {}).pop( tp.self_handle, None) - self._owner.remove_telepathy_handle(tp, tp.self_handle) + self._owner.remove_telepathy_handle(tp) conn = tp.get_connection() @@ -204,13 +205,13 @@ class PresenceService(ExportedGObject): self._buddies[objid] = buddy return buddy - def _contact_online(self, tp, objid, handle, props): + def _contact_online(self, tp, objid, handle, identifier, props): _logger.debug('Handle %u, .../%s is now online', handle, objid) buddy = self.get_buddy(objid) self._handles_buddies[tp][handle] = buddy # store the handle of the buddy for this CM - buddy.add_telepathy_handle(tp, handle) + buddy.add_telepathy_handle(tp, handle, identifier) buddy.set_properties(props) # kick off a request for their current activities @@ -241,14 +242,12 @@ class PresenceService(ExportedGObject): self._buddy_validity_changed_cb(buddy, False) def _contact_offline(self, tp, handle): - if not self._handles_buddies[tp].has_key(handle): - return - - buddy = self._handles_buddies[tp].pop(handle) + buddy = self._handles_buddies[tp].pop(handle, None) # the handle of the buddy for this CM is not valid anymore # (this might trigger _buddy_disappeared_cb if they are not visible # via any CM) - buddy.remove_telepathy_handle(tp, handle) + if buddy is not None: + buddy.remove_telepathy_handle(tp) def _get_next_object_id(self): """Increment and return the object ID counter.""" diff --git a/src/server_plugin.py b/src/server_plugin.py index e48df8d..f5cd202 100644 --- a/src/server_plugin.py +++ b/src/server_plugin.py @@ -73,8 +73,9 @@ class ServerPlugin(gobject.GObject): # args: # contact identification (based on key ID or JID): str # contact handle: int or long + # contact identifier (JID): str or unicode # dict {name: str => property: object} - (gobject.SIGNAL_RUN_FIRST, None, [str, object, object]), + (gobject.SIGNAL_RUN_FIRST, None, [str, object, object, object]), 'contact-offline': # Contact has gone offline. # args: contact handle @@ -131,6 +132,7 @@ class ServerPlugin(gobject.GObject): self._owner = owner self.self_handle = None + self.self_identifier = None self._account = self._get_account_info() self._conn_status = CONNECTION_STATUS_DISCONNECTED @@ -314,10 +316,14 @@ class ServerPlugin(gobject.GObject): if local_pending: # accept pending subscriptions + # FIXME: do this async publish[CHANNEL_INTERFACE_GROUP].AddMembers(local_pending, '') + # FIXME: do this async? self.self_handle = self._conn[CONN_INTERFACE].GetSelfHandle() - self._online_contacts[self.self_handle] = self._account['account'] + self.self_identifier = self._conn[CONN_INTERFACE].InspectHandles( + HANDLE_TYPE_CONTACT, self.self_handle)[0] + self._online_contacts[self.self_handle] = self.self_identifier # request subscriptions from people subscribed to us if we're not # subscribed to them @@ -470,7 +476,7 @@ class ServerPlugin(gobject.GObject): self._online_contacts[handle] = jid objid = self.identify_contacts(None, [handle])[handle] - self.emit("contact-online", objid, handle, props) + self.emit("contact-online", objid, handle, jid, props) def _contact_online_aliases_error_cb(self, handle, props, retry, err): """Handle failure to retrieve given user's alias/information""" -- cgit v0.9.1