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

Dan Williams dcbw at redhat.com
Tue May 22 12:42:13 EDT 2007


On Mon, 2007-05-21 at 12:24 +0100, Simon McVittie wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1

The reason there were symmetrical BuddyAppeared/BuddyDisappeared signals
on the PS object itself was so that clients could attach to _one_ signal
on the PS to detect buddy disappearance, rather than connecting a signal
to each buddy him/herself.  This would suck for the mesh view, for
example, which has to know when every buddy seen comes and goes.  So I'd
like to keep the two signals on the PS itself, but I'm not against a
"disappeared' signal on the Buddy object as long as the
BuddyDisappeared/BuddyLeft signals also go out on the PS object and each
Activity to which the buddy was participating.  The PS is already a kind
of a la carte thing, where you can find out the information from
multiple sources as befits your activity.

Sound ok?

Dan

> - ---
>  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-----
> _______________________________________________
> Sugar mailing list
> Sugar at laptop.org
> http://mailman.laptop.org/mailman/listinfo/sugar



More information about the Sugar mailing list