X-Git-Url: http://git.maemo.org/git/?p=theonering;a=blobdiff_plain;f=src%2Fautogv.py;h=0ebefea13204e0175145a95d53bb9eea91ccd4e7;hp=d18b28b221aa629398eaa767b6264c9bb509f308;hb=effb4ac5c89ea815abbdd6b4f996d8d539f7407b;hpb=ac08a8171fb00beff39b5f5268b768fd4a85773d diff --git a/src/autogv.py b/src/autogv.py index d18b28b..0ebefea 100644 --- a/src/autogv.py +++ b/src/autogv.py @@ -1,6 +1,6 @@ import logging -import gobject +import dbus import telepathy try: @@ -19,10 +19,11 @@ import constants import util.coroutines as coroutines import util.go_utils as gobject_utils import util.tp_utils as telepathy_utils -import gtk_toolbox +import util.misc as misc_utils +import gvoice -_moduleLogger = logging.getLogger("autogv") +_moduleLogger = logging.getLogger(__name__) class NewGVConversations(object): @@ -56,7 +57,7 @@ class NewGVConversations(object): ) self.__callback = None - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_conversations_updated(self, conv, conversationIds): _moduleLogger.debug("Incoming messages from: %r" % (conversationIds, )) for phoneNumber in conversationIds: @@ -64,17 +65,18 @@ class NewGVConversations(object): # Just let the TextChannel decide whether it should be reported to the user or not props = self._connRef().generate_props(telepathy.CHANNEL_TYPE_TEXT, h, False) if self._connRef()._channel_manager.channel_exists(props): + _moduleLogger.debug("Chat box already open for texting conversation with %s" % phoneNumber) 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: + newConversations = mergedConv.conversations + newConversations = gvoice.conversations.filter_out_read(newConversations) + newConversations = gvoice.conversations.filter_out_self(newConversations) + newConversations = list(newConversations) + if not newConversations: + _moduleLogger.debug("Not opening chat box for %s, all new messages are either read or from yourself" % phoneNumber) continue chan = self._connRef()._channel_manager.channel_for_props(props, signal=True) @@ -83,10 +85,11 @@ class NewGVConversations(object): class RefreshVoicemail(object): def __init__(self, connRef): + self._isStarted = False self._connRef = connRef + self._newChannelSignaller = telepathy_utils.NewChannelSignaller(self._on_new_channel) self._outstandingRequests = [] - self._isStarted = False def start(self): self._newChannelSignaller.start() @@ -108,7 +111,7 @@ class RefreshVoicemail(object): self._isStarted = False - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_new_channel(self, bus, serviceName, connObjectPath, channelObjectPath, channelType): if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA: return @@ -119,24 +122,118 @@ class RefreshVoicemail(object): return conn = telepathy.client.Connection(serviceName, connObjectPath) - chan = telepathy.client.Channel(serviceName, channelObjectPath) + try: + chan = telepathy.client.Channel(serviceName, channelObjectPath) + except dbus.exceptions.UnknownMethodException: + _moduleLogger.exception("Client might not have implemented a deprecated method") + return missDetection = telepathy_utils.WasMissedCall( bus, conn, chan, self._on_missed_call, self._on_error_for_missed ) self._outstandingRequests.append(missDetection) - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_missed_call(self, missDetection): _moduleLogger.info("Missed a call") self._connRef().session.voicemailsStateMachine.reset_timers() self._outstandingRequests.remove(missDetection) - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_error_for_missed(self, missDetection, reason): _moduleLogger.debug("Error: %r claims %r" % (missDetection, reason)) self._outstandingRequests.remove(missDetection) +class AutoAcceptGVCall(object): + + def __init__(self, connRef): + self._connRef = connRef + self._isStarted = False + self._incomingCall = False + self._incomingChannel = False + + self._newChannelSignaller = telepathy_utils.NewChannelSignaller(self._on_new_channel) + + self._bus = dbus.SystemBus() + self._bus.add_signal_receiver( + self._on_incoming, + path='/com/nokia/csd/call', + dbus_interface='com.nokia.csd.Call', + signal_name='Coming' + ) + self._callObject = self._bus.get_object('com.nokia.csd.Call', '/com/nokia/csd/call/1') + self._callInstance = dbus.Interface(self._callObject, 'com.nokia.csd.Call.Instance') + + def start(self): + self._newChannelSignaller.start() + self._isStarted = True + + def stop(self): + if not self._isStarted: + _moduleLogger.info("auto-accept monitor stopped without starting") + return + _moduleLogger.info("Stopping auto-accepting") + self._newChannelSignaller.stop() + + self._incomingCall = False + self._incomingChannel = False + self._isStarted = False + + @misc_utils.log_exception(_moduleLogger) + def _on_new_channel(self, bus, serviceName, connObjectPath, channelObjectPath, channelType): + if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA: + return + + cmName = telepathy_utils.cm_from_path(connObjectPath) + if cmName == constants._telepathy_implementation_name_: + _moduleLogger.debug("Ignoring channels from self to prevent deadlock") + return + + conn = telepathy.client.Connection(serviceName, connObjectPath) + try: + chan = telepathy.client.Channel(serviceName, channelObjectPath) + except dbus.exceptions.UnknownMethodException: + _moduleLogger.exception("Client might not have implemented a deprecated method") + return + + chan[telepathy.interfaces.CHANNEL].connect_to_signal( + "Closed", + self._on_closed, + ) + + self._incomingChannel = True + self._accept_if_ready() + + @misc_utils.log_exception(_moduleLogger) + def _on_incoming(self, objPath, callerNumber): + if self._isStarted: + self._incomingCall = True + self._accept_if_ready() + + @misc_utils.log_exception(_moduleLogger) + def _on_closed(self): + self._incomingCall = False + self._incomingChannel = False + + +class TimedDisconnect(object): + + def __init__(self, connRef): + self._connRef = connRef + self.__delayedDisconnect = gobject_utils.Timeout(self._on_delayed_disconnect) + + def start(self): + self.__delayedDisconnect.start(seconds=60) + + def stop(self): + self.__delayedDisconnect.cancel() + + @misc_utils.log_exception(_moduleLogger) + def _on_delayed_disconnect(self): + _moduleLogger.info("Timed disconnect occurred") + self._connRef().disconnect(telepathy.CONNECTION_STATUS_REASON_NETWORK_ERROR) + + class AutoDisconnect(object): def __init__(self, connRef): @@ -147,7 +244,7 @@ class AutoDisconnect(object): self.__connection = None self.__connectionEventId = None - self.__delayedDisconnectEventId = None + self.__delayedDisconnect = gobject_utils.Timeout(self._on_delayed_disconnect) def start(self): if self.__connection is not None: @@ -156,7 +253,7 @@ class AutoDisconnect(object): def stop(self): self._cancel_delayed_disconnect() - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_connection_change(self, connection, event): """ @note Maemo specific @@ -168,33 +265,27 @@ class AutoDisconnect(object): if status == conic.STATUS_DISCONNECTED: _moduleLogger.info("Disconnected from network, starting countdown to logoff") - self.__delayedDisconnectEventId = gobject_utils.timeout_add_seconds( - 5, self._on_delayed_disconnect - ) + self.__delayedDisconnect.start(seconds=5) elif status == conic.STATUS_CONNECTED: _moduleLogger.info("Connected to network") self._cancel_delayed_disconnect() else: _moduleLogger.info("Other status: %r" % (status, )) + @misc_utils.log_exception(_moduleLogger) 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 + self.__delayedDisconnect.cancel() - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_delayed_disconnect(self): - if not self.session.is_logged_in(): + if not self._connRef().session.is_logged_in(): _moduleLogger.info("Received connection change event when not logged in") return try: self._connRef().disconnect(telepathy.CONNECTION_STATUS_REASON_NETWORK_ERROR) except Exception: _moduleLogger.exception("Error durring disconnect") - self.__delayedDisconnectEventId = None - return False class DisconnectOnShutdown(object): @@ -229,12 +320,34 @@ class DisconnectOnShutdown(object): pass # Either None or close was removed (in Fremantle) self._osso = None - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_device_state_change(self, shutdown, save_unsaved_data, memory_low, system_inactivity, message, userData): """ @note Hildon specific """ try: - self._connRef().disconnect(telepathy.CONNECTION_STATUS_REASON_REQUEST) + self._connRef().disconnect(telepathy.CONNECTION_STATUS_REASON_REQUESTED) except Exception: _moduleLogger.exception("Error durring disconnect") + + +class DelayEnableContactIntegration(object): + + def __init__(self, protocolName): + self.__enableSystemContactSupport = telepathy_utils.EnableSystemContactIntegration( + protocolName + ) + self.__delayedEnable = gobject_utils.Async(self._on_delayed_enable) + + def start(self): + self.__delayedEnable.start() + + def stop(self): + self.__delayedEnable.cancel() + + @misc_utils.log_exception(_moduleLogger) + def _on_delayed_enable(self): + try: + self.__enableSystemContactSupport.start() + except dbus.DBusException, e: + _moduleLogger.info("Contact integration seems to not be supported (%s)" % e)