From 67226e2b02973e8b942289da609d2116d69e98e7 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 11 Aug 2010 08:11:43 +0000 Subject: Remove connection handling now that the Shell takes care of it. Also Make sure we have all the info we need right after the service starts. * activity.py: Retrieve properties synchronously. Call AddActivity after sharing. * buddy.py: Stop calling SetActivities, SetAliases and SetProperties. * linklocal_plugin.py: Stop watching Avahi and creating new connections. * presenceservice.py: Connect to available connections synchronously, stop managing connections, make GetActivityById synchronous. * server_plugin.py: Stop creating new connections. * telepathy_plugin.py: Stop managing connections, get connection status synchronously. --- diff --git a/src/activity.py b/src/activity.py index 29ba1a5..b68e71a 100644 --- a/src/activity.py +++ b/src/activity.py @@ -34,6 +34,7 @@ from psutils import (NotFoundError, NotJoinedError, WrongConnectionError, CONN_INTERFACE_ACTIVITY_PROPERTIES = 'org.laptop.Telepathy.ActivityProperties' +CONN_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo' _ACTIVITY_PATH = "/org/laptop/Sugar/Presence/Activities/" _ACTIVITY_INTERFACE = "org.laptop.Sugar.Presence.Activity" @@ -221,9 +222,8 @@ class Activity(ExportedGObject): _logger.warning('Failed to get initial activity properties ' 'for %s: %s', self._id, e) - conn[CONN_INTERFACE_ACTIVITY_PROPERTIES].GetProperties(self._room, - reply_handler=self.set_properties, - error_handler=got_properties_err) + properties = conn[CONN_INTERFACE_ACTIVITY_PROPERTIES].GetProperties(self._room) + self.set_properties(properties) def __repr__(self): return '' % (self._object_id, @@ -958,6 +958,16 @@ class Activity(ExportedGObject): error_handler=lambda e: self._join_failed_cb(e, 'Activity._join_activity_create_channel_cb')) + conn[CONN_INTERFACE_BUDDY_INFO].AddActivity( + self._id, + self._room, + reply_handler=self.__added_activity_cb, + error_handler=lambda e: self._join_failed_cb(e, + 'BuddyInfo.AddActivity')) + + def __added_activity_cb(self): + _logger.debug('Activity.__added_activity_cb') + def _join_activity_got_handles_cb(self, handles): assert len(handles) == 1 @@ -1020,7 +1030,7 @@ class Activity(ExportedGObject): conn = self._tp.get_connection() conn[CONN_INTERFACE].RequestHandles(HANDLE_TYPE_ROOM, - [self._tp.suggest_room_for_activity(self._id)], + [self._id], reply_handler=self._join_activity_got_handles_cb, error_handler=lambda e: self._join_failed_cb(e, 'Activity.join RequestHandles')) diff --git a/src/buddy.py b/src/buddy.py index d81952e..f221a8f 100644 --- a/src/buddy.py +++ b/src/buddy.py @@ -713,18 +713,7 @@ class GenericOwner(Buddy): uses SetActivities on BuddyInfo channel """ - conn = tp.get_connection() - - if CONN_INTERFACE_BUDDY_INFO not in conn: - _logger.warning('%s does not support BuddyInfo - unable to ' - 'set activities' % conn.object_path) - return - - conn[CONN_INTERFACE_BUDDY_INFO].SetActivities( - self._activities_by_connection[tp].iteritems(), - reply_handler=_noop, - error_handler=lambda e: - _logger.warning("setting activities failed: %s", e)) + pass def _set_self_current_activity(self, tp): """Forward our current activity (or "") to network @@ -742,35 +731,9 @@ class GenericOwner(Buddy): cur_activity = "" cur_activity_handle = 0 - _logger.debug("Setting current activity to '%s' (handle %s)", - cur_activity, cur_activity_handle) - conn = tp.get_connection() - - if CONN_INTERFACE_BUDDY_INFO not in conn: - _logger.warning('%s does not support BuddyInfo - unable to ' - 'set current activity' % conn.object_path) - return - - self.PropertyChanged({_PROP_CURACT: self._current_activity or ''}) - conn[CONN_INTERFACE_BUDDY_INFO].SetCurrentActivity(cur_activity, - cur_activity_handle, - reply_handler=_noop, - error_handler=lambda e: - _logger.warning("setting current activity failed: %s", e)) - def _set_self_alias(self, tp): - self_handle = self._handles[tp][0] - conn = tp.get_connection() - - if CONN_INTERFACE_ALIASING not in conn: - _logger.warning('%s does not support aliasing - unable to ' - 'set my own alias' % conn.object_path) - return False + pass - conn[CONN_INTERFACE_ALIASING].SetAliases({self_handle: self._nick}, - reply_handler=_noop, - error_handler=lambda e: - _logger.warning('Error setting alias: %s', e)) # Hack so we can use this as a timeout handler return False @@ -793,36 +756,6 @@ class GenericOwner(Buddy): if tp._PROTOCOL == 'local-xmpp': del props['tags'] - if connected: - if CONN_INTERFACE_BUDDY_INFO not in conn: - _logger.warning('%s does not support BuddyInfo - unable to ' - 'set my own buddy properties' % - conn.object_path) - return False - - conn[CONN_INTERFACE_BUDDY_INFO].SetProperties(props, - reply_handler=_noop, - error_handler=lambda e: - _logger.warning('Error setting OLPC properties: %s', e)) - else: - # we don't yet know whether the connection supports setting buddy - # properties - # FIXME: remove this hack, and the import of dbus.proxies, when - # we have a newer tp-python that makes dbus_object public - try: - obj = conn.dbus_object - if not isinstance(obj, dbus.proxies.ProxyObject): - raise AttributeError - except AttributeError: - obj = conn._dbus_object - - obj.SetProperties(props, dbus_interface=CONN_INTERFACE_BUDDY_INFO, - reply_handler=lambda: - _logger.debug('Successfully preloaded buddy props'), - error_handler=lambda e: - _logger.debug('Failed to preload buddy properties, ' - 'will try again after Connect(): %s', e)) - # Hack so we can use this as a timeout handler return False @@ -852,58 +785,6 @@ class GenericOwner(Buddy): # issues in the avatar cache. Revisit this afterwards return - conn = tp.get_connection() - icon_data = self._icon - - if CONN_INTERFACE_AVATARS not in conn: - _logger.warning('%s does not support Avatars - unable to ' - 'set my own avatar on this connection' % - conn.object_path) - return - - m = new_md5() - m.update(icon_data) - digest = m.hexdigest() - - self_handle = self._handles[tp][0] - token = conn[CONN_INTERFACE_AVATARS].GetAvatarTokens( - [self_handle])[0] - - if buddy_icon_cache.check_avatar(conn.object_path, digest, - token): - # avatar is up to date - return - - def set_self_avatar_cb(token): - buddy_icon_cache.set_avatar(conn.object_path, digest, token) - - types, minw, minh, maxw, maxh, maxsize = \ - conn[CONN_INTERFACE_AVATARS].GetAvatarRequirements() - if not "image/jpeg" in types: - _logger.debug("server does not accept JPEG format avatars.") - return - - width = 96 - height = 96 - size = 8192 - if maxw > 0 and width > maxw: - width = maxw - if maxw > 0 and height > maxh: - height = maxh - if maxsize > 0 and size > maxsize: - size = maxsize - - if 1: - # FIXME: Avatars have been disabled for Trial-2 due to performance - # issues in the avatar cache. Revisit this afterwards - pass - else: - img_data = _get_buddy_icon_at_size(icon_data, width, height, size) - conn[CONN_INTERFACE_AVATARS].SetAvatar(img_data, "image/jpeg", - reply_handler=set_self_avatar_cb, - error_handler=lambda e: - _logger.warning('Error setting avatar: %s', e)) - def _property_changed(self, changed_props): for tp in self._handles.iterkeys(): diff --git a/src/linklocal_plugin.py b/src/linklocal_plugin.py index 051797e..c5c2387 100644 --- a/src/linklocal_plugin.py +++ b/src/linklocal_plugin.py @@ -53,66 +53,12 @@ class LinkLocalPlugin(TelepathyPlugin): def __init__(self, registry, owner): TelepathyPlugin.__init__(self, registry, owner) - self._have_avahi = False - self._watch = None - # Glib source ID indicating we have to wait before be allowed to try - # to connect - self._have_to_wait_id = 0 - self._find_avahi() - - def _find_avahi(self): - try: - sys_bus = SystemBus() - self._watch = sys_bus.watch_name_owner('org.freedesktop.Avahi', - self._avahi_owner_cb) - - except DBusException: - _logger.exception('Error connecting to Avahi') - - def _avahi_owner_cb(self, unique_name): - had_avahi = self._have_avahi - - if unique_name: - self._have_avahi = True - if not had_avahi: - if self._backoff_id > 0: - _logger.info('Avahi appeared on the system bus (%s) - ' - 'will start when retry time is reached') - else: - _logger.info('Avahi appeared on the system bus (%s) - ' - 'starting...', unique_name) - self.emit('want-to-connect') - else: - self._have_avahi = False - if had_avahi: - _logger.info('Avahi disappeared from the system bus - ' - 'stopping...') - self._stop() - def cleanup(self): TelepathyPlugin.cleanup(self) if self._watch is not None: self._watch.cancel() self._watch = None - def _could_connect(self): - return TelepathyPlugin._could_connect(self) and self._have_avahi and \ - self._have_to_wait_id == 0 - - def _get_account_info(self): - """Retrieve connection manager parameters for this account - """ - server = self._owner.get_server() - khash = psutils.pubkey_to_keyid(self._owner.props.key) - - return { - 'nickname': '%s' % self._owner.props.nick, - 'first-name': ' ', - 'last-name': '%s' % self._owner.props.nick, - 'jid': '%s@%s' % (khash, server), - 'published-name': '%s' % khash[:8], - } - def _find_existing_connection(self): """Try to find an existing Telepathy connection to this server @@ -203,29 +149,6 @@ class LinkLocalPlugin(TelepathyPlugin): return ret - - def _have_to_wait_cb(self): - if self._have_to_wait_id > 0: - gobject.source_remove(self._have_to_wait_id) - self._have_to_wait_id = 0 - - _logger.debug("Timeout elapsed. Salut can connect now") - self.emit('want-to-connect') - - def _ip4_address_changed_cb(self, ip4am, address, iface): - TelepathyPlugin._ip4_address_changed_cb(self, ip4am, address, iface) - - # FIXME: what about IPv6 ? - if iface == "msh0" and not address.startswith("169.254."): - # msh0 got a not link-local IP so we are connected to a school - # server. Let's disable Salut. See #6299 for details. - _logger.debug("Connected to a school server. Disable Salut") - self._stop() - - # Salut can't connect during the next 2 minutes - self._have_to_wait_id = gobject.timeout_add(120000, - self._have_to_wait_cb) - def _handle_is_channel_specific(self, handle): # Salut doesn't have channel specific handles return False diff --git a/src/presenceservice.py b/src/presenceservice.py index 84c3cc2..a92fe08 100644 --- a/src/presenceservice.py +++ b/src/presenceservice.py @@ -29,7 +29,8 @@ from telepathy.client import ManagerRegistry from telepathy.interfaces import (CONN_INTERFACE_AVATARS, CONN_INTERFACE_ALIASING) from telepathy.constants import (CONNECTION_STATUS_CONNECTED, - CONNECTION_STATUS_DISCONNECTED) + CONNECTION_STATUS_DISCONNECTED, + CONNECTION_STATUS_REASON_NONE_SPECIFIED) from sugar import util @@ -125,7 +126,11 @@ class PresenceService(ExportedGObject): tp.connect('private-invitation', self._private_invitation) tp.connect('want-to-connect', self._want_to_connect) - tp.start() + + connection = tp.get_connection() + if connection is not None: + status = connection.GetStatus() + self._tp_status_cb(tp, status, CONNECTION_STATUS_REASON_NONE_SPECIFIED) self._contacts_online_queue = [] @@ -148,21 +153,8 @@ class PresenceService(ExportedGObject): def _tp_status_cb(self, plugin, status, reason): if status == CONNECTION_STATUS_CONNECTED: self._tp_connected(plugin) - if (plugin == self._server_plugin and self._ll_plugin) or \ - (plugin == self._ll_plugin and self._server_plugin and \ - self._server_plugin.status == CONNECTION_STATUS_CONNECTED): - # For now, Gabble takes precedence over Salut to alleviate - # corner cases where laptops on mesh can't talk to ones on APs - _logger.debug("Gabble takes precedence, disconnect Salut") - self._ll_plugin.cleanup() else: self._tp_disconnected(plugin) - if plugin == self._server_plugin and self._ll_plugin and \ - status == CONNECTION_STATUS_DISCONNECTED: - # For now, Gabble takes precedence over Salut to alleviate - # corner cases where laptops on mesh can't talk to ones on APs - if self._ll_plugin.status == CONNECTION_STATUS_DISCONNECTED: - self._ll_plugin.start() def _tp_connected(self, tp): self._connected_plugins.add(tp) @@ -623,8 +615,25 @@ class PresenceService(ExportedGObject): out_signature="o") def GetActivityById(self, actid): act = self._activities_by_id.get(actid, None) - if not act or not act.props.valid: - raise NotFoundError("The activity was not found.") + if act is None or not act.props.valid: + tp = self._get_preferred_plugin() + + connection = tp.get_connection() + connection = connection[CONN_INTERFACE_ACTIVITY_PROPERTIES] + + room_handle = None + try: + room_handle = connection.GetActivity(actid) + except dbus.exceptions.DBusException, e: + if e.get_dbus_name() != 'org.freedesktop.Telepathy.Error.NotAvailable': + raise + + if room_handle is not None: + act = self._new_activity(actid, tp, room_handle) + + if not act or not act.props.valid: + raise NotFoundError("The activity was not found.") + return act.object_path() @dbus.service.method(PRESENCE_INTERFACE, in_signature='', diff --git a/src/server_plugin.py b/src/server_plugin.py index 625f608..f0538f3 100644 --- a/src/server_plugin.py +++ b/src/server_plugin.py @@ -60,46 +60,10 @@ class ServerPlugin(TelepathyPlugin): self._friends_channel = None - def _ip4_address_changed_cb(self, ip4am, address, iface): - TelepathyPlugin._ip4_address_changed_cb(self, ip4am, address, iface) - - if address: - _logger.debug("::: valid IP4 address, conn_status %s" % - self._conn_status) - # this is a no-op if starting would be inappropriate right now - if self._conn_status != CONNECTION_STATUS_CONNECTED: - self.emit('want-to-connect') - else: - _logger.debug("::: invalid IP4 address, will disconnect") - self._stop() - - def _get_account_info(self): - """Retrieve connection manager parameters for this account. - We first try to connect without the register flag. If the connection - fails because of an authentication error we'll try to register - the account. - """ - server = self._owner.get_server() - khash = psutils.pubkey_to_keyid(self._owner.props.key) - - return { - 'account': "%s@%s" % (khash, server), - 'fallback-conference-server': "conference.%s" % server, - 'password': self._owner.get_key_hash(), - 'register': False, - 'port': dbus.UInt32(5223), - 'old-ssl': True, - 'ignore-ssl-errors': True, - } - def suggest_room_for_activity(self, activity_id): """Suggest a room to use to share the given activity. """ - # We shouldn't have to do this, but Gabble sometimes finds the IRC - # transport and goes "that has chatrooms, that'll do nicely". Work - # around it til Gabble gets better at finding the MUC service. - return '%s@%s' % (activity_id, - self._account['fallback-conference-server']) + return activity_id def _find_existing_connection(self): """Try to find an existing Telepathy connection to this server @@ -112,8 +76,6 @@ class ServerPlugin(TelepathyPlugin): returns connection or None """ - our_name = self._account['account'] - # Search existing connections, if any, that we might be able to use connections = Connection.get_connections() for item in connections: @@ -121,18 +83,11 @@ class ServerPlugin(TelepathyPlugin): continue if item[CONN_INTERFACE].GetProtocol() != self._PROTOCOL: continue - if item[CONN_INTERFACE].GetStatus() == CONNECTION_STATUS_CONNECTED: - test_handle = item[CONN_INTERFACE].RequestHandles( - HANDLE_TYPE_CONTACT, [our_name])[0] - if item[CONN_INTERFACE].GetSelfHandle() != test_handle: - continue + if item[CONN_INTERFACE].GetStatus() != CONNECTION_STATUS_CONNECTED: + continue return item return None - def _could_connect(self): - return bool(self._ip4am.props.address and - TelepathyPlugin._could_connect(self)) - def _server_is_trusted(self, hostname): """Return True if the server with the given hostname is trusted to verify public-key ownership correctly, and only allows users to @@ -300,32 +255,6 @@ class ServerPlugin(TelepathyPlugin): self._subscribe_channel[CHANNEL_INTERFACE_GROUP].AddMembers( added, '') - def _handle_connection_status_change(self, status, reason): - """Override TelepathyPlugin implementation to manage connection errors - due to authentication problem. If the connection fails because of an - authentication error that's probably because the account isn't - registered yet on the server. So we try to register it. - If it fails because any other reason we unset the register flag so futur - connection attempts won't try to register until we got a new - authentication error. This should properly handle the "XO having to use - different jabber servers" use case.""" - if status == self._conn_status: - return - - if status == CONNECTION_STATUS_DISCONNECTED: - if reason == CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED and \ - not self._account['register']: - _logger.debug( - 'Authentication failed. Trying to register the account') - self._account['register'] = True - self._stop() - self._init_connection() - return - else: - self._account['register'] = False - - TelepathyPlugin._handle_connection_status_change(self, status, reason) - def _publish_channel_cb(self, channel): TelepathyPlugin._publish_channel_cb(self, channel) diff --git a/src/telepathy_plugin.py b/src/telepathy_plugin.py index 5aca07e..37dccb1 100644 --- a/src/telepathy_plugin.py +++ b/src/telepathy_plugin.py @@ -20,7 +20,9 @@ import logging from itertools import izip +import dbus from dbus import DBusException, SessionBus +from dbus import PROPERTIES_IFACE import gobject from telepathy.client import (Channel, Connection) @@ -33,7 +35,7 @@ from telepathy.constants import (CONNECTION_STATUS_DISCONNECTED, from telepathy.interfaces import (CONN_INTERFACE, CHANNEL_TYPE_TEXT, CHANNEL_TYPE_STREAMED_MEDIA, CHANNEL_INTERFACE_GROUP, CONN_INTERFACE_PRESENCE, CHANNEL_TYPE_CONTACT_LIST, - CONN_MGR_INTERFACE) + CONN_MGR_INTERFACE, CHANNEL, CONNECTION_INTERFACE_REQUESTS) from telepathy.errors import (InvalidArgument, InvalidHandle) import psutils @@ -129,9 +131,6 @@ class TelepathyPlugin(gobject.GObject): #: length of the next reconnect timeout self._reconnect_timeout = self._RECONNECT_INITIAL_TIMEOUT - #: Parameters for the connection manager - self._account = self._get_account_info() - #: The ``subscribe`` channel: a `telepathy.client.Channel` or None self._subscribe_channel = None #: The members of the ``subscribe`` channel @@ -144,14 +143,8 @@ class TelepathyPlugin(gobject.GObject): #: The ``publish`` channel: a `telepathy.client.Channel` or None self._publish_channel = None - #: Watch the connection on DBus session bus self._session_bus = SessionBus() - self._watch_conn_name = None - - # Monitor IPv4 address as an indicator of the network connection - self._ip4am = psutils.IP4AddressMonitor.get_instance() - self._ip4am_sigid = self._ip4am.connect('address-changed', - self._ip4_address_changed_cb) + self._init_connection() @property def status(self): @@ -162,11 +155,6 @@ class TelepathyPlugin(gobject.GObject): """Retrieve our telepathy.client.Connection object""" return self._conn - def _get_account_info(self): - """Retrieve connection manager parameters for this account - """ - raise NotImplementedError - def suggest_room_for_activity(self, activity_id): """Suggest a room to use to share the given activity. """ @@ -175,32 +163,6 @@ class TelepathyPlugin(gobject.GObject): def identify_contacts(self, tp_chan, handles, identifiers=None): raise NotImplementedError - def _reconnect_cb(self): - """Attempt to reconnect to the server after the back-off time has - elapsed. - """ - _logger.debug("%r: reconnect timed out. Let's try to connect", self) - if self._backoff_id > 0: - gobject.source_remove(self._backoff_id) - self._backoff_id = 0 - - # this is a no-op unless _could_connect() returns True - self.start() - - return False - - def _reset_reconnect_timer(self): - if self._backoff_id != 0: - gobject.source_remove(self._backoff_id) - - _logger.debug("%r: restart reconnect time out (%u seconds)", - self, self._reconnect_timeout / 1000) - self._backoff_id = gobject.timeout_add(self._reconnect_timeout, - self._reconnect_cb) - - if self._reconnect_timeout < self._RECONNECT_MAX_TIMEOUT: - self._reconnect_timeout *= 2 - def _init_connection(self): """Set up our connection @@ -215,10 +177,8 @@ class TelepathyPlugin(gobject.GObject): _logger.debug('%r: init connection', self) conn = self._find_existing_connection() if not conn: - _logger.debug('%r: no existing connection. Create a new one', self) - conn = self._make_new_connection() - else: - _logger.debug('%r: found existing connection. Reuse it', self) + _logger.debug('%r: no existing connection', self) + return m = conn[CONN_INTERFACE].connect_to_signal('StatusChanged', self._handle_connection_status_change) @@ -230,39 +190,13 @@ class TelepathyPlugin(gobject.GObject): conn.service_name, self._watch_conn_name_cb) self._conn = conn - status = self._conn[CONN_INTERFACE].GetStatus() - - self._owner.set_properties_before_connect(self) - if status == CONNECTION_STATUS_DISCONNECTED: - def connect_reply(): - _logger.debug('%r: Connect() succeeded', self) - def connect_error(e): - _logger.debug('%r: Connect() failed: %s', self, e) - # we don't allow ourselves to retry more often than this - self._reset_reconnect_timer() - self._conn = None - - self._conn[CONN_INTERFACE].Connect(reply_handler=connect_reply, - error_handler=connect_error) - - self._handle_connection_status_change(status, - CONNECTION_STATUS_REASON_NONE_SPECIFIED) + status = self._conn.GetStatus() + self._handle_connection_status_change(status, CONNECTION_STATUS_REASON_NONE_SPECIFIED) def _find_existing_connection(self): raise NotImplementedError - def _make_new_connection(self): - acct = self._account.copy() - - # Create a new connection - mgr = self._registry.GetManager(self._TP_CONN_MANAGER) - name, path = mgr[CONN_MGR_INTERFACE].RequestConnection( - self._PROTOCOL, acct) - conn = Connection(name, path) - del acct - return conn - def _watch_conn_name_cb(self, dbus_name): """Check if we still have a connection on the DBus session bus. @@ -289,17 +223,10 @@ class TelepathyPlugin(gobject.GObject): self._connected_cb() elif status == CONNECTION_STATUS_DISCONNECTED: self._conn = None - self._stop() _logger.debug("%r: disconnected (reason %r)", self, reason) if reason == CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED: # FIXME: handle connection failure; retry later? _logger.debug("%r: authentification failed. Give up ", self) - else: - # Try again later. We'll detect whether we have a network - # connection after the retry period elapses. The fact that - # this timer is running also serves as a marker to indicate - # that we shouldn't try to go back online yet. - self._reset_reconnect_timer() self.emit('status', self._conn_status, int(reason)) @@ -308,47 +235,6 @@ class TelepathyPlugin(gobject.GObject): # or this is the first attempt return (self._backoff_id == 0) - def _stop(self): - """If we still have a connection, disconnect it""" - - matches = self._matches - self._matches = [] - for match in matches: - match.remove() - if self._watch_conn_name is not None: - self._watch_conn_name.cancel() - self._watch_conn_name = None - - if self._conn: - try: - self._conn[CONN_INTERFACE].Disconnect() - except DBusException, e: - _logger.debug('%s Disconnect(): %s', self._conn.object_path, e) - - self._conn_status = CONNECTION_STATUS_DISCONNECTED - self.emit('status', self._conn_status, 0) - - if self._online_contacts: - # Copy contacts when passing them to self._contacts_offline to - # ensure it's pass by _value_, otherwise (since it's a set) it's - # passed by reference and odd things happen when it gets subtracted - # from itself - self._contacts_offline(self._online_contacts.copy()) - - # Erase connection as the last thing done, because some of the - # above calls depend on self._conn being valid - self._conn = None - - def cleanup(self): - self._stop() - - if self._backoff_id > 0: - gobject.source_remove(self._backoff_id) - self._backoff_id = 0 - - self._ip4am.disconnect(self._ip4am_sigid) - self._ip4am_sigid = 0 - def _contacts_offline(self, handles): """Handle contacts going offline (send message, update set)""" self._online_contacts -= handles @@ -523,6 +409,8 @@ class TelepathyPlugin(gobject.GObject): self._matches.append(m) def _subscribe_channel_cb(self, channel): + if self._subscribe_channel is not None: + return # the group of contacts for whom you wish to receive presence self._subscribe_channel = channel m = channel[CHANNEL_INTERFACE_GROUP].connect_to_signal( @@ -568,36 +456,14 @@ class TelepathyPlugin(gobject.GObject): _logger.warning('%s does not support Connection.Interface.' 'Presence', self._conn.object_path) - def start(self): - """Start up the Telepathy networking connections - - if we are already connected, query for the initial contact - information. - - if we are already connecting, do nothing - - otherwise initiate a connection and transfer control to - _connect_reply_cb or _connect_error_cb - """ - - if self._ip4am_sigid == 0: - self._ip4am_sigid = self._ip4am.connect('address-changed', - self._ip4_address_changed_cb) - - if self._conn is not None: - return - - _logger.debug("%r: Starting up...", self) - - # Only init connection if we have a valid IP address - if self._could_connect(): - # Reread account info in case the server changed - self._account = self._get_account_info() - self._init_connection() - else: - _logger.debug('%r: Postponing connection', self) - - def _ip4_address_changed_cb(self, ip4am, address, iface): - _logger.debug("::: IP4 address now %s", address) - - self._reconnect_timeout = self._RECONNECT_INITIAL_TIMEOUT + properties = { + CHANNEL + '.ChannelType': CHANNEL_TYPE_CONTACT_LIST, + CHANNEL + '.TargetHandleType': HANDLE_TYPE_LIST, + CHANNEL + '.TargetID': 'subscribe', + } + properties = dbus.Dictionary(properties, signature='sv') + connection = self._conn[CONNECTION_INTERFACE_REQUESTS] + is_ours, channel_path, properties = connection.EnsureChannel(properties) + + channel = Channel(self._conn.service_name, channel_path) + self._subscribe_channel_cb(channel) -- cgit v0.9.1