From d8090ced1d14d7059d2d2a09cee6a9955cac9bb3 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Thu, 09 Jun 2011 14:51:28 +0000 Subject: Fix invitations from a non sugar client (empathy), part of OLPC #10814 This does bring back the 'invitation from a non-sugar client' functionality based on the 0.84 code. I did remove the part where we claim to handle as well video invitations for now, as we can not handle them. Signed-off-by: Simon Schampijer Acked-By: Sascha Silbe --- diff --git a/src/jarabe/model/invites.py b/src/jarabe/model/invites.py index d2a2e0c..631e49f 100644 --- a/src/jarabe/model/invites.py +++ b/src/jarabe/model/invites.py @@ -17,16 +17,15 @@ import logging from functools import partial +import simplejson import gobject import dbus +import gconf from telepathy.interfaces import CHANNEL, \ CHANNEL_DISPATCHER, \ CHANNEL_DISPATCH_OPERATION, \ CHANNEL_TYPE_CONTACT_LIST, \ - CHANNEL_TYPE_DBUS_TUBE, \ - CHANNEL_TYPE_STREAMED_MEDIA, \ - CHANNEL_TYPE_STREAM_TUBE, \ CHANNEL_TYPE_TEXT, \ CLIENT from telepathy.constants import HANDLE_TYPE_ROOM @@ -45,25 +44,51 @@ CONNECTION_INTERFACE_ACTIVITY_PROPERTIES = \ _instance = None -class ActivityInvite(object): - """Invitation to a shared activity.""" - def __init__(self, dispatch_operation_path, handle, handler, - activity_properties): +class BaseInvite(object): + """Invitation to shared activity or private 1-1 Telepathy channel""" + def __init__(self, dispatch_operation_path, handle, handler): self.dispatch_operation_path = dispatch_operation_path self._handle = handle self._handler = handler - if activity_properties is not None: - self._activity_properties = activity_properties - else: - self._activity_properties = {} - def get_bundle_id(self): if CLIENT in self._handler: return self._handler[len(CLIENT + '.'):] else: return None + def _call_handle_with(self): + bus = dbus.Bus() + obj = bus.get_object(CHANNEL_DISPATCHER, self.dispatch_operation_path) + dispatch_operation = dbus.Interface(obj, CHANNEL_DISPATCH_OPERATION) + dispatch_operation.HandleWith(self._handler, + reply_handler=self._handle_with_reply_cb, + error_handler=self._handle_with_reply_cb) + + def _handle_with_reply_cb(self, error=None): + if error is not None: + raise error + else: + logging.debug('_handle_with_reply_cb') + + def _name_owner_changed_cb(self, name, old_owner, new_owner): + logging.debug('BaseInvite._name_owner_changed_cb %r %r %r', name, + new_owner, old_owner) + if name == self._handler and new_owner and not old_owner: + self._call_handle_with() + + +class ActivityInvite(BaseInvite): + """Invitation to a shared activity.""" + def __init__(self, dispatch_operation_path, handle, handler, + activity_properties): + BaseInvite.__init__(self, dispatch_operation_path, handle, handler) + + if activity_properties is not None: + self._activity_properties = activity_properties + else: + self._activity_properties = {} + def get_color(self): color = self._activity_properties.get('color', None) return XoColor(color) @@ -76,37 +101,44 @@ class ActivityInvite(object): bundle = registry.get_bundle(bundle_id) if bundle is None: self._call_handle_with() - else: - bus = dbus.SessionBus() - bus.add_signal_receiver(self.__name_owner_changed_cb, - 'NameOwnerChanged', - 'org.freedesktop.DBus', - arg0=self._handler) - - model = neighborhood.get_model() - activity_id = model.get_activity_by_room(self._handle).activity_id - misc.launch(bundle, color=self.get_color(), invited=True, - activity_id=activity_id) - - def __name_owner_changed_cb(self, name, old_owner, new_owner): - logging.debug('ActivityInvite.__name_owner_changed_cb %r %r %r', name, - new_owner, old_owner) - if name == self._handler and new_owner and not old_owner: - self._call_handle_with() + return - def _call_handle_with(self): - bus = dbus.Bus() - obj = bus.get_object(CHANNEL_DISPATCHER, self.dispatch_operation_path) - dispatch_operation = dbus.Interface(obj, CHANNEL_DISPATCH_OPERATION) - dispatch_operation.HandleWith(self._handler, - reply_handler=self.__handle_with_reply_cb, - error_handler=self.__handle_with_reply_cb) + bus = dbus.SessionBus() + bus.add_signal_receiver(self._name_owner_changed_cb, + 'NameOwnerChanged', + 'org.freedesktop.DBus', + arg0=self._handler) - def __handle_with_reply_cb(self, error=None): - if error is not None: - raise error - else: - logging.debug('__handle_with_reply_cb') + model = neighborhood.get_model() + activity_id = model.get_activity_by_room(self._handle).activity_id + misc.launch(bundle, color=self.get_color(), invited=True, + activity_id=activity_id) + + +class PrivateInvite(BaseInvite): + def __init__(self, dispatch_operation_path, handle, handler, + private_channel): + BaseInvite.__init__(self, dispatch_operation_path, handle, handler) + + self._private_channel = private_channel + + def get_color(self): + client = gconf.client_get_default() + return XoColor(client.get_string('/desktop/sugar/user/color')) + + def join(self): + logging.error('PrivateInvite.join handler %r', self._handler) + registry = bundleregistry.get_registry() + bundle_id = self.get_bundle_id() + bundle = registry.get_bundle(bundle_id) + + bus = dbus.SessionBus() + bus.add_signal_receiver(self._name_owner_changed_cb, + 'NameOwnerChanged', + 'org.freedesktop.DBus', + arg0=self._handler) + misc.launch(bundle, color=self.get_color(), invited=True, + uri=self._private_channel) class Invites(gobject.GObject): @@ -153,11 +185,15 @@ class Invites(gobject.GObject): error_handler=partial(self.__error_handler_cb, handle, channel_properties, - dispatch_operation_path)) + dispatch_operation_path, + channel_path, + properties)) else: - self._dispatch_non_sugar_invitation(channel_path, + self._dispatch_non_sugar_invitation(handle, channel_properties, - dispatch_operation_path) + dispatch_operation_path, + channel_path, + properties) def __get_properties_cb(self, handle, dispatch_operation_path, properties): logging.debug('__get_properties_cb %r', properties) @@ -165,39 +201,39 @@ class Invites(gobject.GObject): self._add_invite(dispatch_operation_path, handle, handler, properties) def __error_handler_cb(self, handle, channel_properties, - dispatch_operation_path, error): + dispatch_operation_path, channel_path, + properties, error): logging.debug('__error_handler_cb %r', error) exception_name = 'org.freedesktop.Telepathy.Error.NotAvailable' if error.get_dbus_name() == exception_name: self._dispatch_non_sugar_invitation(handle, channel_properties, - dispatch_operation_path) + dispatch_operation_path, + channel_path, + properties) else: raise error def _dispatch_non_sugar_invitation(self, handle, channel_properties, - dispatch_operation_path): + dispatch_operation_path, channel_path, + properties): handler = None channel_type = channel_properties[CHANNEL + '.ChannelType'] if channel_type == CHANNEL_TYPE_CONTACT_LIST: self._handle_with(dispatch_operation_path, CLIENT + '.Sugar') elif channel_type == CHANNEL_TYPE_TEXT: handler = CLIENT + '.org.laptop.Chat' - elif channel_type == CHANNEL_TYPE_STREAMED_MEDIA: - handler = CLIENT + '.org.laptop.VideoChat' - elif channel_type == CHANNEL_TYPE_DBUS_TUBE: - handler = channel_properties[CHANNEL_TYPE_DBUS_TUBE + - '.ServiceName'] - elif channel_type == CHANNEL_TYPE_STREAM_TUBE: - handler = channel_properties[CHANNEL_TYPE_STREAM_TUBE + '.Service'] + self._add_private_invite(dispatch_operation_path, handle, handler, + channel_path, properties) + return else: - self._handle_with(dispatch_operation_path, '') + self._call_handle_with(dispatch_operation_path, '') if handler is not None: logging.debug('Adding an invite from a non-Sugar client') self._add_invite(dispatch_operation_path, handle, handler) - def _handle_with(self, dispatch_operation_path, handler): + def _call_handle_with(self, dispatch_operation_path, handler): logging.debug('_handle_with %r %r', dispatch_operation_path, handler) bus = dbus.Bus() obj = bus.get_object(CHANNEL_DISPATCHER, dispatch_operation_path) @@ -226,6 +262,18 @@ class Invites(gobject.GObject): self._dispatch_operations[dispatch_operation_path] = invite self.emit('invite-added', invite) + def _add_private_invite(self, dispatch_operation_path, handle, handler, + channel_path, properties): + connection_path = properties[CHANNEL_DISPATCH_OPERATION + + '.Connection'] + connection_name = connection_path.replace('/', '.')[1:] + private_channel = simplejson.dumps([connection_name, + connection_path, channel_path]) + invite = PrivateInvite(dispatch_operation_path, handle, handler, + private_channel) + self._dispatch_operations[dispatch_operation_path] = invite + self.emit('invite-added', invite) + def remove_invite(self, invite): del self._dispatch_operations[invite.dispatch_operation_path] self.emit('invite-removed', invite) diff --git a/src/jarabe/model/telepathyclient.py b/src/jarabe/model/telepathyclient.py index c5a1f9f..2604af6 100644 --- a/src/jarabe/model/telepathyclient.py +++ b/src/jarabe/model/telepathyclient.py @@ -27,6 +27,7 @@ from telepathy.interfaces import CLIENT, \ from telepathy.server import DBusProperties from telepathy.constants import CONNECTION_HANDLE_TYPE_ROOM +from telepathy.constants import CONNECTION_HANDLE_TYPE_CONTACT from sugar import dispatch @@ -67,13 +68,20 @@ class TelepathyClient(dbus.service.Object, DBusProperties): return dbus.Array([filter_dict], signature='a{sv}') def __get_filters_approver_cb(self): - filt = { + activity_invitation = { CHANNEL + '.ChannelType': CHANNEL_TYPE_TEXT, CHANNEL + '.TargetHandleType': CONNECTION_HANDLE_TYPE_ROOM, } - filter_dict = dbus.Dictionary(filt, signature='sv') + filter_dict = dbus.Dictionary(activity_invitation, signature='sv') filters = dbus.Array([filter_dict], signature='a{sv}') + text_invitation = { + CHANNEL + '.ChannelType': CHANNEL_TYPE_TEXT, + CHANNEL + '.TargetHandleType': CONNECTION_HANDLE_TYPE_CONTACT, + } + filter_dict = dbus.Dictionary(text_invitation, signature='sv') + filters.append(filter_dict) + logging.debug('__get_filters_approver_cb %r', filters) return filters -- cgit v0.9.1