Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Schampijer <simon@schampijer.de>2011-06-09 14:51:28 (GMT)
committer Simon Schampijer <simon@schampijer.de>2011-06-09 15:00:50 (GMT)
commitd8090ced1d14d7059d2d2a09cee6a9955cac9bb3 (patch)
treea6acfaceb132bada33808324da4e04946e63905a
parent8e5e6c34b015ecab6785f1cc1a3c5ea0019053a7 (diff)
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 <simon@laptop.org> Acked-By: Sascha Silbe <silbe@activitycentral.com>
-rw-r--r--src/jarabe/model/invites.py160
-rw-r--r--src/jarabe/model/telepathyclient.py12
2 files changed, 114 insertions, 58 deletions
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