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")
# 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)
import time
-import datetime
import logging
import telepathy
import tp
import util.coroutines as coroutines
import util.misc as misc_utils
+import gvoice
_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
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:
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
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)
from __future__ import with_statement
+import datetime
import logging
try:
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