Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu.vizoso@collabora.co.uk>2010-06-17 16:16:06 (GMT)
committer Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>2010-08-20 13:02:26 (GMT)
commitcfca468c96db48b03411f202804357578093aca7 (patch)
tree51bad8cc9e3966bfca5eadb58bee43e8775253b0
parented08f043708a46a82bf8aa48d502c41b628f336e (diff)
Split some functionality into _Account out from Neighborhood and
go back to use the Sugar-specific telepathy specs.
-rw-r--r--src/jarabe/model/buddy.py2
-rw-r--r--src/jarabe/model/invites.py4
-rw-r--r--src/jarabe/model/neighborhood.py620
3 files changed, 347 insertions, 279 deletions
diff --git a/src/jarabe/model/buddy.py b/src/jarabe/model/buddy.py
index 15a338d..e20f947 100644
--- a/src/jarabe/model/buddy.py
+++ b/src/jarabe/model/buddy.py
@@ -14,6 +14,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import logging
+
import gobject
import gconf
diff --git a/src/jarabe/model/invites.py b/src/jarabe/model/invites.py
index abe6d39..f828241 100644
--- a/src/jarabe/model/invites.py
+++ b/src/jarabe/model/invites.py
@@ -42,6 +42,8 @@ class ActivityInvite(object):
return self._handler[len(CLIENT + '.'):]
def join(self):
+ logging.error('ActivityInvite.join handler %r', self._handler)
+
bus = dbus.Bus()
obj = bus.get_object(CHANNEL_DISPATCHER, self._dispatch_operation_path)
dispatch_operation = dbus.Interface(obj, CHANNEL_DISPATCH_OPERATION)
@@ -51,7 +53,7 @@ class ActivityInvite(object):
def __handle_with_reply_cb(self, error=None):
if error is not None:
- logging.error('__handle_with_reply_cb %r', error)
+ raise error
else:
logging.debug('__handle_with_reply_cb')
diff --git a/src/jarabe/model/neighborhood.py b/src/jarabe/model/neighborhood.py
index 129870c..0bb67e3 100644
--- a/src/jarabe/model/neighborhood.py
+++ b/src/jarabe/model/neighborhood.py
@@ -1,4 +1,3 @@
-# Copyright (C) 2006-2007 Red Hat, Inc.
# Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
#
# This program is free software; you can redistribute it and/or modify
@@ -37,6 +36,7 @@ from telepathy.interfaces import ACCOUNT, \
CONNECTION, \
CONNECTION_INTERFACE_ALIASING, \
CONNECTION_INTERFACE_CONTACTS, \
+ CONNECTION_INTERFACE_REQUESTS, \
CONNECTION_INTERFACE_SIMPLE_PRESENCE
from telepathy.constants import HANDLE_TYPE_LIST, \
CONNECTION_PRESENCE_TYPE_OFFLINE
@@ -46,7 +46,6 @@ from sugar.graphics.xocolor import XoColor
from sugar import activity
from jarabe.model.buddy import BuddyModel, OwnerBuddyModel
-from jarabe.model import telepathyclient
from jarabe.model import bundleregistry
ACCOUNT_MANAGER_SERVICE = 'org.freedesktop.Telepathy.AccountManager'
@@ -56,120 +55,328 @@ CHANNEL_DISPATCHER_PATH = '/org/freedesktop/Telepathy/ChannelDispatcher'
SUGAR_CLIENT_SERVICE = 'org.freedesktop.Telepathy.Client.Sugar'
SUGAR_CLIENT_PATH = '/org/freedesktop/Telepathy/Client/Sugar'
-CONNECTION_INTERFACE_APPLICATIONS = CONNECTION + '.Interface.Applications.DRAFT'
+CONNECTION_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo'
+CONNECTION_INTERFACE_ACTIVITY_PROPERTIES = 'org.laptop.Telepathy.ActivityProperties'
+
+class ActivityModel(gobject.GObject):
+ def __init__(self, activity_id, room_handle):
+ gobject.GObject.__init__(self)
-class ActivityModel(object):
- def __init__(self, bundle, activity_id, channel_type, handle_type, connection):
- self.bundle = bundle
self.activity_id = activity_id
- self._channel_type = channel_type
- self._handle_type = handle_type
- self._connection = connection
+ self.room_handle = room_handle
+ self._bundle = None
+ self._color = None
def get_color(self):
- logging.info('KILL_PS get the initiator''s colors')
- return None
+ return self._color
- def _find_account(self):
- bus = dbus.Bus()
- obj = bus.get_object(ACCOUNT_MANAGER_SERVICE, ACCOUNT_MANAGER_PATH)
- account_manager = dbus.Interface(obj, ACCOUNT_MANAGER)
+ def set_color(self, color):
+ self._color = color
- accounts = account_manager.Get(ACCOUNT_MANAGER, 'ValidAccounts',
- dbus_interface=PROPERTIES_IFACE)
- for account_path in accounts:
- obj = bus.get_object(ACCOUNT_MANAGER_SERVICE, account_path)
- account = dbus.Interface(obj, ACCOUNT)
- connection = account.Get(ACCOUNT, 'Connection',
- dbus_interface=PROPERTIES_IFACE)
- if connection == self._connection.object_path:
- return account_path
+ color = gobject.property(type=object, getter=get_color, setter=set_color)
- return None
+ def get_bundle(self):
+ return self._bundle
+
+ def set_bundle(self, bundle):
+ self._bundle = bundle
+
+ bundle = gobject.property(type=object, getter=get_bundle, setter=set_bundle)
+
+ def get_name(self):
+ return self._name
+
+ def set_name(self, name):
+ self._name = name
+
+ name = gobject.property(type=object, getter=get_name, setter=set_name)
def join(self):
- account_path = self._find_account()
- service_name = CLIENT + '.' + self.bundle.get_bundle_id()
+ pass
+
+class _Account(gobject.GObject):
+ __gsignals__ = {
+ 'activity-added': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object, object, object])),
+ 'activity-updated': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object, object])),
+ 'activity-removed': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object])),
+ 'buddy-added': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object])),
+ 'buddy-updated': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object, object])),
+ 'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([object]))
+ }
+
+ def __init__(self, account_path):
+ gobject.GObject.__init__(self)
+
+ self._connection = None
+ self._buddy_handles = {}
+ self._activity_handles = {}
+
+ self._buddies_per_activity = {}
+ self._activities_per_buddy = {}
bus = dbus.Bus()
- obj = bus.get_object(CHANNEL_DISPATCHER_SERVICE, CHANNEL_DISPATCHER_PATH)
- channel_dispatcher = dbus.Interface(obj, CHANNEL_DISPATCHER)
+ obj = bus.get_object(ACCOUNT_MANAGER_SERVICE, account_path)
+ obj.Get(ACCOUNT, 'Connection',
+ reply_handler=self.__got_connection_cb,
+ error_handler=self.__error_handler_cb)
+ obj.connect_to_signal(
+ 'AccountPropertyChanged', self.__account_property_changed_cb)
- properties = {
- CHANNEL + '.ChannelType': self._channel_type,
- CHANNEL + '.TargetHandleType': self._handle_type,
- CHANNEL + '.TargetID': self.activity_id,
- }
- request_path = channel_dispatcher.EnsureChannel(account_path,
- properties, 0,
- service_name)
- obj = bus.get_object(CHANNEL_DISPATCHER_SERVICE, request_path)
- request = dbus.Interface(obj, CHANNEL_REQUEST)
- #request.connect_to_signal('Failed', self.__channel_request_failed_cb)
- #request.connect_to_signal('Succeeded', self.__channel_request_succeeded_cb)
- request.Proceed()
+ def __error_handler_cb(self, error):
+ raise RuntimeError(error)
+
+ def __got_connection_cb(self, connection_path):
+ logging.debug('__got_connection_cb %r', connection_path)
+
+ if connection_path == '/':
+ return
+
+ self._prepare_connection(connection_path)
+
+ def __account_property_changed_cb(self, properties):
+ if properties.get('Connection', '/') != '/' and self._connection is None:
+ self._prepare_connection(properties['Connection'])
+
+ def _prepare_connection(self, connection_path):
+ connection_name = connection_path.replace('/', '.')[1:]
+
+ self._connection = Connection(connection_name, connection_path,
+ ready_handler=self.__connection_ready_cb)
+
+ def __connection_ready_cb(self, connection):
+ logging.debug('__connection_ready_cb %r', connection)
+
+ connection[CONNECTION_INTERFACE_ALIASING].connect_to_signal(
+ 'AliasesChanged', self.__aliases_changed_cb)
+
+ connection[CONNECTION_INTERFACE_SIMPLE_PRESENCE].connect_to_signal(
+ 'PresencesChanged', self.__presences_changed_cb)
+
+ if CONNECTION_INTERFACE_BUDDY_INFO in connection:
+ connection[CONNECTION_INTERFACE_BUDDY_INFO].connect_to_signal(
+ 'PropertiesChanged', self.__buddy_info_updated_cb,
+ byte_arrays=True)
+
+ connection[CONNECTION_INTERFACE_BUDDY_INFO].connect_to_signal(
+ 'ActivitiesChanged', self.__buddy_activities_changed_cb)
+ else:
+ logging.warning('Connection %s does not support OLPC buddy '
+ 'properties', connection.object_path)
+
+ if CONNECTION_INTERFACE_ACTIVITY_PROPERTIES in connection:
+ connection[CONNECTION_INTERFACE_ACTIVITY_PROPERTIES].connect_to_signal(
+ 'ActivityPropertiesChanged',
+ self.__activity_properties_changed_cb)
+ else:
+ logging.warning('Connection %s does not support OLPC activity '
+ 'properties', connection.object_path)
+
+ for target_id in 'subscribe', 'publish':
+ properties = {
+ CHANNEL + '.ChannelType': CHANNEL_TYPE_CONTACT_LIST,
+ CHANNEL + '.TargetHandleType': HANDLE_TYPE_LIST,
+ CHANNEL + '.TargetID': target_id,
+ }
+ is_ours, channel_path, properties = \
+ connection[CONNECTION_INTERFACE_REQUESTS].EnsureChannel(
+ dbus.Dictionary(properties, signature='sv'))
+ print is_ours, channel_path
+
+ channel = Channel(connection.service_name, channel_path)
+ channel[CHANNEL_INTERFACE_GROUP].connect_to_signal(
+ 'MembersChanged', self.__members_changed_cb)
+
+ channel = Channel(connection.service_name, channel_path)
+ channel[PROPERTIES_IFACE].Get(CHANNEL_INTERFACE_GROUP,
+ 'Members',
+ reply_handler=self.__get_members_ready_cb,
+ error_handler=self.__error_handler_cb)
+
+ def __aliases_changed_cb(self, aliases):
+ logging.debug('__aliases_changed_cb')
+ for handle, alias in aliases:
+ if handle in self._buddy_handles:
+ logging.debug('Got handle %r with nick %r, going to update', handle, alias)
+
+ def __presences_changed_cb(self, presences):
+ logging.debug('__presences_changed_cb %r', presences)
+ for handle, presence in presences.iteritems():
+ if handle in self._buddy_handles:
+ presence_type, status_, message_ = presence
+ if presence_type == CONNECTION_PRESENCE_TYPE_OFFLINE:
+ del self._buddy_handles[handle]
+ self.emit('buddy-removed', handle)
+
+ def __buddy_info_updated_cb(self, handle, properties):
+ logging.debug('__buddy_info_updated_cb %r %r', handle, properties)
+
+ def __buddy_activities_changed_cb(self, buddy_handle, activities):
+ logging.debug('__buddy_activities_changed_cb %r %r', buddy_handle, activities)
+ self._update_buddy_activities(buddy_handle, activities)
+
+ def _update_buddy_activities(self, buddy_handle, activities):
+ contact_id = self._buddy_handles[buddy_handle]
+ for activity_id, room_handle in activities:
+ if room_handle not in self._activity_handles:
+ self._activity_handles[room_handle] = activity_id
+ self.emit('activity-added', contact_id, room_handle, activity_id)
+
+ if not activity_id in self._buddies_per_activity:
+ self._buddies_per_activity[activity_id] = set()
+ self._buddies_per_activity[activity_id].add(contact_id)
+ self._activities_per_buddy[contact_id].add(activity_id)
+
+ current_activity_ids = [activity_id for activity_id, room_handle in activities]
+ for activity_id in self._activities_per_buddy[contact_id]:
+ if not activity_id in current_activity_ids:
+ self._buddies_per_activity[activity_id].remove(contact_id)
+ self.emit('activity-removed', activity_id)
+
+ def __activity_properties_changed_cb(self, room_handle, properties):
+ logging.debug('__activity_properties_changed_cb %r %r', room_handle, properties)
+ if room_handle in self._activity_handles:
+ self.emit('activity-updated', self._activity_handles[room_handle],
+ properties)
+ else:
+ logging.debug('__activity_properties_changed_cb unknown activity')
+
+ def __members_changed_cb(self, message, added, removed, local_pending,
+ remote_pending, actor, reason):
+ self._add_handles(added)
+
+ def __get_members_ready_cb(self, handles):
+ logging.debug('__get_members_ready_cb %r', handles)
+ if not handles:
+ return
+
+ self._add_handles(handles)
+
+ """
+ if CONNECTION_INTERFACE_APPLICATIONS in connection:
+ connection[CONNECTION_INTERFACE_APPLICATIONS].GetApplications(
+ handles,
+ reply_handler=partial(self.__get_applications_ready_cb, connection),
+ error_handler=self.__error_handler_cb)
+ """
+
+ def _add_handles(self, handles):
+ logging.debug('_add_handles %r', handles)
+ interfaces = [CONNECTION, CONNECTION_INTERFACE_ALIASING]
+ self._connection[CONNECTION_INTERFACE_CONTACTS].GetContactAttributes(
+ handles, interfaces, False,
+ reply_handler=self.__get_contact_attributes_cb,
+ error_handler=self.__error_handler_cb)
+
+ if CONNECTION_INTERFACE_BUDDY_INFO not in self._connection:
+ return
+
+ for handle in handles:
+ self._connection[CONNECTION_INTERFACE_BUDDY_INFO].GetProperties(
+ handle,
+ reply_handler=partial(self.__got_buddy_info_cb, handle),
+ error_handler=self.__error_handler_cb,
+ byte_arrays=True)
+
+ self._connection[CONNECTION_INTERFACE_BUDDY_INFO].GetActivities(
+ handle,
+ reply_handler=partial(self.__got_activities_cb, handle),
+ error_handler=self.__error_handler_cb)
+
+ def __got_buddy_info_cb(self, handle, properties):
+ logging.debug('__got_buddy_info_cb %r', properties)
+ self.emit('buddy-updated', self._buddy_handles[handle], properties)
+
+ def __get_contact_attributes_cb(self, attributes):
+ logging.debug('__get_contact_attributes_cb')
+
+ for handle in attributes.keys():
+ nick = attributes[handle][CONNECTION_INTERFACE_ALIASING + '/alias']
+ if handle in self._buddy_handles:
+ logging.debug('Got handle %r with nick %r, going to update', handle, nick)
+ self.emit('buddy-updated', self._buddy_handles[handle], attributes[handle])
+ else:
+ logging.debug('Got handle %r with nick %r, going to add', handle, nick)
+ contact_id = attributes[handle][CONNECTION + '/contact-id']
+ self._buddy_handles[handle] = contact_id
+ self._activities_per_buddy[contact_id] = set()
+ self.emit('buddy-added', attributes[handle])
+
+ def __got_activities_cb(self, buddy_handle, activities):
+ logging.debug('__got_activities_cb %r %r', buddy_handle, activities)
+ self._update_buddy_activities(buddy_handle, activities)
class Neighborhood(gobject.GObject):
__gsignals__ = {
'activity-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
+ gobject.TYPE_NONE, ([object])),
'activity-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
+ gobject.TYPE_NONE, ([object])),
'buddy-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
+ gobject.TYPE_NONE, ([object])),
'buddy-moved': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT])),
+ ([object,
+ object])),
'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT]))
+ gobject.TYPE_NONE, ([object]))
}
def __init__(self):
gobject.GObject.__init__(self)
- self._activities = {}
self._buddies = {None: OwnerBuddyModel()}
+ self._activities = {}
+ self._accounts = []
+ self._create_accounts()
+ def _create_accounts(self):
bus = dbus.Bus()
obj = bus.get_object(ACCOUNT_MANAGER_SERVICE, ACCOUNT_MANAGER_PATH)
account_manager = dbus.Interface(obj, ACCOUNT_MANAGER)
- accounts = account_manager.Get(ACCOUNT_MANAGER, 'ValidAccounts',
- dbus_interface=PROPERTIES_IFACE)
- logging.debug('accounts %r', accounts)
+ account_paths = account_manager.Get(ACCOUNT_MANAGER, 'ValidAccounts',
+ dbus_interface=PROPERTIES_IFACE)
- client_handler = telepathyclient.get_instance()
- client_handler.got_channel.connect(self.__got_channel_cb)
+ account_manager.connect_to_signal('AccountValidityChanged',
+ self.__account_validity_changed_cb)
- self._ensure_link_local_account(account_manager, accounts)
- self._ensure_server_account(account_manager, accounts)
+ self._ensure_link_local_account(account_manager, account_paths)
+ #self._ensure_server_account(account_manager, account_paths)
- for account in accounts:
- obj = bus.get_object(CHANNEL_DISPATCHER_SERVICE, CHANNEL_DISPATCHER_PATH)
- channel_dispatcher = dbus.Interface(obj, CHANNEL_DISPATCHER)
+ for account_path in account_paths:
+ self._add_account(account_path)
- properties = {
- CHANNEL + '.ChannelType': CHANNEL_TYPE_CONTACT_LIST,
- CHANNEL + '.TargetHandleType': HANDLE_TYPE_LIST,
- CHANNEL + '.TargetID': 'subscribe',
- }
- request_path = channel_dispatcher.EnsureChannel(account, properties, 0, SUGAR_CLIENT_SERVICE)
- obj = bus.get_object(CHANNEL_DISPATCHER_SERVICE, request_path)
- request = dbus.Interface(obj, CHANNEL_REQUEST)
- request.connect_to_signal('Failed', self.__channel_request_failed_cb)
- request.connect_to_signal('Succeeded', self.__channel_request_succeeded_cb)
- request.Proceed()
+ def __account_validity_changed_cb(self, account_path, valid):
+ if valid:
+ self._add_account(account_path)
+ else:
+ raise NotImplementedError('TODO')
- logging.debug('meec %r', request)
+ def _add_account(self, account_path):
+ account = _Account(account_path)
+ account.connect('buddy-added', self.__buddy_added_cb)
+ account.connect('buddy-updated', self.__buddy_updated_cb)
+ account.connect('activity-added', self.__activity_added_cb)
+ account.connect('activity-updated', self.__activity_updated_cb)
+ account.connect('activity-removed', self.__activity_removed_cb)
+ self._accounts.append(account)
def _ensure_link_local_account(self, account_manager, accounts):
# TODO: Is this the better way to check for an account?
for account in accounts:
if 'salut' in account:
+ logging.debug('Already have a Salut account')
return
+ logging.debug('Still dont have a Salut account, creating one')
+
client = gconf.client_get_default()
nick = client.get_string('/desktop/sugar/user/nick')
@@ -194,17 +401,25 @@ class Neighborhood(gobject.GObject):
def _ensure_server_account(self, account_manager, accounts):
# TODO: Is this the better way to check for an account?
for account in accounts:
- if 'jabber2' in account:
+ if 'gabble' in account:
+ logging.debug('Already have a Gabble account')
return
+ logging.debug('Still dont have a Gabble account, creating one')
+
client = gconf.client_get_default()
nick = client.get_string('/desktop/sugar/user/nick')
params = {
- 'account': '***',
+ 'account': '%s-mec@jabber2.sugarlabs.org' % nick,
'password': '***',
'server': 'jabber2.sugarlabs.org',
'resource': 'sugar',
+ 'require-encryption': True,
+ 'ignore-ssl-errors': True,
+ 'register': True,
+ 'old-ssl': True,
+ 'port': dbus.UInt32(5223),
}
properties = {
@@ -217,239 +432,88 @@ class Neighborhood(gobject.GObject):
'jabber', params, properties)
accounts.append(account)
- def __got_channel_cb(self, **kwargs):
- # TODO: How hacky is this?
- connection_name = kwargs['connection'].replace('/', '.')[1:]
+ def __buddy_added_cb(self, account, properties):
+ logging.debug('__buddy_added_cb %r', properties)
- channel_path = kwargs['channel'][0]
- Connection(connection_name, kwargs['connection'],
- ready_handler=partial(self.__connection_ready_cb, channel_path))
+ contact_id = properties[CONNECTION + '/contact-id']
- def __connection_ready_cb(self, channel_path, connection):
- connection[CONNECTION_INTERFACE_ALIASING].connect_to_signal(
- 'AliasesChanged',
- partial(self.__aliases_changed_cb, connection))
+ if contact_id in self._buddies:
+ logging.debug('__buddy_added_cb buddy already tracked')
+ return
- connection[CONNECTION_INTERFACE_SIMPLE_PRESENCE].connect_to_signal(
- 'PresencesChanged',
- partial(self.__presences_changed_cb, connection))
+ buddy = BuddyModel(
+ nick=properties[CONNECTION_INTERFACE_ALIASING + '/alias'])
+ self._buddies[contact_id] = buddy
- if CONNECTION_INTERFACE_APPLICATIONS in connection:
- connection[CONNECTION_INTERFACE_APPLICATIONS].connect_to_signal(
- 'ApplicationsUpdated',
- partial(self.__applications_updated_cb, connection))
-
- channel = Channel(connection.service_name, channel_path)
- channel[CHANNEL_INTERFACE_GROUP].connect_to_signal(
- 'MembersChanged',
- partial(self.__members_changed_cb, connection))
-
- channel[PROPERTIES_IFACE].Get(CHANNEL_INTERFACE_GROUP,
- 'Members',
- reply_handler=partial(self.__get_members_ready_cb, connection),
- error_handler=self.__error_handler_cb)
+ self.emit('buddy-added', buddy)
- def __get_members_ready_cb(self, connection, handles):
- if not handles:
+ def __buddy_updated_cb(self, account, contact_id, properties):
+ logging.debug('__buddy_updated_cb %r %r', contact_id, properties)
+ if contact_id not in self._buddies:
+ logging.debug('__buddy_updated_cb Unknown buddy with contact_id %r', contact_id)
return
- self._add_handles(connection, handles)
-
- if CONNECTION_INTERFACE_APPLICATIONS in connection:
- connection[CONNECTION_INTERFACE_APPLICATIONS].GetApplications(
- handles,
- reply_handler=partial(self.__get_applications_ready_cb, connection),
- error_handler=self.__error_handler_cb)
-
- def __presences_changed_cb(self, connection, presences):
- logging.debug('__presences_changed_cb %r', presences)
- for handle, presence in presences.iteritems():
- if (connection.service_name, handle) in self._buddies:
- presence_type, status_, message_ = presence
- if presence_type == CONNECTION_PRESENCE_TYPE_OFFLINE:
- buddy = self._buddies[(connection.service_name, handle)]
- del self._buddies[(connection.service_name, handle)]
- self.emit('buddy-removed', buddy)
+ buddy = self._buddies[contact_id]
+ if 'color' in properties:
+ buddy.props.color = XoColor(properties['color'])
+ if 'key' in properties:
+ buddy.props.key = properties['key']
- def __aliases_changed_cb(self, connection, aliases):
- logging.debug('__aliases_changed_cb')
- for handle, alias in aliases:
- if (connection.service_name, handle) in self._buddies:
- logging.debug('Got handle %r with nick %r, going to update', handle, alias)
- buddy = self._buddies[(connection.service_name, handle)]
- buddy.props.nick = alias
- buddy.props.key = (connection.service_name, handle)
-
- def __get_applications_ready_cb(self, connection, applications_per_contact):
- logging.debug('__get_applications_ready_cb %r %r', connection, applications_per_contact)
- for handle, applications in applications_per_contact.iteritems():
- self._add_applications(connection, handle, applications)
-
- def __applications_updated_cb(self, connection, handle, applications):
- self._add_applications(connection, handle, applications)
-
- def _add_applications(self, connection, contact_handle, applications):
- logging.debug('_add_applications %r %r', contact_handle, applications)
- for application in applications:
- channel_type, handle_type, activity_id, service_name = application
-
- # TODO: refactor it so it doesn't duplicates what is in invites.py
- if channel_type == CHANNEL_TYPE_TEXT:
- bundle_id = 'org.laptop.Chat'
- elif channel_type == CHANNEL_TYPE_STREAMED_MEDIA:
- bundle_id = 'org.laptop.VideoChat'
- elif channel_type == CHANNEL_TYPE_DBUS_TUBE:
- bundle_id = channel_properties[CHANNEL_TYPE_DBUS_TUBE + '.ServiceName']
- elif channel_type == CHANNEL_TYPE_STREAM_TUBE:
- bundle_id = channel_properties[CHANNEL_TYPE_STREAM_TUBE + '.Service']
- else:
- logging.warning('Ignoring unknown channel type: %s', channel_type)
- continue
+ def __activity_added_cb(self, account, contact_id, room_handle, activity_id):
+ if contact_id not in self._buddies:
+ logging.debug('__activity_added_cb Unknown buddy with contact_id %r', contact_id)
+ return
- if not activity_id:
- logging.warning('Ignoring malformed shared activity')
- continue
+ if activity_id in self._activities:
+ logging.debug('__activity_added_cb activity already tracked')
+ return
- if self.has_activity(activity_id):
- return
+ activity = ActivityModel(activity_id, room_handle)
+ self._activities[activity_id] = activity
- buddy = self._buddies.get((connection.service_name, contact_handle), None)
-
- if buddy is None:
- logging.warning('Ignoring activity of unknown owner: %r', contact_handle)
- continue
-
- registry = bundleregistry.get_registry()
- bundle = registry.get_bundle(bundle_id)
- if not bundle:
- logging.warning('Ignoring shared activity we don''t have')
- continue
-
- model = ActivityModel(bundle, activity_id, channel_type, handle_type, connection)
- self._activities[activity_id] = model
- self.emit('activity-added', model)
-
- logging.info('KILL_PS move buddies around')
- """
- for buddy in self._pservice.get_buddies():
- cur_activity = buddy.props.current_activity
- object_path = buddy.object_path()
- if cur_activity == activity and object_path in self._buddies:
- buddy_model = self._buddies[object_path]
- self.emit('buddy-moved', buddy_model, model)
- """
-
- def _add_handles(self, connection, handles):
- interfaces = [CONNECTION, CONNECTION_INTERFACE_ALIASING]
- connection[CONNECTION_INTERFACE_CONTACTS].GetContactAttributes(
- handles, interfaces, False,
- reply_handler=partial(self.__get_contact_attributes_cb, connection),
- error_handler=self.__error_handler_cb)
+ def __activity_updated_cb(self, account, activity_id, properties):
+ logging.debug('__activity_updated_cb %r %r', activity_id, properties)
+ if activity_id not in self._activities:
+ logging.debug('__activity_updated_cb Unknown activity with activity_id %r', activity_id)
+ return
- def __error_handler_cb(self, error):
- raise RuntimeError(error)
+ registry = bundleregistry.get_registry()
+ bundle = registry.get_bundle(properties['type'])
+ if not bundle:
+ logging.warning('Ignoring shared activity we don''t have')
+ return
- def __get_contact_attributes_cb(self, connection, attributes):
- logging.debug('__get_contact_attributes_cb')
+ activity = self._activities[activity_id]
- for handle in attributes.keys():
- nick = attributes[handle][CONNECTION_INTERFACE_ALIASING + '/alias']
- if (connection.service_name, handle) in self._buddies:
- logging.debug('Got handle %r with nick %r, going to update', handle, nick)
- buddy = self._buddies[(connection.service_name, handle)]
- buddy.props.nick = nick
- else:
- logging.debug('Got handle %r with nick %r, going to add', handle, nick)
- buddy = BuddyModel(nick=nick, key=(connection.service_name, handle))
- self._buddies[(connection.service_name, handle)] = buddy
- self.emit('buddy-added', buddy)
+ is_new = activity.props.bundle is None
- def __members_changed_cb(self, connection, message, added, removed,
- local_pending, remote_pending, actor, reason):
- self._add_handles(connection, added)
+ activity.props.color = XoColor(properties['color'])
+ activity.props.bundle = bundle
+ activity.props.name = properties['name']
- def __channel_request_failed_cb(self, error, message):
- raise RuntimeError('Couldn\'t retrieve contact list: %s %s', error, message)
+ if is_new:
+ self.emit('activity-added', activity)
- def __channel_request_succeeded_cb(self):
- logging.debug('Successfully ensured a ContactList channel')
+ def __activity_removed_cb(self, account, activity_id):
+ logging.debug('__activity_removed_cb %r', activity_id)
+ activity = self._activities[activity_id]
+ del self._activities[activity_id]
+ self.emit('activity-removed', activity)
def get_activities(self):
- return self._activities.values()
+ return []
def get_buddies(self):
return self._buddies.values()
- def _buddy_activity_changed_cb(self, model, cur_activity):
- if not self._buddies.has_key(model.get_buddy().object_path()):
- return
- if cur_activity and self._activities.has_key(cur_activity.props.id):
- activity_model = self._activities[cur_activity.props.id]
- self.emit('buddy-moved', model, activity_model)
- else:
- self.emit('buddy-moved', model, None)
-
- def __buddy_added_cb(self, **kwargs):
- self.emit('buddy-added', kwargs['buddy'])
-
- def _buddy_appeared_cb(self, pservice, buddy):
- if self._buddies.has_key(buddy.object_path()):
- return
-
- model = BuddyModel(buddy=buddy)
- model.connect('current-activity-changed',
- self._buddy_activity_changed_cb)
- self._buddies[buddy.object_path()] = model
- self.emit('buddy-added', model)
-
- cur_activity = buddy.props.current_activity
- if cur_activity:
- self._buddy_activity_changed_cb(model, cur_activity)
-
- def _buddy_disappeared_cb(self, pservice, buddy):
- if not self._buddies.has_key(buddy.object_path()):
- return
- self.emit('buddy-removed', self._buddies[buddy.object_path()])
- del self._buddies[buddy.object_path()]
-
- def _activity_appeared_cb(self, pservice, act):
- self._check_activity(act)
-
- def _check_activity(self, presence_activity):
- registry = bundleregistry.get_registry()
- bundle = registry.get_bundle(presence_activity.props.type)
- if not bundle:
- return
- if self.has_activity(presence_activity.props.id):
- return
- self.add_activity(bundle, presence_activity)
-
def has_activity(self, activity_id):
- return self._activities.has_key(activity_id)
+ return False
def get_activity(self, activity_id):
- if self.has_activity(activity_id):
- return self._activities[activity_id]
- else:
- return None
+ return None
def add_activity(self, bundle, act):
- model = ActivityModel(act, bundle)
- self._activities[model.get_id()] = model
- self.emit('activity-added', model)
-
- for buddy in self._pservice.get_buddies():
- cur_activity = buddy.props.current_activity
- object_path = buddy.object_path()
- if cur_activity == activity and object_path in self._buddies:
- buddy_model = self._buddies[object_path]
- self.emit('buddy-moved', buddy_model, model)
-
- def _activity_disappeared_cb(self, pservice, act):
- if self._activities.has_key(act.props.id):
- activity_model = self._activities[act.props.id]
- self.emit('activity-removed', activity_model)
- del self._activities[act.props.id]
+ pass
_model = None