From 1fef4c904eb76566922c285de05a965dcf5d9d6c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 11 Jun 2007 15:28:29 +0000 Subject: Move avatar handling to Buddy (with a small dispatch function in PresenceService) --- diff --git a/src/buddy.py b/src/buddy.py index 6199342..5c0a877 100644 --- a/src/buddy.py +++ b/src/buddy.py @@ -543,6 +543,34 @@ class Buddy(ExportedGObject): except AttributeError: self._valid = False + def update_avatar(self, tp, new_avatar_token): + """Handle update of the avatar""" + conn = tp.get_connection() + handle, identifier = self._handles[tp] + + icon = buddy_icon_cache.get_icon(conn.object_path, identifier, + new_avatar_token) + if not icon: + # cache miss + def got_avatar(avatar, mime_type): + icon = str(icon) + buddy_icon_cache.store_icon(conn.object_path, identifier, + new_avatar_token, icon) + if self._icon != icon: + self._icon = icon + self.IconChanged(self._icon) + + conn[CONN_INTERFACE_AVATARS].RequestAvatar(handle, + reply_handler=got_avatar, + error_handler=lambda e: + _logger.warning('Error getting avatar for %r: %s', + self, e), + byte_arrays=True) + else: + if self._icon != icon: + self._icon = icon + self.IconChanged(self._icon) + class GenericOwner(Buddy): """Common functionality for Local User-like objects @@ -745,6 +773,11 @@ class GenericOwner(Buddy): """Customisation point: handle the registration of the owner""" raise RuntimeError("Subclasses must implement") + def update_avatar(self, tp, new_avatar_token): + # This should never get called because Owner avatar changes are + # driven by the Sugar shell, but just in case: + _logger.warning('GenericOwner.update_avatar() should not be called') + class ShellOwner(GenericOwner): """Representation of the local-machine owner using Sugar's Shell diff --git a/src/presenceservice.py b/src/presenceservice.py index 2a1e795..e5505a5 100644 --- a/src/presenceservice.py +++ b/src/presenceservice.py @@ -25,7 +25,8 @@ from dbus.exceptions import DBusException from dbus.gobject_service import ExportedGObject from dbus.mainloop.glib import DBusGMainLoop from telepathy.client import ManagerRegistry, Connection -from telepathy.interfaces import (CONN_MGR_INTERFACE, CONN_INTERFACE) +from telepathy.interfaces import (CONN_MGR_INTERFACE, CONN_INTERFACE, + CONN_INTERFACE_AVATARS) from telepathy.constants import (CONNECTION_STATUS_CONNECTING, CONNECTION_STATUS_CONNECTED, CONNECTION_STATUS_DISCONNECTED) @@ -112,7 +113,6 @@ class PresenceService(ExportedGObject): 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.connect('avatar-updated', self._avatar_updated) self._server_plugin.connect('buddy-properties-changed', self._buddy_properties_changed) self._server_plugin.connect('activity-invitation', @@ -178,6 +178,12 @@ class PresenceService(ExportedGObject): 'ActivitiesChanged', buddy_activities_changed) self._conn_matches[conn].append(m) + def avatar_updated(contact, avatar_token): + self._avatar_updated(tp, contact, avatar_token) + m = conn[CONN_INTERFACE_AVATARS].connect_to_signal('AvatarUpdated', + avatar_updated) + self._conn_matches[conn].append(m) + def _tp_disconnected(self, tp): if tp.self_handle is not None: self._handles_buddies.setdefault(tp, {}).pop( @@ -254,11 +260,11 @@ class PresenceService(ExportedGObject): self._next_object_id = self._next_object_id + 1 return self._next_object_id - def _avatar_updated(self, tp, handle, avatar): + def _avatar_updated(self, tp, handle, new_avatar_token): buddy = self._handles_buddies[tp].get(handle) - if buddy and not buddy.props.owner: + if buddy is not None and buddy is not self._owner: _logger.debug("Buddy %s icon updated" % buddy.props.nick) - buddy.props.icon = avatar + buddy.update_avatar(tp, new_avatar_token) def _buddy_properties_changed(self, tp, handle, properties): buddy = self._handles_buddies[tp].get(handle) diff --git a/src/server_plugin.py b/src/server_plugin.py index f5cd202..3efd696 100644 --- a/src/server_plugin.py +++ b/src/server_plugin.py @@ -44,7 +44,6 @@ from sugar import util # Presence Service local modules import psutils -from buddyiconcache import buddy_icon_cache CONN_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo' @@ -84,12 +83,6 @@ class ServerPlugin(gobject.GObject): # Connection status changed. # args: status, reason as for Telepathy StatusChanged (gobject.SIGNAL_RUN_FIRST, None, [int, int]), - 'avatar-updated': - # Contact's avatar has changed - # args: - # contact handle: int - # icon data: str - (gobject.SIGNAL_RUN_FIRST, None, [object, object]), 'buddy-properties-changed': # OLPC buddy properties changed; as for PropertiesChanged # args: @@ -342,9 +335,6 @@ class ServerPlugin(gobject.GObject): self._buddy_current_activity_changed_cb) self._matches.append(m) - self._conn[CONN_INTERFACE_AVATARS].connect_to_signal('AvatarUpdated', - self._avatar_updated_cb) - self._matches.append(m) self._conn[CONN_INTERFACE_ALIASING].connect_to_signal('AliasesChanged', self._alias_changed_cb) self._matches.append(m) @@ -618,44 +608,6 @@ class ServerPlugin(gobject.GObject): for handle in now_offline: self._contact_offline(handle) - def _request_avatar_cb(self, handle, new_avatar_token, avatar, mime_type): - jid = self._online_contacts[handle] - if not jid: - logging.debug("Handle %s not valid yet..." % handle) - return - icon = ''.join(map(chr, avatar)) - buddy_icon_cache.store_icon(self._conn.object_path, jid, - new_avatar_token, icon) - self.emit("avatar-updated", handle, icon) - - def _avatar_updated_cb(self, handle, new_avatar_token): - """Handle update of given user (handle)'s avatar""" - if handle == self._conn[CONN_INTERFACE].GetSelfHandle(): - # ignore network events for Owner property changes since those - # are handled locally - return - - if not self._online_contacts.has_key(handle): - _logger.debug("Handle %s unknown.", handle) - return - - jid = self._online_contacts[handle] - if not jid: - _logger.debug("Handle %s not valid yet...", handle) - return - - icon = buddy_icon_cache.get_icon(self._conn.object_path, jid, - new_avatar_token) - if not icon: - # cache miss - self._conn[CONN_INTERFACE_AVATARS].RequestAvatar(handle, - reply_handler=lambda *args: self._request_avatar_cb(handle, - new_avatar_token, *args), - error_handler=lambda e: - _logger.warning('Error getting avatar: %s', e)) - else: - self.emit("avatar-updated", handle, icon) - def _alias_changed_cb(self, aliases): """Handle update of aliases for all users""" for handle, alias in aliases: @@ -703,7 +655,7 @@ class ServerPlugin(gobject.GObject): if local_pending: self.emit('activity-invitation', handle) def got_all_members_err(e): - logger.debug('Unable to get channel members for %s:', + _logger.debug('Unable to get channel members for %s:', object_path, exc_info=1) group = channel[CHANNEL_INTERFACE_GROUP] -- cgit v0.9.1