Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/telepathy_plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/telepathy_plugin.py')
-rw-r--r--src/telepathy_plugin.py176
1 files changed, 21 insertions, 155 deletions
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)