From 131378064035e5d9527adc85fd7ff5da05ed8cdb Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 16 Feb 2010 20:53:34 -0600 Subject: [PATCH] Consolidating filtering code, fixing some bugs along the way --- src/autogv.py | 12 +++++------ src/channel/text.py | 47 ++++++++++++++++--------------------------- src/gvoice/conversations.py | 45 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/autogv.py b/src/autogv.py index fcc1386..525ecaf 100644 --- a/src/autogv.py +++ b/src/autogv.py @@ -19,6 +19,7 @@ import util.coroutines as coroutines import util.go_utils as gobject_utils import util.tp_utils as telepathy_utils import util.misc as misc_utils +import gvoice _moduleLogger = logging.getLogger("autogv") @@ -68,12 +69,11 @@ class NewGVConversations(object): # 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: continue chan = self._connRef()._channel_manager.channel_for_props(props, signal=True) diff --git a/src/channel/text.py b/src/channel/text.py index d4cb5c0..d01b1af 100644 --- a/src/channel/text.py +++ b/src/channel/text.py @@ -1,5 +1,4 @@ import time -import datetime import logging import telepathy @@ -7,6 +6,7 @@ import telepathy import tp import util.coroutines as coroutines import util.misc as misc_utils +import gvoice _moduleLogger = logging.getLogger("channel.text") @@ -14,15 +14,13 @@ _moduleLogger = logging.getLogger("channel.text") class TextChannel(tp.ChannelTypeText): - NULL_TIMESTAMP = datetime.datetime(1, 1, 1) - def __init__(self, connection, manager, props, contactHandle): self.__manager = manager self.__props = props tp.ChannelTypeText.__init__(self, connection, manager, props) self.__nextRecievedId = 0 - self.__lastMessageTimestamp = self.NULL_TIMESTAMP + self.__hasServerBeenPolled = False self.__otherHandle = contactHandle @@ -38,6 +36,8 @@ class TextChannel(tp.ChannelTypeText): self.__callback ) + self._filter_out_reported = gvoice.conversations.FilterOutReported() + # The only reason there should be anything in the conversation is if # its new, so report it all try: @@ -58,7 +58,7 @@ class TextChannel(tp.ChannelTypeText): if messageType != telepathy.CHANNEL_TEXT_MESSAGE_TYPE_NORMAL: raise telepathy.errors.NotImplemented("Unhandled message type: %r" % messageType) - if self.__lastMessageTimestamp == self.NULL_TIMESTAMP: + if not self.__hasServerBeenPolled: # 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 @@ -110,57 +110,44 @@ class TextChannel(tp.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( + _moduleLogger.info( "No messages ended up existing for %r" % (self._contactKey, ) ) return + + # 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 = self._filter_out_reported(newConversations) - newConversations = self._filter_out_read(newConversations) + newConversations = gvoice.conversations.filter_out_read(newConversations) + newConversations = gvoice.conversations.filter_out_self(newConversations) newConversations = list(newConversations) if not newConversations: _moduleLogger.debug( "New messages for %r have already been read externally" % (self._contactKey, ) ) return - self.__lastMessageTimestamp = newConversations[-1].time messages = [ newMessage for newConversation in newConversations for newMessage in newConversation.messages - if newMessage.whoFrom != "Me:" + if not gvoice.conversations.is_message_from_self(newMessage) ] - if not newConversations: + if not messages: _moduleLogger.debug( - "All incoming messages were really outbound messages for %r" % (self._contactKey, ) + "How did this happen for %r?" % (self._contactKey, ) ) return - 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 ( - conversation - for conversation in conversations - if self.__lastMessageTimestamp < conversation.time - ) - - @staticmethod - def _filter_out_read(conversations): - return ( - conversation - for conversation in conversations - if not conversation.isRead and not conversation.isArchived - ) + self.__hasServerBeenPolled = True def _format_message(self, message): return " ".join(part.text.strip() for part in message.body) diff --git a/src/gvoice/conversations.py b/src/gvoice/conversations.py index 4ccce3a..f6fe4b2 100644 --- a/src/gvoice/conversations.py +++ b/src/gvoice/conversations.py @@ -2,6 +2,7 @@ from __future__ import with_statement +import datetime import logging try: @@ -175,3 +176,47 @@ class MergedConversations(object): len(newConversationMessages), )) assert 0 < len(newConversation.messages), "Everything shouldn't have been removed" + + +def filter_out_read(conversations): + return ( + conversation + for conversation in conversations + if not conversation.isRead and not conversation.isArchived + ) + + +def is_message_from_self(message): + return message.whoFrom == "Me:" + + +def filter_out_self(conversations): + return ( + newConversation + for newConversation in conversations + if len(newConversation.messages) and any( + not is_message_from_self(message) + for message in newConversation.messages + ) + ) + + +class FilterOutReported(object): + + NULL_TIMESTAMP = datetime.datetime(1, 1, 1) + + def __init__(self): + self._lastMessageTimestamp = self.NULL_TIMESTAMP + + def get_last_timestamp(self): + return self._lastMessageTimestamp + + def __call__(self, conversations): + filteredConversations = [ + conversation + for conversation in conversations + if self._lastMessageTimestamp < conversation.time + ] + if filteredConversations and self._lastMessageTimestamp < filteredConversations[0].time: + self._lastMessageTimestamp = filteredConversations[0].time + return filteredConversations -- 1.7.9.5