[telepathy-ashes/master] Mechanism to request channel with handler class.
David Laban
david.laban at collabora.co.uk
Wed Oct 14 10:59:26 PDT 2009
Many functions now take an optional handler_class argument, which
can be used to override the class from _handler_classes.
There is also a create_channel(request, handler_class) convenience
function.
---
ashes/tools/dispatchers.py | 59 +++++++++++++++++++++++++++++++++++---------
ashes/tools/groups.py | 4 +-
2 files changed, 49 insertions(+), 14 deletions(-)
diff --git a/ashes/tools/dispatchers.py b/ashes/tools/dispatchers.py
index 43b9ad9..72f5bec 100644
--- a/ashes/tools/dispatchers.py
+++ b/ashes/tools/dispatchers.py
@@ -12,7 +12,6 @@ from helper_functions import (get_connections, get_property,
# garbage collected.
# Should probably be sets but I'll leave it like this for now.
connections = []
-channels = []
class ChannelDispatcher(ConnectionListener):
@@ -27,8 +26,14 @@ class ChannelDispatcher(ConnectionListener):
REQUESTS = telepathy.interfaces.CONNECTION_INTERFACE_REQUESTS
CAPS = telepathy.interfaces.CONNECTION_INTERFACE_CAPABILITIES
+ # FIXME: This dict looks like a class variable, but is shadowed by an
+ # instance variable later. This is massively confusing.
_handler_classes = {}
+ # This list really is a class variable. The reason for this is to avoid
+ # two instances of the dispatcher handling the same channel.
+ channels = []
+
def _collect_handler_classes(self):
"""
This function collects handler classes registered to subclasses/
@@ -61,8 +66,9 @@ class ChannelDispatcher(ConnectionListener):
def finish_setup(self, *conn):
"""
- Sets up super-classes recursively, then sets capabilities
- FIXME: do caps based on _handler_classes rather than hardcoded.
+ Sets up super-classes recursively.
+ Note that setting capabilities is done in dispatch_initial_channels,
+ after the connection has told us that it is online.
"""
super(ChannelDispatcher, self).finish_setup()
@@ -75,6 +81,10 @@ class ChannelDispatcher(ConnectionListener):
super(ChannelDispatcher, self).StatusChanged(status, reason)
def dispatch_initial_channels(self):
+ """
+ Tells the connection manager what capabilities we support, and asks it
+ what channels it already has (reply handled by self.NewChannels).
+ """
handler_classes = self._collect_handler_classes()
caps = []
for (chantype, handletype), handler_class in handler_classes.items():
@@ -96,18 +106,26 @@ class ChannelDispatcher(ConnectionListener):
get_property(self.connection, telepathy.CONNECTION_INTERFACE_REQUESTS,
'Channels', reply_handler=self.NewChannels, error_handler=printer)
- #@shiny.debug_exceptions
def NewChannels(self, Channels):
"""
Callback for Requests.NewChannels.
"""
for object_path, properties in Channels:
- cb = rpartial(self.dispatch_channel, properties)
- telepathy.client.Channel(self.connection.service_name,
- object_path,
- ready_handler=cb)
+ self._new_channel(object_path, properties)
- def dispatch_channel(self, channel, properties):
+ def _new_channel(self, object_path, properties, handler_class=None):
+ """
+ Gets called for each new channel in NewChannels, and also as the reply
+ callback of create_channel.
+
+ handler_class can be used to override the default handler class.
+ """
+ cb = rpartial(self.dispatch_channel, properties, handler_class)
+ telepathy.client.Channel(self.connection.service_name,
+ object_path,
+ ready_handler=cb)
+
+ def dispatch_channel(self, channel, properties, handler_class=None):
"""
Gets called for each channel in a NewChannels signal.
The channel is guaranteed to be "ready" at this point.
@@ -117,7 +135,7 @@ class ChannelDispatcher(ConnectionListener):
handle = properties['org.freedesktop.Telepathy.Channel.TargetHandle']
requested = properties['org.freedesktop.Telepathy.Channel.Requested']
id = properties['org.freedesktop.Telepathy.Channel.TargetID']
- # Hrrrm. This optimisation is probably not very general.
+ # FIXME. This optimisation is probably not very general.
# Don't be putting it in any libraries.
if handle_type == telepathy.HANDLE_TYPE_CONTACT:
if re.match(self.contact_regexp, id):
@@ -130,13 +148,30 @@ class ChannelDispatcher(ConnectionListener):
else:
print id, 'does not match', self.contact_regexp
return
+ if channel in self.channels:
+ print "Channel already handled:", channel.object_path
- if (channel_type, handle_type) in self._handler_classes:
+ if handler_class is not None:
+ # FIXME: split this out into its own function.
+ handler = handler_class(self, channel, properties)
+ self.channels.append(handler)
+ elif (channel_type, handle_type) in self._handler_classes:
handler_class = self._handler_classes[channel_type, handle_type]
handler = handler_class(self, channel, properties)
- channels.append(handler)
+ self.channels.append(handler)
return handler
else:
print "Don't know how to handle channel with handle type:", handle_type,
print "and channel type", channel_type
+ def create_channel(self, request, handler_class=None, error_handler=printer):
+ """
+ Calls CreateChannel, and uses handler_class as the handler, if provided,
+ or uses the default as found in self._handler_classes.
+ Passing in a handler class will cause the NewChannels signal to be
+ ignored for this channel, as it will have already been handled.
+ """
+ cb = rpartial(self._new_channel, handler_class)
+ self.connection[telepathy.interfaces.CONNECTION_INTERFACE_REQUESTS
+ ].CreateChannel(request, reply_handler=cb, error_handler=error_handler)
+
diff --git a/ashes/tools/groups.py b/ashes/tools/groups.py
index 7fc2c9e..6d04655 100644
--- a/ashes/tools/groups.py
+++ b/ashes/tools/groups.py
@@ -141,12 +141,12 @@ class ContactSubscriber(ChannelDispatcher):
super(ContactSubscriber, self).__init__(*args, **kwargs)
self.contact_list_handlers = {}
- def dispatch_channel(self, channel, properties):
+ def dispatch_channel(self, *args):
"""
Adds a special case to ContactAcceptor classes (which handle magic
ContactList groups like publish and subscribe).
"""
- handler = super(ContactSubscriber, self).dispatch_channel(channel, properties)
+ handler = super(ContactSubscriber, self).dispatch_channel(*args)
if isinstance(handler, ContactAcceptor):
self.register_contact_list_handler(handler)
return handler
--
1.5.6.5
More information about the telepathy-commits
mailing list