Handle invitations using Mission Control 5.
src/sugar/activity/activity.py: If the activity is being invoked to handle an invite, create a Client.Handler instance and share the activity when HandleChannels is invoked. src/sugar/activity/activityfactory.py, src/sugar/activity/activityhandle.py, src/sugar/activity/main.py: Add a -i switch that indicates to the activity that it should handle the channel from an invitation. src/sugar/presence/activity.py: Expose Activity.room_handle. src/sugar/presence/presenceservice.py: Add get_activity_by_handle(). src/sugar/presence/util.py: Add get_account_for_connection().
This commit is contained in:
parent
af6e3aa5ef
commit
363f828205
@ -52,15 +52,25 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
import gconf
|
from functools import partial
|
||||||
|
|
||||||
|
import gconf
|
||||||
import gtk
|
import gtk
|
||||||
import gobject
|
import gobject
|
||||||
import dbus
|
import dbus
|
||||||
import dbus.service
|
import dbus.service
|
||||||
|
from dbus import PROPERTIES_IFACE
|
||||||
import cjson
|
import cjson
|
||||||
|
from telepathy.server import DBusProperties
|
||||||
|
from telepathy.interfaces import CONNECTION, \
|
||||||
|
CHANNEL, \
|
||||||
|
CHANNEL_TYPE_TEXT, \
|
||||||
|
CLIENT, \
|
||||||
|
CLIENT_HANDLER
|
||||||
|
from telepathy.constants import CONNECTION_HANDLE_TYPE_CONTACT
|
||||||
|
|
||||||
from sugar import util
|
from sugar import util
|
||||||
|
from sugar import dispatch
|
||||||
from sugar.presence import presenceservice
|
from sugar.presence import presenceservice
|
||||||
from sugar.activity.activityservice import ActivityService
|
from sugar.activity.activityservice import ActivityService
|
||||||
from sugar.activity.namingalert import NamingAlert
|
from sugar.activity.namingalert import NamingAlert
|
||||||
@ -88,6 +98,7 @@ J_DBUS_SERVICE = 'org.laptop.Journal'
|
|||||||
J_DBUS_PATH = '/org/laptop/Journal'
|
J_DBUS_PATH = '/org/laptop/Journal'
|
||||||
J_DBUS_INTERFACE = 'org.laptop.Journal'
|
J_DBUS_INTERFACE = 'org.laptop.Journal'
|
||||||
|
|
||||||
|
CONN_INTERFACE_ACTIVITY_PROPERTIES = 'org.laptop.Telepathy.ActivityProperties'
|
||||||
|
|
||||||
class _ActivitySession(gobject.GObject):
|
class _ActivitySession(gobject.GObject):
|
||||||
|
|
||||||
@ -300,10 +311,50 @@ class Activity(Window, gtk.Container):
|
|||||||
if self._jobject.metadata.has_key('share-scope'):
|
if self._jobject.metadata.has_key('share-scope'):
|
||||||
share_scope = self._jobject.metadata['share-scope']
|
share_scope = self._jobject.metadata['share-scope']
|
||||||
|
|
||||||
|
self.shared_activity = None
|
||||||
|
self._join_id = None
|
||||||
|
|
||||||
|
if handle.handle_invite:
|
||||||
|
wait_loop = gobject.MainLoop()
|
||||||
|
self._client_handler = _ClientHandler(
|
||||||
|
self.get_bundle_id(),
|
||||||
|
partial(self.__got_channel_cb, wait_loop))
|
||||||
|
# The current API requires that self.shared_activity is set before
|
||||||
|
# exiting from __init__, so we wait until we have got the shared
|
||||||
|
# activity.
|
||||||
|
wait_loop.run()
|
||||||
|
else:
|
||||||
|
pservice = presenceservice.get_instance()
|
||||||
|
mesh_instance = pservice.get_activity(self._activity_id,
|
||||||
|
warn_if_none=False)
|
||||||
|
self._set_up_sharing(mesh_instance, share_scope)
|
||||||
|
|
||||||
|
if handle.object_id is None and create_jobject:
|
||||||
|
logging.debug('Creating a jobject.')
|
||||||
|
self._jobject = datastore.create()
|
||||||
|
title = _('%s Activity') % get_bundle_name()
|
||||||
|
self._jobject.metadata['title'] = title
|
||||||
|
self.set_title(self._jobject.metadata['title'])
|
||||||
|
self._jobject.metadata['title_set_by_user'] = '0'
|
||||||
|
self._jobject.metadata['activity'] = self.get_bundle_id()
|
||||||
|
self._jobject.metadata['activity_id'] = self.get_id()
|
||||||
|
self._jobject.metadata['keep'] = '0'
|
||||||
|
self._jobject.metadata['preview'] = ''
|
||||||
|
self._jobject.metadata['share-scope'] = SCOPE_PRIVATE
|
||||||
|
if self.shared_activity is not None:
|
||||||
|
icon_color = self.shared_activity.props.color
|
||||||
|
else:
|
||||||
|
client = gconf.client_get_default()
|
||||||
|
icon_color = client.get_string('/desktop/sugar/user/color')
|
||||||
|
self._jobject.metadata['icon-color'] = icon_color
|
||||||
|
|
||||||
|
self._jobject.file_path = ''
|
||||||
|
# Cannot call datastore.write async for creates:
|
||||||
|
# https://dev.laptop.org/ticket/3071
|
||||||
|
datastore.write(self._jobject)
|
||||||
|
|
||||||
|
def _set_up_sharing(self, mesh_instance, share_scope):
|
||||||
# handle activity share/join
|
# handle activity share/join
|
||||||
pservice = presenceservice.get_instance()
|
|
||||||
mesh_instance = pservice.get_activity(self._activity_id,
|
|
||||||
warn_if_none=False)
|
|
||||||
logging.debug("*** Act %s, mesh instance %r, scope %s",
|
logging.debug("*** Act %s, mesh instance %r, scope %s",
|
||||||
self._activity_id, mesh_instance, share_scope)
|
self._activity_id, mesh_instance, share_scope)
|
||||||
if mesh_instance is not None:
|
if mesh_instance is not None:
|
||||||
@ -331,29 +382,19 @@ class Activity(Window, gtk.Container):
|
|||||||
else:
|
else:
|
||||||
logging.debug('Unknown share scope %r', share_scope)
|
logging.debug('Unknown share scope %r', share_scope)
|
||||||
|
|
||||||
if handle.object_id is None and create_jobject:
|
def __got_channel_cb(self, wait_loop, connection_path, channel_path):
|
||||||
logging.debug('Creating a jobject.')
|
logging.debug('Activity.__got_channel_cb')
|
||||||
self._jobject = datastore.create()
|
connection_name = connection_path.replace('/', '.')[1:]
|
||||||
title = _('%s Activity') % get_bundle_name()
|
|
||||||
self._jobject.metadata['title'] = title
|
|
||||||
self.set_title(self._jobject.metadata['title'])
|
|
||||||
self._jobject.metadata['title_set_by_user'] = '0'
|
|
||||||
self._jobject.metadata['activity'] = self.get_bundle_id()
|
|
||||||
self._jobject.metadata['activity_id'] = self.get_id()
|
|
||||||
self._jobject.metadata['keep'] = '0'
|
|
||||||
self._jobject.metadata['preview'] = ''
|
|
||||||
self._jobject.metadata['share-scope'] = SCOPE_PRIVATE
|
|
||||||
if self.shared_activity is not None:
|
|
||||||
icon_color = self.shared_activity.props.color
|
|
||||||
else:
|
|
||||||
client = gconf.client_get_default()
|
|
||||||
icon_color = client.get_string('/desktop/sugar/user/color')
|
|
||||||
self._jobject.metadata['icon-color'] = icon_color
|
|
||||||
|
|
||||||
self._jobject.file_path = ''
|
bus = dbus.SessionBus()
|
||||||
# Cannot call datastore.write async for creates:
|
channel = bus.get_object(connection_name, channel_path)
|
||||||
# https://dev.laptop.org/ticket/3071
|
room_handle = channel.Get(CHANNEL, 'TargetHandle')
|
||||||
datastore.write(self._jobject)
|
|
||||||
|
pservice = presenceservice.get_instance()
|
||||||
|
mesh_instance = pservice.get_activity_by_handle(connection_path,
|
||||||
|
room_handle)
|
||||||
|
self._set_up_sharing(mesh_instance, SCOPE_PRIVATE)
|
||||||
|
wait_loop.quit()
|
||||||
|
|
||||||
def get_active(self):
|
def get_active(self):
|
||||||
return self._active
|
return self._active
|
||||||
@ -646,6 +687,7 @@ class Activity(Window, gtk.Container):
|
|||||||
|
|
||||||
def __joined_cb(self, activity, success, err):
|
def __joined_cb(self, activity, success, err):
|
||||||
"""Callback when join has finished"""
|
"""Callback when join has finished"""
|
||||||
|
logging.debug('Activity.__joined_cb %r', success)
|
||||||
self.shared_activity.disconnect(self._join_id)
|
self.shared_activity.disconnect(self._join_id)
|
||||||
self._join_id = None
|
self._join_id = None
|
||||||
if not success:
|
if not success:
|
||||||
@ -854,6 +896,50 @@ class Activity(Window, gtk.Container):
|
|||||||
# DEPRECATED
|
# DEPRECATED
|
||||||
_shared_activity = property(lambda self: self.shared_activity, None)
|
_shared_activity = property(lambda self: self.shared_activity, None)
|
||||||
|
|
||||||
|
SUGAR_CLIENT_PATH = '/org/freedesktop/Telepathy/Client/Sugar'
|
||||||
|
|
||||||
|
class _ClientHandler(dbus.service.Object, DBusProperties):
|
||||||
|
def __init__(self, bundle_id, got_channel_cb):
|
||||||
|
self._interfaces = set([CLIENT, CLIENT_HANDLER, PROPERTIES_IFACE])
|
||||||
|
self._got_channel_cb = got_channel_cb
|
||||||
|
|
||||||
|
bus = dbus.Bus()
|
||||||
|
name = CLIENT + '.' + bundle_id
|
||||||
|
bus_name = dbus.service.BusName(name, bus=bus)
|
||||||
|
|
||||||
|
path = '/' + name.replace('.', '/')
|
||||||
|
dbus.service.Object.__init__(self, bus_name, path)
|
||||||
|
DBusProperties.__init__(self)
|
||||||
|
|
||||||
|
self._implement_property_get(CLIENT, {
|
||||||
|
'Interfaces': lambda: list(self._interfaces),
|
||||||
|
})
|
||||||
|
self._implement_property_get(CLIENT_HANDLER, {
|
||||||
|
'HandlerChannelFilter': self.__get_filters_cb,
|
||||||
|
})
|
||||||
|
|
||||||
|
def __get_filters_cb(self):
|
||||||
|
logging.debug('__get_filters_cb')
|
||||||
|
filters = {
|
||||||
|
CHANNEL + '.ChannelType' : CHANNEL_TYPE_TEXT,
|
||||||
|
CHANNEL + '.TargetHandleType': CONNECTION_HANDLE_TYPE_CONTACT,
|
||||||
|
}
|
||||||
|
filter_dict = dbus.Dictionary(filters, signature='sv')
|
||||||
|
logging.debug('__get_filters_cb %r', dbus.Array([filter_dict], signature='a{sv}'))
|
||||||
|
return dbus.Array([filter_dict], signature='a{sv}')
|
||||||
|
|
||||||
|
@dbus.service.method(dbus_interface=CLIENT_HANDLER,
|
||||||
|
in_signature='ooa(oa{sv})aota{sv}', out_signature='')
|
||||||
|
def HandleChannels(self, account, connection, channels, requests_satisfied,
|
||||||
|
user_action_time, handler_info):
|
||||||
|
logging.debug('HandleChannels\n\t%r\n\t%r\n\t%r\n\t%r\n\t%r\n\t%r',
|
||||||
|
account, connection, channels, requests_satisfied,
|
||||||
|
user_action_time, handler_info)
|
||||||
|
try:
|
||||||
|
for channel in channels:
|
||||||
|
self._got_channel_cb(connection, channel[0])
|
||||||
|
except Exception, e:
|
||||||
|
logging.exception(e)
|
||||||
|
|
||||||
_session = None
|
_session = None
|
||||||
|
|
||||||
|
@ -121,7 +121,8 @@ def get_environment(activity):
|
|||||||
return environ
|
return environ
|
||||||
|
|
||||||
|
|
||||||
def get_command(activity, activity_id=None, object_id=None, uri=None):
|
def get_command(activity, activity_id=None, object_id=None, uri=None,
|
||||||
|
activity_invite=False):
|
||||||
if not activity_id:
|
if not activity_id:
|
||||||
activity_id = create_activity_id()
|
activity_id = create_activity_id()
|
||||||
|
|
||||||
@ -133,6 +134,8 @@ def get_command(activity, activity_id=None, object_id=None, uri=None):
|
|||||||
command.extend(['-o', object_id])
|
command.extend(['-o', object_id])
|
||||||
if uri is not None:
|
if uri is not None:
|
||||||
command.extend(['-u', uri])
|
command.extend(['-u', uri])
|
||||||
|
if activity_invite:
|
||||||
|
command.append('-i')
|
||||||
|
|
||||||
# if the command is in $BUNDLE_ROOT/bin, execute the absolute path so there
|
# if the command is in $BUNDLE_ROOT/bin, execute the absolute path so there
|
||||||
# is no need to mangle with the shell's PATH
|
# is no need to mangle with the shell's PATH
|
||||||
@ -236,8 +239,8 @@ class ActivityCreationHandler(gobject.GObject):
|
|||||||
environ = get_environment(self._bundle)
|
environ = get_environment(self._bundle)
|
||||||
(log_path, log_file) = open_log_file(self._bundle)
|
(log_path, log_file) = open_log_file(self._bundle)
|
||||||
command = get_command(self._bundle, self._handle.activity_id,
|
command = get_command(self._bundle, self._handle.activity_id,
|
||||||
self._handle.object_id,
|
self._handle.object_id, self._handle.uri,
|
||||||
self._handle.uri)
|
self._handle.handle_invite)
|
||||||
|
|
||||||
dev_null = file('/dev/null', 'w')
|
dev_null = file('/dev/null', 'w')
|
||||||
environment_dir = None
|
environment_dir = None
|
||||||
|
@ -23,7 +23,8 @@ STABLE.
|
|||||||
class ActivityHandle(object):
|
class ActivityHandle(object):
|
||||||
"""Data structure storing simple activity metadata"""
|
"""Data structure storing simple activity metadata"""
|
||||||
|
|
||||||
def __init__(self, activity_id=None, object_id=None, uri=None):
|
def __init__(self, activity_id=None, object_id=None, uri=None,
|
||||||
|
handle_invite=False):
|
||||||
"""Initialise the handle from activity_id
|
"""Initialise the handle from activity_id
|
||||||
|
|
||||||
activity_id -- unique id for the activity to be
|
activity_id -- unique id for the activity to be
|
||||||
@ -45,14 +46,18 @@ class ActivityHandle(object):
|
|||||||
activity, rather than a journal object
|
activity, rather than a journal object
|
||||||
(downloads stored on the file system for
|
(downloads stored on the file system for
|
||||||
example or web pages)
|
example or web pages)
|
||||||
|
handle_invite -- the activity is being launched for handling an invite
|
||||||
|
from the network
|
||||||
"""
|
"""
|
||||||
self.activity_id = activity_id
|
self.activity_id = activity_id
|
||||||
self.object_id = object_id
|
self.object_id = object_id
|
||||||
self.uri = uri
|
self.uri = uri
|
||||||
|
self.handle_invite = handle_invite
|
||||||
|
|
||||||
def get_dict(self):
|
def get_dict(self):
|
||||||
"""Retrieve our settings as a dictionary"""
|
"""Retrieve our settings as a dictionary"""
|
||||||
result = {'activity_id': self.activity_id}
|
result = {'activity_id': self.activity_id,
|
||||||
|
'handle_invite': self.handle_invite}
|
||||||
if self.object_id:
|
if self.object_id:
|
||||||
result['object_id'] = self.object_id
|
result['object_id'] = self.object_id
|
||||||
if self.uri:
|
if self.uri:
|
||||||
@ -65,5 +70,6 @@ def create_from_dict(handle_dict):
|
|||||||
"""Create a handle from a dictionary of parameters"""
|
"""Create a handle from a dictionary of parameters"""
|
||||||
result = ActivityHandle(handle_dict['activity_id'],
|
result = ActivityHandle(handle_dict['activity_id'],
|
||||||
object_id = handle_dict.get('object_id'),
|
object_id = handle_dict.get('object_id'),
|
||||||
uri = handle_dict.get('uri'))
|
uri = handle_dict.get('uri'),
|
||||||
|
handle_invite = handle_dict.get('handle_invite'))
|
||||||
return result
|
return result
|
||||||
|
@ -75,6 +75,10 @@ def main():
|
|||||||
parser.add_option('-s', '--single-process', dest='single_process',
|
parser.add_option('-s', '--single-process', dest='single_process',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='start all the instances in the same process')
|
help='start all the instances in the same process')
|
||||||
|
parser.add_option('-i', '--handle-invite', dest='handle_invite',
|
||||||
|
action='store_true',
|
||||||
|
help='the activity is being launched for handling an '
|
||||||
|
'invite from the network')
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
logger.start()
|
logger.start()
|
||||||
@ -121,7 +125,8 @@ def main():
|
|||||||
activity_constructor = getattr(module, class_name)
|
activity_constructor = getattr(module, class_name)
|
||||||
activity_handle = activityhandle.ActivityHandle(
|
activity_handle = activityhandle.ActivityHandle(
|
||||||
activity_id=options.activity_id,
|
activity_id=options.activity_id,
|
||||||
object_id=options.object_id, uri=options.uri)
|
object_id=options.object_id, uri=options.uri,
|
||||||
|
handle_invite=options.handle_invite)
|
||||||
|
|
||||||
if options.single_process is True:
|
if options.single_process is True:
|
||||||
sessionbus = dbus.SessionBus()
|
sessionbus = dbus.SessionBus()
|
||||||
|
@ -94,7 +94,7 @@ class Activity(gobject.GObject):
|
|||||||
self.telepathy_text_chan = None
|
self.telepathy_text_chan = None
|
||||||
self.telepathy_tubes_chan = None
|
self.telepathy_tubes_chan = None
|
||||||
|
|
||||||
self._room_handle = room_handle
|
self.room_handle = room_handle
|
||||||
self._join_command = None
|
self._join_command = None
|
||||||
self._id = properties.get('id', None)
|
self._id = properties.get('id', None)
|
||||||
self._color = properties.get('color', None)
|
self._color = properties.get('color', None)
|
||||||
@ -111,7 +111,7 @@ class Activity(gobject.GObject):
|
|||||||
self._handle_to_buddy = {}
|
self._handle_to_buddy = {}
|
||||||
|
|
||||||
self._get_properties_call = None
|
self._get_properties_call = None
|
||||||
if not self._room_handle is None:
|
if not self.room_handle is None:
|
||||||
self._start_tracking_properties()
|
self._start_tracking_properties()
|
||||||
|
|
||||||
def _start_tracking_properties(self):
|
def _start_tracking_properties(self):
|
||||||
@ -122,7 +122,7 @@ class Activity(gobject.GObject):
|
|||||||
CONN_INTERFACE_ACTIVITY_PROPERTIES,
|
CONN_INTERFACE_ACTIVITY_PROPERTIES,
|
||||||
'GetProperties',
|
'GetProperties',
|
||||||
'u',
|
'u',
|
||||||
(self._room_handle,),
|
(self.room_handle,),
|
||||||
reply_handler=self.__got_properties_cb,
|
reply_handler=self.__got_properties_cb,
|
||||||
error_handler=self.__error_handler_cb,
|
error_handler=self.__error_handler_cb,
|
||||||
utf8_strings=True)
|
utf8_strings=True)
|
||||||
@ -364,12 +364,12 @@ class Activity(gobject.GObject):
|
|||||||
_logger.debug('%r: joining', self)
|
_logger.debug('%r: joining', self)
|
||||||
|
|
||||||
self._join_command = _JoinCommand(self.telepathy_conn,
|
self._join_command = _JoinCommand(self.telepathy_conn,
|
||||||
self._room_handle)
|
self.room_handle)
|
||||||
self._join_command.connect('finished', self.__joined_cb)
|
self._join_command.connect('finished', self.__joined_cb)
|
||||||
self._join_command.run()
|
self._join_command.run()
|
||||||
|
|
||||||
def share(self, share_activity_cb, share_activity_error_cb):
|
def share(self, share_activity_cb, share_activity_error_cb):
|
||||||
if not self._room_handle is None:
|
if not self.room_handle is None:
|
||||||
raise ValueError('Already have a room handle')
|
raise ValueError('Already have a room handle')
|
||||||
|
|
||||||
self._share_command = _ShareCommand(self.telepathy_conn, self._id)
|
self._share_command = _ShareCommand(self.telepathy_conn, self._id)
|
||||||
@ -384,7 +384,7 @@ class Activity(gobject.GObject):
|
|||||||
_logger.debug('%r: Share finished %r', self, error)
|
_logger.debug('%r: Share finished %r', self, error)
|
||||||
if error is None:
|
if error is None:
|
||||||
self._joined = True
|
self._joined = True
|
||||||
self._room_handle = share_command.room_handle
|
self.room_handle = share_command.room_handle
|
||||||
self.telepathy_text_chan = share_command.text_channel
|
self.telepathy_text_chan = share_command.text_channel
|
||||||
self.telepathy_tubes_chan = share_command.tubes_channel
|
self.telepathy_tubes_chan = share_command.tubes_channel
|
||||||
self._publish_properties()
|
self._publish_properties()
|
||||||
@ -410,7 +410,7 @@ class Activity(gobject.GObject):
|
|||||||
|
|
||||||
logging.debug('_publish_properties calling SetProperties %r', properties)
|
logging.debug('_publish_properties calling SetProperties %r', properties)
|
||||||
self.telepathy_conn.SetProperties(
|
self.telepathy_conn.SetProperties(
|
||||||
self._room_handle,
|
self.room_handle,
|
||||||
properties,
|
properties,
|
||||||
dbus_interface=CONN_INTERFACE_ACTIVITY_PROPERTIES)
|
dbus_interface=CONN_INTERFACE_ACTIVITY_PROPERTIES)
|
||||||
|
|
||||||
@ -528,7 +528,7 @@ class _JoinCommand(_BaseCommand):
|
|||||||
_BaseCommand.__init__(self)
|
_BaseCommand.__init__(self)
|
||||||
|
|
||||||
self._connection = connection
|
self._connection = connection
|
||||||
self._room_handle = room_handle
|
self.room_handle = room_handle
|
||||||
self._finished = False
|
self._finished = False
|
||||||
self._text_channel_group_flags = None
|
self._text_channel_group_flags = None
|
||||||
self.text_channel = None
|
self.text_channel = None
|
||||||
@ -539,13 +539,13 @@ class _JoinCommand(_BaseCommand):
|
|||||||
raise RuntimeError('This command has already finished')
|
raise RuntimeError('This command has already finished')
|
||||||
|
|
||||||
self._connection.RequestChannel(CHANNEL_TYPE_TEXT,
|
self._connection.RequestChannel(CHANNEL_TYPE_TEXT,
|
||||||
HANDLE_TYPE_ROOM, self._room_handle, True,
|
HANDLE_TYPE_ROOM, self.room_handle, True,
|
||||||
reply_handler=self.__create_text_channel_cb,
|
reply_handler=self.__create_text_channel_cb,
|
||||||
error_handler=self.__error_handler_cb,
|
error_handler=self.__error_handler_cb,
|
||||||
dbus_interface=CONNECTION)
|
dbus_interface=CONNECTION)
|
||||||
|
|
||||||
self._connection.RequestChannel(CHANNEL_TYPE_TUBES,
|
self._connection.RequestChannel(CHANNEL_TYPE_TUBES,
|
||||||
HANDLE_TYPE_ROOM, self._room_handle, True,
|
HANDLE_TYPE_ROOM, self.room_handle, True,
|
||||||
reply_handler=self.__create_tubes_channel_cb,
|
reply_handler=self.__create_tubes_channel_cb,
|
||||||
error_handler=self.__error_handler_cb,
|
error_handler=self.__error_handler_cb,
|
||||||
dbus_interface=CONNECTION)
|
dbus_interface=CONNECTION)
|
||||||
@ -636,7 +636,7 @@ class _JoinCommand(_BaseCommand):
|
|||||||
def __text_channel_members_changed_cb(self, message, added, removed,
|
def __text_channel_members_changed_cb(self, message, added, removed,
|
||||||
local_pending, remote_pending,
|
local_pending, remote_pending,
|
||||||
actor, reason):
|
actor, reason):
|
||||||
_logger.debug('__text_channel_members_changed_cb added %r removed %r local_pending %r remote_pending %r', added, removed, local_pending, remote_pending)
|
_logger.debug('__text_channel_members_changed_cb added %r removed %r local_pending %r remote_pending %r self_handle %r', added, removed, local_pending, remote_pending, self._self_handle)
|
||||||
if self._self_handle in added:
|
if self._self_handle in added:
|
||||||
logging.info('KILL_PS Set the channel properties')
|
logging.info('KILL_PS Set the channel properties')
|
||||||
self._finished = True
|
self._finished = True
|
||||||
@ -645,9 +645,9 @@ class _JoinCommand(_BaseCommand):
|
|||||||
return
|
return
|
||||||
|
|
||||||
#_logger.debug('Activity %r text channel %u currently has %r',
|
#_logger.debug('Activity %r text channel %u currently has %r',
|
||||||
# self, self._room_handle, self._handle_to_buddy)
|
# self, self.room_handle, self._handle_to_buddy)
|
||||||
_logger.debug('Text channel %u members changed: + %r, - %r, LP %r, '
|
_logger.debug('Text channel %u members changed: + %r, - %r, LP %r, '
|
||||||
'RP %r, message %r, actor %r, reason %r', self._room_handle,
|
'RP %r, message %r, actor %r, reason %r', self.room_handle,
|
||||||
added, removed, local_pending, remote_pending,
|
added, removed, local_pending, remote_pending,
|
||||||
message, actor, reason)
|
message, actor, reason)
|
||||||
# Note: D-Bus calls this with list arguments, but after GetMembers()
|
# Note: D-Bus calls this with list arguments, but after GetMembers()
|
||||||
|
@ -280,6 +280,24 @@ class PresenceService(gobject.GObject):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_activity_by_handle(self, connection_path, room_handle):
|
||||||
|
if self._activity_cache is not None:
|
||||||
|
if self._activity_cache.room_handle != room_handle:
|
||||||
|
raise RuntimeError('Activities can only access their own shared'
|
||||||
|
'instance')
|
||||||
|
return self._activity_cache
|
||||||
|
else:
|
||||||
|
connection_manager = get_connection_manager()
|
||||||
|
account_path = connection_manager.get_account_for_connection(connection_path)
|
||||||
|
|
||||||
|
connection_name = connection_path.replace('/', '.')[1:]
|
||||||
|
bus = dbus.SessionBus()
|
||||||
|
connection = bus.get_object(connection_name, connection_path)
|
||||||
|
activity = Activity(account_path, connection,
|
||||||
|
room_handle=room_handle)
|
||||||
|
self._activity_cache = activity
|
||||||
|
return activity
|
||||||
|
|
||||||
def get_buddies(self):
|
def get_buddies(self):
|
||||||
"""Retrieve set of all buddies from service
|
"""Retrieve set of all buddies from service
|
||||||
|
|
||||||
|
@ -50,6 +50,12 @@ class ConnectionManager(object):
|
|||||||
def get_connections_per_account(self):
|
def get_connections_per_account(self):
|
||||||
return self._connections_per_account
|
return self._connections_per_account
|
||||||
|
|
||||||
|
def get_account_for_connection(self, connection_path):
|
||||||
|
for account_path, connection in self._connections_per_account.items():
|
||||||
|
if connection.object_path == connection_path:
|
||||||
|
return account_path
|
||||||
|
return None
|
||||||
|
|
||||||
_connection_manager = None
|
_connection_manager = None
|
||||||
|
|
||||||
def get_connection_manager():
|
def get_connection_manager():
|
||||||
|
Loading…
Reference in New Issue
Block a user