[telepathy-butterfly/master] Updated to tp-python 0.15.9 (now implements the Requests interface)

Louis-Francis Ratté-Boulianne louis-francis.ratte-boulianne at collabora.co.uk
Fri Jul 17 14:53:57 PDT 2009


---
 NEWS                              |    2 +
 butterfly/channel/contact_list.py |   20 +++++----
 butterfly/channel/group.py        |    8 ++--
 butterfly/channel/text.py         |    8 +--
 butterfly/channel_manager.py      |   78 +++++++++++++++++-------------------
 butterfly/connection.py           |   81 +++++++++++++++++++++++++------------
 telepathy-butterfly               |    4 +-
 7 files changed, 115 insertions(+), 86 deletions(-)

diff --git a/NEWS b/NEWS
index 4b8b3b5..ca2a3d2 100644
--- a/NEWS
+++ b/NEWS
@@ -4,9 +4,11 @@ telepathy-butterfly-0.3.5 (UNRELEASED)
 Dependencies:
  * Drop pymsn dependency
  * papyon 0.4.0
+ * telepathy-python 0.15.9
 
 Enhancements:
  * Migrate from pymsn to papyon as the MSN backend library
+ * Implement the Requests connection interface
 
 Fixes:
  * Use the presence type busy for busy presence (fd.o #22619)
diff --git a/butterfly/channel/contact_list.py b/butterfly/channel/contact_list.py
index afef20b..08bfa64 100644
--- a/butterfly/channel/contact_list.py
+++ b/butterfly/channel/contact_list.py
@@ -29,7 +29,11 @@ from butterfly.handle import ButterflyHandleFactory
 __all__ = ['ButterflyContactListChannelFactory']
 
 
-def ButterflyContactListChannelFactory(connection, handle):
+def ButterflyContactListChannelFactory(connection, manager, handle, props):
+    handle = connection.handle(
+        props[telepathy.CHANNEL_INTERFACE + '.TargetHandleType'],
+        props[telepathy.CHANNEL_INTERFACE + '.TargetHandle'])
+
     if handle.get_name() == 'subscribe':
         channel_class = ButterflySubscribeListChannel
     elif handle.get_name() == 'publish':
@@ -42,7 +46,7 @@ def ButterflyContactListChannelFactory(connection, handle):
         channel_class = ButterflyDenyListChannel
     else:
         raise TypeError("Unknown list type : " + handle.get_name())
-    return channel_class(connection, handle)
+    return channel_class(connection, manager, props)
 
 
 class ButterflyListChannel(
@@ -51,9 +55,9 @@ class ButterflyListChannel(
         papyon.event.AddressBookEventInterface):
     "Abstract Contact List channels"
 
-    def __init__(self, connection, handle):
+    def __init__(self, connection, manager, props):
         self._conn_ref = weakref.ref(connection)
-        telepathy.server.ChannelTypeContactList.__init__(self, connection, handle)
+        telepathy.server.ChannelTypeContactList.__init__(self, connection, manager, props)
         telepathy.server.ChannelInterfaceGroup.__init__(self)
         papyon.event.AddressBookEventInterface.__init__(self, connection.msn_client)
         self._populate(connection)
@@ -127,8 +131,8 @@ class ButterflySubscribeListChannel(ButterflyListChannel,
     'subscribed', basically this list contains the contact for whom you are
     supposed to receive presence notification."""
 
-    def __init__(self, connection, handle):
-        ButterflyListChannel.__init__(self, connection, handle)
+    def __init__(self, connection, manager, props):
+        ButterflyListChannel.__init__(self, connection, manager, props)
         papyon.event.ContactEventInterface.__init__(self, connection.msn_client)
         self.GroupFlagsChanged(telepathy.CHANNEL_GROUP_FLAG_CAN_ADD |
                 telepathy.CHANNEL_GROUP_FLAG_CAN_REMOVE, 0)
@@ -179,8 +183,8 @@ class ButterflySubscribeListChannel(ButterflyListChannel,
 class ButterflyPublishListChannel(ButterflyListChannel,
         papyon.event.ContactEventInterface):
 
-    def __init__(self, connection, handle):
-        ButterflyListChannel.__init__(self, connection, handle)
+    def __init__(self, connection, manager, props):
+        ButterflyListChannel.__init__(self, connection, manager, props)
         papyon.event.ContactEventInterface.__init__(self, connection.msn_client)
         self.GroupFlagsChanged(0, 0)
 
diff --git a/butterfly/channel/group.py b/butterfly/channel/group.py
index d0ae9cb..efd03b8 100644
--- a/butterfly/channel/group.py
+++ b/butterfly/channel/group.py
@@ -35,10 +35,10 @@ logger = logging.getLogger('Butterfly.GroupChannel')
 class ButterflyGroupChannel(ButterflyListChannel,
             papyon.event.AddressBookEventInterface):
 
-    def __init__(self, connection, handle):
+    def __init__(self, connection, manager, props):
         self.__pending_add = []
         self.__pending_remove = []
-        ButterflyListChannel.__init__(self, connection, handle)
+        ButterflyListChannel.__init__(self, connection, manager, props)
         papyon.event.AddressBookEventInterface.__init__(self, connection.msn_client)
         self.GroupFlagsChanged(telepathy.CHANNEL_GROUP_FLAG_CAN_ADD | 
                 telepathy.CHANNEL_GROUP_FLAG_CAN_REMOVE, 0)
@@ -46,8 +46,8 @@ class ButterflyGroupChannel(ButterflyListChannel,
         # FIXME: Move the server-side group creation into the GroupHandle.__init__
         @async
         def create_group():
-            if handle.group is None:
-                connection.msn_client.address_book.add_group(handle.name)
+            if self._handle.group is None:
+                connection.msn_client.address_book.add_group(self._handle.name)
         create_group()
 
     def AddMembers(self, contacts, message):
diff --git a/butterfly/channel/text.py b/butterfly/channel/text.py
index ce0b8b2..c42b6be 100644
--- a/butterfly/channel/text.py
+++ b/butterfly/channel/text.py
@@ -39,13 +39,12 @@ class ButterflyTextChannel(
         telepathy.server.ChannelInterfaceChatState,
         papyon.event.ConversationEventInterface):
 
-    def __init__(self, connection, conversation, chan_manager):
+    def __init__(self, conn, manager, conversation, props):
         self._recv_id = 0
         self._conversation = conversation
-        self._conn_ref = weakref.ref(connection)
-        self._chan_manager_ref = weakref.ref(chan_manager)
+        self._conn_ref = weakref.ref(conn)
 
-        telepathy.server.ChannelTypeText.__init__(self, connection, None)
+        telepathy.server.ChannelTypeText.__init__(self, conn, manager, props)
         telepathy.server.ChannelInterfaceGroup.__init__(self)
         telepathy.server.ChannelInterfaceChatState.__init__(self)
         papyon.event.ConversationEventInterface.__init__(self, self._conversation)
@@ -71,7 +70,6 @@ class ButterflyTextChannel(
 
     def Close(self):
         self._conversation.leave()
-        self._chan_manager_ref().remove_text_channel(self)
         telepathy.server.ChannelTypeText.Close(self)
         self.remove_from_connection()
 
diff --git a/butterfly/channel_manager.py b/butterfly/channel_manager.py
index f5eb4e5..040877f 100644
--- a/butterfly/channel_manager.py
+++ b/butterfly/channel_manager.py
@@ -27,53 +27,49 @@ from butterfly.channel.group import ButterflyGroupChannel
 from butterfly.channel.text import ButterflyTextChannel
 from butterfly.handle import ButterflyHandleFactory
 
-__all__ = ['ChannelManager']
+__all__ = ['ButterflyChannelManager']
 
 logger = logging.getLogger('Butterfly.ChannelManager')
 
-
-class ChannelManager(object):
+class ButterflyChannelManager(telepathy.server.ChannelManager):
     def __init__(self, connection):
-        self._conn_ref = weakref.ref(connection)
-        self._list_channels = weakref.WeakValueDictionary()
-        self._text_channels = weakref.WeakValueDictionary()
-
-    def close(self):
-        for channel in self._list_channels.values():
-            channel.remove_from_connection()# so that dbus lets it die.
-        for channel in self._text_channels.values():
-            channel.Close()
-
-    def channel_for_list(self, handle, suppress_handler=False):
-        if handle in self._list_channels:
-            channel = self._list_channels[handle]
-        else:
-            if handle.get_type() == telepathy.HANDLE_TYPE_GROUP:
-                channel = ButterflyGroupChannel(self._conn_ref(), handle)
-            else:
-                channel = ButterflyContactListChannelFactory(self._conn_ref(), handle)
-            self._list_channels[handle] = channel
-            self._conn_ref().add_channel(channel, handle, suppress_handler)
-        return channel
+        telepathy.server.ChannelManager.__init__(self, connection)
+
+        fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT,
+            telepathy.CHANNEL_INTERFACE + '.TargetHandleType': telepathy.HANDLE_TYPE_CONTACT}
+        self._implement_channel_class(telepathy.CHANNEL_TYPE_TEXT,
+            self._get_text_channel, fixed, [])
+
+        fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_CONTACT_LIST}
+        self._implement_channel_class(telepathy.CHANNEL_TYPE_CONTACT_LIST,
+            self._get_list_channel, fixed, [])
+
+    def _get_list_channel(self, props):
+        _, surpress_handler, handle = self._get_type_requested_handle(props)
 
-    def channel_for_text(self, handle, conversation=None, suppress_handler=False):
-        if handle in self._text_channels:
-            channel = self._text_channels[handle]
+        logger.debug('New contact list channel')
+        if handle.get_type() == telepathy.HANDLE_TYPE_GROUP:
+            channel = ButterflyGroupChannel(self._conn, self, props)
         else:
-            logger.debug("Requesting new text channel")
-            contact = handle.contact
-
-            if conversation is None:
-                client = self._conn_ref().msn_client
-                conversation = papyon.Conversation(client, [contact])
-            channel = ButterflyTextChannel(self._conn_ref(), conversation, self)
-            self._text_channels[handle] = channel
-            self._conn_ref().add_channel(channel, handle, suppress_handler)
+            channel = ButterflyContactListChannelFactory(self._conn,
+                self, handle, props)
         return channel
 
-    def remove_text_channel(self, text_channel):
-        logger.debug("Removing channel %s" % text_channel)
-        for handle, chan in self._text_channels.items():
-            if chan == text_channel:
-                del self._text_channels[handle]
+    def _get_text_channel(self, props, conversation=None):
+        _, surpress_handler, handle = self._get_type_requested_handle(props)
 
+        if handle.get_type() != telepathy.HANDLE_TYPE_CONTACT:
+            raise telepathy.NotImplemented('Only contacts are allowed')
+
+        contact = handle.contact
+
+        if contact.presence == papyon.Presence.OFFLINE:
+            raise telepathy.NotAvailable('Contact not available')
+
+        logger.debug('New text channel')
+
+        if conversation is None:
+            client = self._conn.msn_client
+            conversation = papyon.Conversation(client, [contact])
+        channel = ButterflyTextChannel(self._conn, self, conversation, props)
+        return channel
diff --git a/butterfly/connection.py b/butterfly/connection.py
index 8ff2a4e..b9defd2 100644
--- a/butterfly/connection.py
+++ b/butterfly/connection.py
@@ -20,6 +20,7 @@
 import weakref
 import logging
 
+import dbus
 import telepathy
 import papyon
 import papyon.event
@@ -29,7 +30,7 @@ from butterfly.aliasing import ButterflyAliasing
 from butterfly.avatars import ButterflyAvatars
 from butterfly.handle import ButterflyHandleFactory
 from butterfly.contacts import ButterflyContacts
-from butterfly.channel_manager import ChannelManager
+from butterfly.channel_manager import ButterflyChannelManager
 
 __all__ = ['ButterflyConnection']
 
@@ -37,6 +38,7 @@ logger = logging.getLogger('Butterfly.Connection')
 
 
 class ButterflyConnection(telepathy.server.Connection,
+        telepathy.server.ConnectionInterfaceRequests,
         ButterflyPresence,
         ButterflyAliasing,
         ButterflyAvatars,
@@ -85,10 +87,11 @@ class ButterflyConnection(telepathy.server.Connection,
             self._msn_client = papyon.Client(server, proxies)
             self._account = (parameters['account'].encode('utf-8'),
                     parameters['password'].encode('utf-8'))
-            self._channel_manager = ChannelManager(self)
+            self._channel_manager = ButterflyChannelManager(self)
 
             # Call parent initializers
             telepathy.server.Connection.__init__(self, 'msn', account, 'butterfly')
+            telepathy.server.ConnectionInterfaceRequests.__init__(self)
             ButterflyPresence.__init__(self)
             ButterflyAliasing.__init__(self)
             ButterflyAvatars.__init__(self)
@@ -165,26 +168,32 @@ class ButterflyConnection(telepathy.server.Connection,
             self.add_client_handle(handle, sender)
         return handles
 
-    def RequestChannel(self, type, handle_type, handle_id, suppress_handler):
-        self.check_connected()
+    def _generate_props(self, channel_type, handle, suppress_handler):
+        return {
+            telepathy.CHANNEL_INTERFACE + '.ChannelType': channel_type,
+            telepathy.CHANNEL_INTERFACE + '.TargetHandle': 0 if handle is None else handle.get_id(),
+            telepathy.CHANNEL_INTERFACE + '.TargetHandleType': telepathy.HANDLE_TYPE_NONE if handle is None else handle.get_type(),
+            telepathy.CHANNEL_INTERFACE + '.Requested': suppress_handler
+            }
 
-        channel = None
+    @dbus.service.method(telepathy.CONNECTION, in_signature='suub',
+        out_signature='o', async_callbacks=('_success', '_error'))
+    def RequestChannel(self, type, handle_type, handle_id, suppress_handler,
+            _success, _error):
+        self.check_connected()
         channel_manager = self._channel_manager
-        handle = self.handle(handle_type, handle_id)
-
-        if type == telepathy.CHANNEL_TYPE_CONTACT_LIST:
-            channel = channel_manager.channel_for_list(handle, suppress_handler)
-        elif type == telepathy.CHANNEL_TYPE_TEXT:
-            if handle_type != telepathy.HANDLE_TYPE_CONTACT:
-                raise telepathy.NotImplemented("Only Contacts are allowed")
-            contact = handle.contact
-            if contact.presence == papyon.Presence.OFFLINE:
-                raise telepathy.NotAvailable('Contact not available')
-            channel = channel_manager.channel_for_text(handle, None, suppress_handler)
+
+        if handle_id == 0:
+            handle = None
         else:
-            raise telepathy.NotImplemented("unknown channel type %s" % type)
+            handle = self.handle(handle_type, handle_id)
+        props = self._generate_props(type, handle, suppress_handler)
+        self._validate_handle(props)
+
+        channel = channel_manager.channel_for_props(props, signal=False)
 
-        return channel._object_path
+        _success(channel._object_path)
+        self.signal_new_channels([channel])
 
     # papyon.event.ClientEventInterface
     def on_client_state_changed(self, state):
@@ -193,19 +202,35 @@ class ButterflyConnection(telepathy.server.Connection,
                     telepathy.CONNECTION_STATUS_REASON_REQUESTED)
         elif state == papyon.event.ClientState.SYNCHRONIZED:
             handle = ButterflyHandleFactory(self, 'list', 'subscribe')
-            self._channel_manager.channel_for_list(handle)
+            props = self._generate_props(telepathy.CHANNEL_TYPE_CONTACT_LIST,
+                handle, False)
+            self._channel_manager.channel_for_props(props, signal=True)
+
             handle = ButterflyHandleFactory(self, 'list', 'publish')
-            self._channel_manager.channel_for_list(handle)
+            props = self._generate_props(telepathy.CHANNEL_TYPE_CONTACT_LIST,
+                handle, False)
+            self._channel_manager.channel_for_props(props, signal=True)
+
             #handle = ButterflyHandleFactory(self, 'list', 'hide')
-            #self._channel_manager.channel_for_list(handle)
+            #props = self._generate_props(telepathy.CHANNEL_TYPE_CONTACT_LIST,
+            #    handle, False)
+            #self._channel_manager.channel_for_props(props, signal=True)
+
             #handle = ButterflyHandleFactory(self, 'list', 'allow')
-            #self._channel_manager.channel_for_list(handle)
+            #props = self._generate_propstelepathy.CHANNEL_TYPE_CONTACT_LIST,
+            #    handle, False)
+            #self._channel_manager.channel_for_props(props, signal=True)
+
             #handle = ButterflyHandleFactory(self, 'list', 'deny')
-            #self._channel_manager.channel_for_list(handle)
+            #props = self._generate_props(telepathy.CHANNEL_TYPE_CONTACT_LIST,
+            #    handle, False)
+            #self._channel_manager.channel_for_props(props, signal=True)
 
             for group in self.msn_client.address_book.groups:
                 handle = ButterflyHandleFactory(self, 'group', group.name)
-                self._channel_manager.channel_for_list(handle)
+                props = self._generate_props(
+                    telepathy.CHANNEL_TYPE_CONTACT_LIST, handle, False)
+                self._channel_manager.channel_for_props(props, signal=True)
         elif state == papyon.event.ClientState.OPEN:
             self.StatusChanged(telepathy.CONNECTION_STATUS_CONNECTED,
                     telepathy.CONNECTION_STATUS_REASON_REQUESTED)
@@ -240,13 +265,17 @@ class ButterflyConnection(telepathy.server.Connection,
     def on_invite_conversation(self, conversation):
         logger.debug("Conversation invite")
         #FIXME: get rid of this crap and implement group support
-        participants = conversation.participants 
+        participants = conversation.participants
         for p in participants:
             participant = p
             break
         handle = ButterflyHandleFactory(self, 'contact',
                 participant.account, participant.network_id)
-        channel = self._channel_manager.channel_for_text(handle, conversation)
+
+        props = self._generate_props(telepathy.CHANNEL_TYPE_TEXT,
+            handle, False)
+        channel = self._channel_manager.channel_for_props(props,
+            signal=True, conversation=conversation)
 
     def _advertise_disconnected(self):
         self._manager.disconnected(self)
diff --git a/telepathy-butterfly b/telepathy-butterfly
index aadf024..6ff50cf 100755
--- a/telepathy-butterfly
+++ b/telepathy-butterfly
@@ -26,8 +26,8 @@ import sys
 import logging
 
 import telepathy
-if telepathy.version < (0, 15, 6):
-    print >> sys.stderr, 'Critical: telepathy-python >= 0.15.6 required. Exiting.'
+if telepathy.version < (0, 15, 8, 1):
+    print >> sys.stderr, 'Critical: telepathy-python >= 0.15.8.1 required. Exiting.'
     sys.exit(1)
 
 from telepathy.utils import debug_divert_messages
-- 
1.5.6.5



More information about the telepathy-commits mailing list