6 import util.coroutines as coroutines
9 _moduleLogger = logging.getLogger("gvoice.conversations")
12 class Conversations(object):
14 def __init__(self, backend):
15 self._backend = backend
16 self._conversations = {}
18 self.updateSignalHandler = coroutines.CoTee()
20 def update(self, force=False):
21 if not force and self._conversations:
24 oldConversationIds = set(self._conversations.iterkeys())
26 updateConversationIds = set()
27 conversations = list(self._backend.get_conversations())
29 for conversation in conversations:
30 key = conversation.contactId, conversation.number
32 mergedConversations = self._conversations[key]
34 mergedConversations = MergedConversations()
35 self._conversations[key] = mergedConversations
38 mergedConversations.append_conversation(conversation)
39 isConversationUpdated = True
41 isConversationUpdated = False
43 if isConversationUpdated:
44 updateConversationIds.add(key)
46 if updateConversationIds:
47 message = (self, updateConversationIds, )
48 self.updateSignalHandler.stage.send(message)
50 def get_conversations(self):
51 return self._conversations.iterkeys()
53 def get_conversation(self, key):
54 return self._conversations[key]
56 def clear_conversation(self, key):
58 del self._conversations[key]
60 _moduleLogger.info("Conversation never existed for %r" % (key,))
63 self._conversations.clear()
66 class MergedConversations(object):
69 self._conversations = []
71 def append_conversation(self, newConversation):
72 self._validate(newConversation)
73 self._remove_repeats(newConversation)
74 self._conversations.append(newConversation)
77 def conversations(self):
78 return self._conversations
80 def _validate(self, newConversation):
81 if not self._conversations:
84 for constantField in ("contactId", "number"):
85 assert getattr(self._conversations[0], constantField) == getattr(newConversation, constantField), "Constant field changed, soemthing is seriously messed up: %r v %r" % (
86 getattr(self._conversations[0], constantField),
87 getattr(newConversation, constantField),
90 if newConversation.time <= self._conversations[-1].time:
91 raise RuntimeError("Conversations got out of order")
93 def _remove_repeats(self, newConversation):
94 similarConversations = [
96 for conversation in self._conversations
97 if conversation.id == newConversation.id
100 for similarConversation in similarConversations:
101 for commonField in ("isRead", "isSpam", "isTrash", "isArchived"):
102 newValue = getattr(newConversation, commonField)
103 setattr(similarConversation, commonField, newValue)
105 newConversation.messages = [
107 for newMessage in newConversation.messages
108 if newMessage not in similarConversation.messages
110 assert 0 < len(newConversation.messages), "Everything shouldn't have been removed"