[sugar] [PATCH] services/presence/: move more of the handle tracking into the Buddy object

Simon McVittie simon.mcvittie
Mon May 21 07:24:11 EDT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- ---
 services/presence/buddy.py           |   25 +++++++++++++++-
 services/presence/presenceservice.py |   55 ++++++++++++++++++++++++++++-----
 2 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/services/presence/buddy.py b/services/presence/buddy.py
index ab397ef..eb072a1 100644
- --- a/services/presence/buddy.py
+++ b/services/presence/buddy.py
@@ -80,7 +80,9 @@ class Buddy(ExportedGObject):
         'property-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
                             ([gobject.TYPE_PYOBJECT])),
         'icon-changed':     (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- -                            ([gobject.TYPE_PYOBJECT]))
+                            ([gobject.TYPE_PYOBJECT])),
+        'disappeared':      (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+                            ([])),
     }
 
     __gproperties__ = {
@@ -236,6 +238,12 @@ class Buddy(ExportedGObject):
             full set of properties, just the changes.
         """
 
+    def add_telepathy_handle(self, tp_client, handle):
+        """Add a Telepathy handle."""
+        conn = tp_client.get_connection()
+        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):
         """Another Telepathy handle has become associated with the buddy.
@@ -250,6 +258,21 @@ class Buddy(ExportedGObject):
             newly associated with the buddy
         """
 
+    def remove_telepathy_handle(self, tp_client, handle):
+        """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)
+            if not self.handles:
+                self.emit('disappeared')
+        else:
+            _logger.debug('Telepathy handle %u supposedly removed, but '
+                          'my handle on that connection is %u - ignoring',
+                          handle, my_handle)
+
     @dbus.service.signal(_BUDDY_INTERFACE, signature='sou')
     def TelepathyHandleRemoved(self, tp_conn_name, tp_conn_path, handle):
         """A Telepathy handle has ceased to be associated with the buddy,
diff --git a/services/presence/presenceservice.py b/services/presence/presenceservice.py
index c554ce6..4bd4da8 100644
- --- a/services/presence/presenceservice.py
+++ b/services/presence/presenceservice.py
@@ -126,12 +126,12 @@ class PresenceService(ExportedGObject):
             objid = self._get_next_object_id()
             buddy = Buddy(self._bus_name, objid, key=key)
             buddy.connect("validity-changed", self._buddy_validity_changed_cb)
+            buddy.connect("disappeared", self._buddy_disappeared_cb)
             self._buddies[key] = buddy
 
- -        buddies = self._handles_buddies[tp]
- -        buddies[handle] = buddy
+        self._handles_buddies[tp][handle] = buddy
         # store the handle of the buddy for this CM
- -        buddy.handles[tp] = handle
+        buddy.add_telepathy_handle(tp, handle)
 
         buddy.set_properties(props)
 
@@ -143,6 +143,12 @@ class PresenceService(ExportedGObject):
             self.BuddyDisappeared(buddy.object_path())
             _logger.debug("Buddy left: %s (%s)" % (buddy.props.nick, buddy.props.color))
 
+    def _buddy_disappeared_cb(self, buddy):
+        if buddy.props.valid:
+            self.BuddyDisappeared(buddy.object_path())
+            _logger.debug('Buddy left: %s (%s)' % (buddy.props.nick, buddy.props.color))
+        self._buddies.pop(buddy.props.key)
+
     def _contact_offline(self, tp, handle):
         if not self._handles_buddies[tp].has_key(handle):
             return
@@ -151,12 +157,7 @@ class PresenceService(ExportedGObject):
         key = buddy.props.key
 
         # the handle of the buddy for this CM is not valid anymore
- -        buddy.handles.pop(tp)
- -        if not buddy.handles:
- -            if buddy.props.valid:
- -                self.BuddyDisappeared(buddy.object_path())
- -                _logger.debug("Buddy left: %s (%s)" % (buddy.props.nick, buddy.props.color))
- -            self._buddies.pop(key)
+        buddy.remove_telepathy_handle(tp, handle)
 
     def _get_next_object_id(self):
         """Increment and return the object ID counter."""
@@ -304,6 +305,42 @@ class PresenceService(ExportedGObject):
                 return buddy.object_path()
         raise NotFoundError("The buddy was not found.")
 
+    @dbus.service.method(_PRESENCE_INTERFACE, in_signature='sou',
+                         out_signature='o')
+    def GetBuddyByTelepathyHandle(self, tp_conn_name, tp_conn_path, handle):
+        """Get the buddy corresponding to a Telepathy handle.
+
+        :Parameters:
+            `tp_conn_name` : str
+                The well-known bus name of a Telepathy connection
+            `tp_conn_path` : dbus.ObjectPath
+                The object path of the Telepathy connection
+            `handle` : int or long
+                The handle of a Telepathy contact on that connection,
+                of type HANDLE_TYPE_CONTACT. This may not be a
+                channel-specific handle.
+        :Returns: the object path of a Buddy
+        :Raises NotFoundError: if the buddy is not found.
+        """
+        for tp, handles in self._handles_buddies.iteritems():
+            conn = tp.get_connection()
+            if conn is None:
+                continue
+            if (conn.service_name == tp_conn_name
+                and conn.object_path == tp_conn_path):
+                buddy = handles.get(handle)
+                if buddy is not None and buddy.props.valid:
+                        return buddy.object_path()
+                # either the handle is invalid, or we don't have a Buddy
+                # object for that buddy because we don't have all their
+                # details yet
+                raise NotFoundError("The buddy %u was not found on the "
+                                    "connection to %s:%s"
+                                    % (handle, tp_conn_name, tp_conn_path))
+        raise NotFoundError("The buddy %u was not found: we have no "
+                            "connection to %s:%s" % (handle, tp_conn_name,
+                                                     tp_conn_path))
+
     @dbus.service.method(_PRESENCE_INTERFACE, out_signature="o")
     def GetOwner(self):
         if not self._owner:
- -- 
1.5.2-rc3.GIT

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: OpenPGP key: http://www.pseudorandom.co.uk/2003/contact/ or pgp.net

iD8DBQFGUYFbWSc8zVUw7HYRAt/HAJwO9KlFyOVh8L3i5t+qmsr19Ag+/gCgjcyv
E5WdXpj+JeTnlFnCj1wm11o=
=idu8
-----END PGP SIGNATURE-----



More information about the Sugar-devel mailing list