From ce4c05e738f65ca74316c59651bf63fb67329e06 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Sat, 28 Nov 2009 21:35:24 -0600 Subject: [PATCH] Lots of work in prep for conversations to work Also added unregistering for addressbook events --- src/channel/contact_list.py | 9 ++++++ src/channel/text.py | 73 ++++++++++++++++++++++++++++++++++++------- src/channel_manager.py | 2 +- src/connection.py | 20 +++++++----- src/gvoice/conversations.py | 7 +++++ 5 files changed, 92 insertions(+), 19 deletions(-) diff --git a/src/channel/contact_list.py b/src/channel/contact_list.py index e2a8493..970b809 100644 --- a/src/channel/contact_list.py +++ b/src/channel/contact_list.py @@ -4,6 +4,7 @@ import telepathy import util.go_utils as gobject_utils import util.coroutines as coroutines +import gtk_toolbox import handle @@ -39,6 +40,14 @@ class AllContactsListChannel(AbstractListChannel): contacts = addressbook.get_contacts() self._process_refresh(addressbook, contacts, []) + @gtk_toolbox.log_exception(_moduleLogger) + def Close(self): + telepathy.server.ChannelTypeContactList.Close(self) + self.remove_from_connection() + self._session.addressbook.updateSignalHandler.unregister_sink( + self._on_contacts_refreshed + ) + @coroutines.func_sink @coroutines.expand_positional @gobject_utils.async diff --git a/src/channel/text.py b/src/channel/text.py index 83de6da..5261690 100644 --- a/src/channel/text.py +++ b/src/channel/text.py @@ -1,10 +1,12 @@ import time +import datetime import logging import telepathy +import util.go_utils as gobject_utils +import util.coroutines as coroutines import gtk_toolbox -import handle _moduleLogger = logging.getLogger("channel.text") @@ -18,9 +20,23 @@ class TextChannel(telepathy.server.ChannelTypeText): def __init__(self, connection, h): telepathy.server.ChannelTypeText.__init__(self, connection, h) self._nextRecievedId = 0 + self._lastMessageTimestamp = datetime.datetime(1, 1, 1) self._otherHandle = h + self._conn.session.conversations.updateSignalHandler.register_sink( + self._on_message_received + ) + + # The only reason there should be anything in the conversation is if + # its new, so report it all + try: + conversation = self._conn.session.conversations[self._contactKey] + except KeyError: + pass + else: + self._report_conversation(conversation) + @gtk_toolbox.log_exception(_moduleLogger) def Send(self, messageType, text): if messageType != telepathy.CHANNEL_TEXT_MESSAGE_TYPE_NORMAL: @@ -32,21 +48,56 @@ class TextChannel(telepathy.server.ChannelTypeText): @gtk_toolbox.log_exception(_moduleLogger) def Close(self): - telepathy.server.ChannelTypeText.Close(self) - self.remove_from_connection() - - def _on_message_received(self, contactId, contactNumber, message): - """ - @todo Attatch this to receiving a message signal - """ + try: + # Clear since the user has seen it all and it should start a new conversation + self._conn.session.clear_conversation(self._contactKey) + + self._conn.session.conversations.updateSignalHandler.unregister_sink( + self._on_message_received + ) + finally: + telepathy.server.ChannelTypeText.Close(self) + self.remove_from_connection() + + @property + def _contactKey(self): + contactKey = self._otherHandle.contactID, self._otherHandle.phoneNumber + return contactKey + + @coroutines.func_sink + @coroutines.expand_positional + @gobject_utils.async + def _on_conversations_updated(self, conversationIds): + if self._contactKey not in conversationIds: + return + conversation = self._conn.session.conversations[self._contactKey] + self._report_conversation(conversation) + + def _report_conversation(self, conversation): + completeMessageHistory = conversation["messageParts"] + messages = self._filter_seen_messages(completeMessageHistory) + self._lastMessageTimestamp = messages[-1][0] + formattedMessage = self._format_messages(messages) + self._report_new_message(formattedMessage) + + def _filter_seen_messages(self, messages): + return ( + message + for message in messages + if self._lastMessageTimestamp < message[0] + ) + + def _format_messages(self, messages): + return "\n".join(message[1] for message in messages) + + def _report_new_message(self, message): currentReceivedId = self._nextRecievedId timestamp = int(time.time()) - h = handle.create_handle(self._conn, "contact", contactId, contactNumber) type = telepathy.CHANNEL_TEXT_MESSAGE_TYPE_NORMAL message = message.content - _moduleLogger.info("Received message from User %r" % h) - self.Received(id, timestamp, h, type, 0, message) + _moduleLogger.info("Received message from User %r" % self._otherHandle) + self.Received(id, timestamp, self._otherHandle, type, 0, message) self._nextRecievedId += 1 diff --git a/src/channel_manager.py b/src/channel_manager.py index 5f609fe..2331063 100644 --- a/src/channel_manager.py +++ b/src/channel_manager.py @@ -19,7 +19,7 @@ class ChannelManager(object): def close(self): for chan in self._listChannels.values(): - chan.remove_from_connection()# so that dbus lets it die. + chan.Close() for chan in self._textChannels.values(): chan.Close() for chan in self._callChannels.values(): diff --git a/src/connection.py b/src/connection.py index 2724a45..5fe94de 100644 --- a/src/connection.py +++ b/src/connection.py @@ -4,6 +4,8 @@ import logging import telepathy import constants +import util.go_utils as gobject_utils +import util.coroutines as coroutines import gtk_toolbox import gvoice import handle @@ -196,11 +198,15 @@ class TheOneRingConnection( h = handle.create_handle(self, 'contact', requestedContactId, requestedContactNumber) return h - def _on_invite_text(self, contactId): - """ - @todo Get externally initiated conversations working - """ - h = self._create_contact_handle(contactId) - + @coroutines.func_sink + @coroutines.expand_positional + @gobject_utils.async + def _on_conversations_updated(self, conversationIds): + # @todo get conversations update running + # @todo test conversatiuons channelManager = self._channelManager - channel = channelManager.channel_for_text(handle) + for contactId, phoneNumber in conversationIds: + h = self._create_contact_handle(contactId, phoneNumber) + # if its new, __init__ will take care of things + # if its old, its own update will take care of it + channel = channelManager.channel_for_text(handle) diff --git a/src/gvoice/conversations.py b/src/gvoice/conversations.py index a1c6f57..3e0040c 100644 --- a/src/gvoice/conversations.py +++ b/src/gvoice/conversations.py @@ -58,6 +58,12 @@ class Conversations(object): def get_conversation(self, key): return self._conversations[key] + def clear_conversation(self, key): + del self._conversations[key] + + def clear_all(self): + self._conversations.clear() + class Conversation(object): @@ -95,6 +101,7 @@ class Conversation(object): messageAppended = False + # @todo Handle No Transcription voicemails messageParts = self._data["messageParts"] for message in moreData["messageParts"]: messageWithTimestamp = self._append_time(message, moreData["time"]) -- 1.7.9.5