X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fchannel%2Ftext.py;h=d4cb5c08122973a3356c76bf608cceaf9269d225;hb=5bfb4228f1fff939aa06dfbe446cf17b5ce3ed76;hp=24a0687a9b2dd969f5ae536830656afb00313db1;hpb=287749a3ecbe03010bdea9423d75b19df37551e4;p=theonering diff --git a/src/channel/text.py b/src/channel/text.py index 24a0687..d4cb5c0 100644 --- a/src/channel/text.py +++ b/src/channel/text.py @@ -4,48 +4,28 @@ import logging import telepathy +import tp import util.coroutines as coroutines -import gtk_toolbox +import util.misc as misc_utils _moduleLogger = logging.getLogger("channel.text") -class TextChannel(telepathy.server.ChannelTypeText): - """ - Look into implementing ChannelInterfaceMessages for rich text formatting - """ +class TextChannel(tp.ChannelTypeText): + + NULL_TIMESTAMP = datetime.datetime(1, 1, 1) def __init__(self, connection, manager, props, contactHandle): self.__manager = manager self.__props = props - try: - # HACK Older python-telepathy way - telepathy.server.ChannelTypeText.__init__(self, connection, contactHandle) - self._requested = props[telepathy.interfaces.CHANNEL_INTERFACE + '.Requested'] - self._implement_property_get( - telepathy.interfaces.CHANNEL_INTERFACE, - {"Requested": lambda: self._requested} - ) - except TypeError: - # HACK Newer python-telepathy way - telepathy.server.ChannelTypeText.__init__(self, connection, manager, props) + tp.ChannelTypeText.__init__(self, connection, manager, props) self.__nextRecievedId = 0 - self.__lastMessageTimestamp = datetime.datetime(1, 1, 1) + self.__lastMessageTimestamp = self.NULL_TIMESTAMP self.__otherHandle = contactHandle - # HACK Older python-telepathy doesn't provide this - self._immutable_properties = { - 'ChannelType': telepathy.server.interfaces.CHANNEL_INTERFACE, - 'TargetHandle': telepathy.server.interfaces.CHANNEL_INTERFACE, - 'Interfaces': telepathy.server.interfaces.CHANNEL_INTERFACE, - 'TargetHandleType': telepathy.server.interfaces.CHANNEL_INTERFACE, - 'TargetID': telepathy.server.interfaces.CHANNEL_INTERFACE, - 'Requested': telepathy.server.interfaces.CHANNEL_INTERFACE - } - self.__callback = coroutines.func_sink( coroutines.expand_positional( self._on_conversations_updated @@ -63,39 +43,48 @@ class TextChannel(telepathy.server.ChannelTypeText): try: mergedConversations = self._conn.session.voicemails.get_conversation(self._contactKey) except KeyError: - _moduleLogger.debug("Nothing in the conversation yet for %r" % (self._contactKey, )) + _moduleLogger.debug("No voicemails in the conversation yet for %r" % (self._contactKey, )) else: self._report_conversation(mergedConversations) try: mergedConversations = self._conn.session.texts.get_conversation(self._contactKey) except KeyError: - _moduleLogger.debug("Nothing in the conversation yet for %r" % (self._contactKey, )) + _moduleLogger.debug("No texts conversation yet for %r" % (self._contactKey, )) else: self._report_conversation(mergedConversations) - def get_props(self): - # HACK Older python-telepathy doesn't provide this - props = dict() - for prop, iface in self._immutable_properties.items(): - props[iface + '.' + prop] = \ - self._prop_getters[iface][prop]() - return props - - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def Send(self, messageType, text): if messageType != telepathy.CHANNEL_TEXT_MESSAGE_TYPE_NORMAL: raise telepathy.errors.NotImplemented("Unhandled message type: %r" % messageType) + if self.__lastMessageTimestamp == self.NULL_TIMESTAMP: + # Hack: GV marks messages as read when they are replied to. If GV + # marks them as read than we ignore them. So reduce the window for + # them being marked as read. Oh and Conversations already handles + # it if the message was already part of a thread, so we can limit + # this to if we are trying to start a thread. You might say a + # voicemail could be what is being replied to and that doesn't mean + # anything. Oh well. + try: + self._conn.session.texts.update(force=True) + except Exception: + _moduleLogger.exception( + "Update failed when proactively checking for texts" + ) + + _moduleLogger.info("Sending message to %r" % (self.__otherHandle, )) self._conn.session.backend.send_sms(self.__otherHandle.phoneNumber, text) self._conn.session.textsStateMachine.reset_timers() self.Sent(int(time.time()), messageType, text) - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def Close(self): self.close() def close(self): + _moduleLogger.debug("Closing text") self._conn.session.voicemails.updateSignalHandler.unregister_sink( self.__callback ) @@ -104,18 +93,15 @@ class TextChannel(telepathy.server.ChannelTypeText): ) self.__callback = None - telepathy.server.ChannelTypeText.Close(self) - if self.__manager.channel_exists(self.__props): - # HACK Older python-telepathy requires doing this manually - self.__manager.remove_channel(self) + tp.ChannelTypeText.Close(self) self.remove_from_connection() @property def _contactKey(self): - contactKey = self.__otherHandle.contactID, self.__otherHandle.phoneNumber + contactKey = self.__otherHandle.phoneNumber return contactKey - @gtk_toolbox.log_exception(_moduleLogger) + @misc_utils.log_exception(_moduleLogger) def _on_conversations_updated(self, conv, conversationIds): if self._contactKey not in conversationIds: return @@ -124,7 +110,15 @@ class TextChannel(telepathy.server.ChannelTypeText): self._report_conversation(mergedConversations) def _report_conversation(self, mergedConversations): + # Can't filter out messages in a texting conversation that came in + # before the last one sent because that creates a race condition of two + # people sending at about the same time, which happens quite a bit newConversations = mergedConversations.conversations + if not newConversations: + _moduleLogger.debug( + "No messages ended up existing for %r" % (self._contactKey, ) + ) + return newConversations = self._filter_out_reported(newConversations) newConversations = self._filter_out_read(newConversations) newConversations = list(newConversations) @@ -150,6 +144,8 @@ class TextChannel(telepathy.server.ChannelTypeText): for newMessage in messages: formattedMessage = self._format_message(newMessage) self._report_new_message(formattedMessage) + for conv in newConversations: + conv.isRead = True def _filter_out_reported(self, conversations): return ( @@ -158,7 +154,8 @@ class TextChannel(telepathy.server.ChannelTypeText): if self.__lastMessageTimestamp < conversation.time ) - def _filter_out_read(self, conversations): + @staticmethod + def _filter_out_read(conversations): return ( conversation for conversation in conversations