-
-"""
-@todo Add params for different state machines update times
-@todo Get a callback for missed calls to force an update of the voicemail state machine
-@todo Get a callback on an incoming call and if its from GV, auto-pickup
-"""
-
-
import os
import weakref
import logging
+import gobject
import telepathy
try:
import constants
import tp
import util.coroutines as coroutines
+import util.go_utils as gobject_utils
import util.misc as util_misc
import gtk_toolbox
_moduleLogger = logging.getLogger("connection")
+class TheOneRingOptions(object):
+
+ useGVContacts = True
+
+ assert gvoice.session.Session._DEFAULTS["contacts"][1] == "hours"
+ contactsPollPeriodInHours = gvoice.session.Session._DEFAULTS["contacts"][0]
+
+ assert gvoice.session.Session._DEFAULTS["voicemail"][1] == "minutes"
+ voicemailPollPeriodInMinutes = gvoice.session.Session._DEFAULTS["voicemail"][0]
+
+ assert gvoice.session.Session._DEFAULTS["texts"][1] == "minutes"
+ textsPollPeriodInMinutes = gvoice.session.Session._DEFAULTS["texts"][0]
+
+ def __init__(self, parameters = None):
+ if parameters is None:
+ return
+ self.useGVContacts = parameters["use-gv-contacts"]
+ self.contactsPollPeriodInHours = parameters['contacts-poll-period-in-hours']
+ self.voicemailPollPeriodInMinutes = parameters['voicemail-poll-period-in-minutes']
+ self.textsPollPeriodInMinutes = parameters['texts-poll-period-in-minutes']
+
+
class TheOneRingConnection(
tp.Connection,
requests.RequestsMixin,
# overiding base class variable
_mandatory_parameters = {
- 'account' : 's',
- 'password' : 's',
+ 'account': 's',
+ 'password': 's',
}
# overiding base class variable
_optional_parameters = {
- 'forward' : 's',
+ 'forward': 's',
+ 'use-gv-contacts': 'b',
+ 'contacts-poll-period-in-hours': 'i',
+ 'voicemail-poll-period-in-minutes': 'i',
+ 'texts-poll-period-in-minutes': 'i',
}
_parameter_defaults = {
- 'forward' : '',
+ 'forward': '',
+ 'use-gv-contacts': TheOneRingOptions.useGVContacts,
+ 'contacts-poll-period-in-hours': TheOneRingOptions.contactsPollPeriodInHours,
+ 'voicemail-poll-period-in-minutes': TheOneRingOptions.voicemailPollPeriodInMinutes,
+ 'texts-poll-period-in-minutes': TheOneRingOptions.textsPollPeriodInMinutes,
}
_secret_parameters = set((
"password",
# Connection init must come first
self.__session = gvoice.session.Session(None)
+ self.__options = TheOneRingOptions(parameters)
tp.Connection.__init__(
self,
constants._telepathy_protocol_name_,
if conic is not None:
self.__connection = conic.Connection()
- self.__connectionEventId = None
else:
self.__connection = None
- self.__connectionEventId = None
self.__cachePath = os.sep.join((constants._data_path_, "cache", self.username))
try:
os.makedirs(self.__cachePath)
self.set_self_handle(handle.create_handle(self, 'connection'))
self.__callback = None
+ self.__connectionEventId = None
+ self.__delayedDisconnectEventId = None
_moduleLogger.info("Connection to the account %s created" % account)
@property
return self.__session
@property
+ def options(self):
+ return self.__options
+
+ @property
def username(self):
return self.__credentials[0]
def get_handle_by_name(self, handleType, handleName):
requestedHandleName = handleName.encode('utf-8')
if handleType == telepathy.HANDLE_TYPE_CONTACT:
- _moduleLogger.info("get_handle_by_name Contact: %s" % requestedHandleName)
+ _moduleLogger.debug("get_handle_by_name Contact: %s" % requestedHandleName)
h = handle.create_handle(self, 'contact', requestedHandleName)
elif handleType == telepathy.HANDLE_TYPE_LIST:
# Support only server side (immutable) lists
- _moduleLogger.info("get_handle_by_name List: %s" % requestedHandleName)
+ _moduleLogger.debug("get_handle_by_name List: %s" % requestedHandleName)
h = handle.create_handle(self, 'list', requestedHandleName)
else:
raise telepathy.errors.NotAvailable('Handle type unsupported %d' % handleType)
"""
For org.freedesktop.telepathy.Connection
"""
- self.StatusChanged(
- telepathy.CONNECTION_STATUS_DISCONNECTED,
- telepathy.CONNECTION_STATUS_REASON_REQUESTED
- )
try:
self._disconnect()
except Exception:
_moduleLogger.exception("Error durring disconnect")
+ self.StatusChanged(
+ telepathy.CONNECTION_STATUS_DISCONNECTED,
+ telepathy.CONNECTION_STATUS_REASON_REQUESTED
+ )
@gtk_toolbox.log_exception(_moduleLogger)
def RequestChannel(self, type, handleType, handleId, suppressHandler):
self.session.save(self.__cachePath)
self.session.logout()
self.session.close()
- self.__session = None
- if self.__connection is not None:
- self.__connection.disconnect(self.__connectionEventId)
- self.__connectionEventId = None
self.manager.disconnected(self)
+
+ self._cancel_delayed_disconnect()
+ self.__connection = None
_moduleLogger.info("Disconnected")
@gtk_toolbox.log_exception(_moduleLogger)
h = self.get_handle_by_name(telepathy.HANDLE_TYPE_CONTACT, phoneNumber)
# Just let the TextChannel decide whether it should be reported to the user or not
props = self._generate_props(telepathy.CHANNEL_TYPE_TEXT, h, False)
+ if self.__channelManager.channel_exists(props):
+ continue
+
+ # Maemo 4.1's RTComm opens a window for a chat regardless if a
+ # message is received or not, so we need to do some filtering here
+ mergedConv = conv.get_conversation(phoneNumber)
+ unreadConvs = [
+ conversation
+ for conversation in mergedConv.conversations
+ if not conversation.isRead and not conversation.isArchived
+ ]
+ if not unreadConvs:
+ continue
+
chan = self.__channelManager.channel_for_props(props, signal=True)
@gtk_toolbox.log_exception(_moduleLogger)
def _on_connection_change(self, connection, event):
"""
@note Maemo specific
-
- @todo Make this delayed to handle background switching of networks. First I need to verify I receive connected
"""
status = event.get_status()
error = event.get_error()
bearer = event.get_bearer_type()
if status == conic.STATUS_DISCONNECTED:
- _moduleLogger.info("Disconnecting due to loss of network connection")
- self.StatusChanged(
- telepathy.CONNECTION_STATUS_DISCONNECTED,
- telepathy.CONNECTION_STATUS_REASON_NETWORK_ERROR
+ _moduleLogger.info("Disconnected from network, starting countdown to logoff")
+ self.__delayedDisconnectEventId = gobject_utils.timeout_add_seconds(
+ 5, self._on_delayed_disconnect
)
- try:
- self._disconnect()
- except Exception:
- _moduleLogger.exception("Error durring disconnect")
+ elif status == conic.STATUS_CONNECTED:
+ _moduleLogger.info("Connected to network")
+ self._cancel_delayed_disconnect()
else:
_moduleLogger.info("Other status: %r" % (status, ))
+
+ def _cancel_delayed_disconnect(self):
+ if self.__delayedDisconnectEventId is None:
+ return
+ _moduleLogger.info("Cancelling auto-log off")
+ gobject.source_reove(self.__delayedDisconnectEventId)
+ self.__delayedDisconnectEventId = None
+
+ @gtk_toolbox.log_exception(_moduleLogger)
+ def _on_delayed_disconnect(self):
+ if not self.session.is_logged_in():
+ _moduleLogger.info("Received connection change event when not logged in")
+ return
+ try:
+ self._disconnect()
+ except Exception:
+ _moduleLogger.exception("Error durring disconnect")
+ self.StatusChanged(
+ telepathy.CONNECTION_STATUS_DISCONNECTED,
+ telepathy.CONNECTION_STATUS_REASON_NETWORK_ERROR
+ )
+ self.__delayedDisconnectEventId = None
+ return False