Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2007-06-11 16:42:00 (GMT)
committer Simon McVittie <simon.mcvittie@collabora.co.uk>2007-06-11 16:42:00 (GMT)
commit006df6ff75871a42b06f442833f0726704f74f33 (patch)
tree332a7e4b4b87825afac1d0cb8507f8df58df8fca
parent1fef4c904eb76566922c285de05a965dcf5d9d6c (diff)
Make Buddy responsible for initial property lookup when a Tp handle is added
-rw-r--r--src/buddy.py58
-rw-r--r--src/presenceservice.py9
-rw-r--r--src/server_plugin.py96
3 files changed, 79 insertions, 84 deletions
diff --git a/src/buddy.py b/src/buddy.py
index 5c0a877..96698c8 100644
--- a/src/buddy.py
+++ b/src/buddy.py
@@ -295,6 +295,64 @@ class Buddy(ExportedGObject):
self._handles[tp_client] = (handle, uid)
self.TelepathyHandleAdded(conn.service_name, conn.object_path, handle)
+ # FIXME: we should probably have a class SomeoneElse(Buddy) for
+ # everyone who's not the owner
+ if not self._owner:
+ self._discover_properties(tp_client, handle, uid)
+
+ def _discover_properties(self, tp_client, handle, uid):
+ conn = tp_client.get_connection()
+
+ accumulator = {}
+
+ def got_aliases(aliases):
+ try:
+ _logger.debug('Buddy %s nick set to %s', self._object_id,
+ aliases[0])
+ accumulator.update({'nick': aliases[0]})
+ finally:
+ self.set_properties(accumulator)
+ def aliases_error(e):
+ try:
+ _logger.warning('Error getting buddy properties for %s: '
+ '%s', uid, e)
+ finally:
+ self.set_properties(accumulator)
+
+ def get_alias():
+ accumulator.setdefault('nick', uid)
+ if CONN_INTERFACE_ALIASING in conn:
+ conn[CONN_INTERFACE_ALIASING].RequestAliases([handle],
+ reply_handler=got_aliases,
+ error_handler=aliases_error)
+ else:
+ self.set_properties(accumulator)
+
+ def got_properties(props):
+ try:
+ _logger.debug('Buddy %s properties are %r', self._object_id,
+ props)
+ accumulator.update(props)
+ finally:
+ get_alias()
+ def properties_error(e):
+ try:
+ _logger.warning('Error getting buddy properties for %s: '
+ '%s', uid, e)
+ finally:
+ get_alias()
+
+ # Kick off the first request, which is for the properties.
+ # Chain from there to the aliases request; chain from *there* to
+ # setting the accumulated properties.
+ accumulator['color'] = 'white'
+ if CONN_INTERFACE_BUDDY_INFO in conn:
+ conn[CONN_INTERFACE_BUDDY_INFO].GetProperties(handle,
+ byte_arrays=True, reply_handler=got_properties,
+ error_handler=properties_error)
+ else:
+ get_alias()
+
@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.
diff --git a/src/presenceservice.py b/src/presenceservice.py
index e5505a5..22e76c3 100644
--- a/src/presenceservice.py
+++ b/src/presenceservice.py
@@ -211,19 +211,20 @@ class PresenceService(ExportedGObject):
self._buddies[objid] = buddy
return buddy
- def _contact_online(self, tp, objid, handle, identifier, props):
+ def _contact_online(self, tp, objid, handle, identifier):
_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, identifier)
- buddy.set_properties(props)
- # kick off a request for their current activities
- # FIXME: move this to the Buddy?
conn = tp.get_connection()
+ # Kick off a request for their current activities. This isn't done
+ # internally by the Buddy itself, because when we get the activities
+ # back, we actually want to feed them to the Activity objects.
+
def got_activities(activities):
self._buddy_activities_changed(tp, handle, activities)
conn[CONN_INTERFACE_BUDDY_INFO].GetActivities(handle,
diff --git a/src/server_plugin.py b/src/server_plugin.py
index 3efd696..b1060b2 100644
--- a/src/server_plugin.py
+++ b/src/server_plugin.py
@@ -20,6 +20,7 @@
import logging
import os
import sys
+from itertools import izip
from string import hexdigits
# Other libraries
@@ -452,87 +453,15 @@ class ServerPlugin(gobject.GObject):
self.emit("contact-offline", handle)
del self._online_contacts[handle]
- def _contact_online_aliases_cb(self, handle, props, aliases):
- """Handle contact's alias being received (do further queries)"""
- if not self._conn or not aliases or not len(aliases):
- _logger.debug("Handle %s - No aliases", handle)
- self._contact_offline(handle)
- return
-
- props['nick'] = aliases[0]
-
- jid = self._conn[CONN_INTERFACE].InspectHandles(HANDLE_TYPE_CONTACT,
- [handle])[0]
- self._online_contacts[handle] = jid
- objid = self.identify_contacts(None, [handle])[handle]
-
- 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"""
- if retry:
- _logger.debug("Handle %s - Error getting nickname (will retry):"
- "%s", handle, err)
- self._conn[CONN_INTERFACE_ALIASING].RequestAliases([handle],
- reply_handler=lambda *args: self._contact_online_aliases_cb(
- handle, props, *args),
- error_handler=lambda e: self._contact_online_aliases_error_cb(
- handle, props, False, e))
- else:
- _logger.debug("Handle %s - Error getting nickname: %s",
- handle, err)
- self._contact_offline(handle)
-
- def _contact_online_properties_cb(self, handle, props):
- """Handle failure to retrieve given user's alias/information"""
- if not props.has_key('key'):
- _logger.debug("Handle %s - invalid key.", handle)
- self._contact_offline(handle)
- return
- if not props.has_key('color'):
- _logger.debug("Handle %s - invalid color.", handle)
- self._contact_offline(handle)
- return
-
- self._conn[CONN_INTERFACE_ALIASING].RequestAliases([handle],
- reply_handler=lambda *args: self._contact_online_aliases_cb(
- handle, props, *args),
- error_handler=lambda e: self._contact_online_aliases_error_cb(
- handle, props, True, e))
-
- def _contact_online_request_properties(self, handle, tries):
- self._conn[CONN_INTERFACE_BUDDY_INFO].GetProperties(handle,
- byte_arrays=True,
- reply_handler=lambda *args: self._contact_online_properties_cb(
- handle, *args),
- error_handler=lambda e: self._contact_online_properties_error_cb(
- handle, tries, e))
- return False
-
- def _contact_online_properties_error_cb(self, handle, tries, err):
- """Handle error retrieving property-set for a user (handle)"""
- if tries <= 3:
- _logger.debug("Handle %s - Error getting properties (will retry):"
- " %s", handle, err)
- tries += 1
- gobject.timeout_add(1000, self._contact_online_request_properties,
- handle, tries)
- else:
- _logger.debug("Handle %s - Error getting properties: %s",
- handle, err)
- self._contact_offline(handle)
-
def _contacts_online(self, handles):
"""Handle contacts coming online"""
relevant = []
for handle in handles:
if handle == self.self_handle:
- jid = self._conn[CONN_INTERFACE].InspectHandles(
- HANDLE_TYPE_CONTACT, [handle])[0]
- self._online_contacts[handle] = jid
# ignore network events for Owner property changes since those
# are handled locally
+ pass
elif (handle in self._subscribe_members or
handle in self._subscribe_local_pending or
handle in self._subscribe_remote_pending):
@@ -540,9 +469,14 @@ class ServerPlugin(gobject.GObject):
# else it's probably a channel-specific handle - can't create a
# Buddy object for those yet
- for handle in relevant:
- self._online_contacts[handle] = None
- self._contact_online_request_properties(handle, 1)
+ jids = self._conn[CONN_INTERFACE].InspectHandles(
+ HANDLE_TYPE_CONTACT, relevant)
+
+ objids = self.identify_contacts(None, relevant, jids)
+
+ for handle, jid, objid in izip(relevant, jids, objids):
+ self._online_contacts[handle] = jid
+ self.emit('contact-online', objid, handle, jid)
def _subscribe_members_changed_cb(self, message, added, removed,
local_pending, remote_pending,
@@ -689,7 +623,7 @@ class ServerPlugin(gobject.GObject):
"""
return (hostname == 'olpc.collabora.co.uk')
- def identify_contacts(self, tp_chan, handles):
+ def identify_contacts(self, tp_chan, handles, identifiers=None):
"""Work out the "best" unique identifier we can for the given handles,
in the context of the given channel (which may be None), using only
'fast' connection manager API (that does not involve network
@@ -732,6 +666,7 @@ class ServerPlugin(gobject.GObject):
group = tp_chan[CHANNEL_INTERFACE_GROUP]
if (group.GetGroupFlags() &
CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES):
+ identifiers = None
owners = group.GetHandleOwners(handles)
for i, owner in enumerate(owners):
if owner == 0:
@@ -739,11 +674,12 @@ class ServerPlugin(gobject.GObject):
else:
group = None
- jids = self._conn[CONN_INTERFACE].InspectHandles(HANDLE_TYPE_CONTACT,
- owners)
+ if identifiers is None:
+ identifiers = self._conn[CONN_INTERFACE].InspectHandles(
+ HANDLE_TYPE_CONTACT, identifiers)
ret = {}
- for handle, jid in zip(handles, jids):
+ for handle, jid in izip(handles, identifiers):
# special-case the Owner - we always know who we are
if (handle == self.self_handle or
(group is not None and handle == group.GetSelfHandle())):