Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/sugar/presence
diff options
context:
space:
mode:
Diffstat (limited to 'src/sugar/presence')
-rw-r--r--src/sugar/presence/Makefile.am9
-rw-r--r--src/sugar/presence/__init__.py24
-rw-r--r--src/sugar/presence/activity.py410
-rw-r--r--src/sugar/presence/buddy.py239
-rw-r--r--src/sugar/presence/presenceservice.py609
-rw-r--r--src/sugar/presence/sugartubeconn.py63
-rw-r--r--src/sugar/presence/test_presence.txt26
-rw-r--r--src/sugar/presence/tubeconn.py114
8 files changed, 0 insertions, 1494 deletions
diff --git a/src/sugar/presence/Makefile.am b/src/sugar/presence/Makefile.am
deleted file mode 100644
index 0c4368b..0000000
--- a/src/sugar/presence/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-sugardir = $(pythondir)/sugar/presence
-sugar_PYTHON = \
- __init__.py \
- activity.py \
- buddy.py \
- sugartubeconn.py \
- tubeconn.py \
- presenceservice.py
-
diff --git a/src/sugar/presence/__init__.py b/src/sugar/presence/__init__.py
deleted file mode 100644
index 1136c19..0000000
--- a/src/sugar/presence/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2006-2007, Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""Client-code's interface to the PresenceService
-
-Provides a simplified API for accessing the dbus service
-which coordinates native network presence and sharing
-information. This includes both "buddies" and "shared
-activities".
-"""
diff --git a/src/sugar/presence/activity.py b/src/sugar/presence/activity.py
deleted file mode 100644
index dc02aa1..0000000
--- a/src/sugar/presence/activity.py
+++ /dev/null
@@ -1,410 +0,0 @@
-# Copyright (C) 2007, Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""UI interface to an activity in the presence service
-
-STABLE.
-"""
-
-import logging
-
-import dbus
-import gobject
-import telepathy
-
-_logger = logging.getLogger('sugar.presence.activity')
-
-class Activity(gobject.GObject):
- """UI interface for an Activity in the presence service
-
- Activities in the presence service represent your and other user's
- shared activities.
-
- Properties:
- id
- color
- name
- type
- joined
- """
- __gsignals__ = {
- 'buddy-joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'buddy-left': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'new-channel': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])),
- }
-
- __gproperties__ = {
- 'id' : (str, None, None, None, gobject.PARAM_READABLE),
- 'name' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'tags' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'color' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'type' : (str, None, None, None, gobject.PARAM_READABLE),
- 'private' : (bool, None, None, True, gobject.PARAM_READWRITE),
- 'joined' : (bool, None, None, False, gobject.PARAM_READABLE),
- }
-
- _PRESENCE_SERVICE = "org.laptop.Sugar.Presence"
- _ACTIVITY_DBUS_INTERFACE = "org.laptop.Sugar.Presence.Activity"
-
- def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
- """Initialse the activity interface, connecting to service"""
- gobject.GObject.__init__(self)
- self._telepathy_room_handle = None
- self._object_path = object_path
- self._ps_new_object = new_obj_cb
- self._ps_del_object = del_obj_cb
- bobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
- self._activity = dbus.Interface(bobj, self._ACTIVITY_DBUS_INTERFACE)
- self._activity.connect_to_signal('BuddyHandleJoined',
- self._buddy_handle_joined_cb)
- self._activity.connect_to_signal('BuddyLeft',
- self._buddy_left_cb)
- self._activity.connect_to_signal('NewChannel', self._new_channel_cb)
- self._activity.connect_to_signal('PropertiesChanged',
- self._properties_changed_cb,
- utf8_strings=True)
- # FIXME: this *would* just use a normal proxy call, but I want the
- # pending call object so I can block on it, and normal proxy methods
- # don't return those as of dbus-python 0.82.1; so do it the hard way
- self._get_properties_call = bus.call_async(self._PRESENCE_SERVICE,
- object_path, self._ACTIVITY_DBUS_INTERFACE, 'GetProperties',
- '', (), self._get_properties_reply_cb,
- self._get_properties_error_cb, utf8_strings=True)
-
- self._id = None
- self._color = None
- self._name = None
- self._type = None
- self._tags = None
- self._private = True
- self._joined = False
- # Cache for get_buddy_by_handle, maps handles to buddy object paths
- self._handle_to_buddy_path = {}
- self._buddy_path_to_handle = {}
-
- # Set up by set_up_tubes()
- self.telepathy_conn = None
- self.telepathy_tubes_chan = None
- self.telepathy_text_chan = None
- self._telepathy_room = None
-
- def __repr__(self):
- return ('<proxy for %s at %x>' % (self._object_path, id(self)))
-
- def _get_properties_reply_cb(self, new_props):
- self._get_properties_call = None
- _logger.debug('%r: initial GetProperties returned', self)
- self._properties_changed_cb(new_props)
-
- def _get_properties_error_cb(self, e):
- self._get_properties_call = None
- # FIXME: do something with the error
- _logger.warning('%r: Error doing initial GetProperties: %s', self, e)
-
- def _properties_changed_cb(self, new_props):
- _logger.debug('%r: Activity properties changed to %r', self, new_props)
- val = new_props.get('name', self._name)
- if isinstance(val, str) and val != self._name:
- self._name = val
- self.notify('name')
- val = new_props.get('tags', self._tags)
- if isinstance(val, str) and val != self._tags:
- self._tags = val
- self.notify('tags')
- val = new_props.get('color', self._color)
- if isinstance(val, str) and val != self._color:
- self._color = val
- self.notify('color')
- val = bool(new_props.get('private', self._private))
- if val != self._private:
- self._private = val
- self.notify('private')
- val = new_props.get('id', self._id)
- if isinstance(val, str) and self._id is None:
- self._id = val
- self.notify('id')
- val = new_props.get('type', self._type)
- if isinstance(val, str) and self._type is None:
- self._type = val
- self.notify('type')
-
- def object_path(self):
- """Get our dbus object path"""
- return self._object_path
-
- def do_get_property(self, pspec):
- """Retrieve a particular property from our property dictionary"""
-
- if pspec.name == "joined":
- return self._joined
-
- if self._get_properties_call is not None:
- _logger.debug('%r: Blocking on GetProperties() because someone '
- 'wants property %s', self, pspec.name)
- self._get_properties_call.block()
-
- if pspec.name == "id":
- return self._id
- elif pspec.name == "name":
- return self._name
- elif pspec.name == "color":
- return self._color
- elif pspec.name == "type":
- return self._type
- elif pspec.name == "tags":
- return self._tags
- elif pspec.name == "private":
- return self._private
-
- # FIXME: need an asynchronous API to set these properties, particularly
- # 'private'
- def do_set_property(self, pspec, val):
- """Set a particular property in our property dictionary"""
- if pspec.name == "name":
- self._activity.SetProperties({'name': val})
- self._name = val
- elif pspec.name == "color":
- self._activity.SetProperties({'color': val})
- self._color = val
- elif pspec.name == "tags":
- self._activity.SetProperties({'tags': val})
- self._tags = val
- elif pspec.name == "private":
- self._activity.SetProperties({'private': val})
- self._private = val
-
- def set_private(self, val, reply_handler, error_handler):
- self._activity.SetProperties({'private': bool(val)},
- reply_handler=reply_handler,
- error_handler=error_handler)
-
- def _emit_buddy_joined_signal(self, object_path):
- """Generate buddy-joined GObject signal with presence Buddy object"""
- self.emit('buddy-joined', self._ps_new_object(object_path))
- return False
-
- def _buddy_handle_joined_cb(self, object_path, handle):
- _logger.debug('%r: buddy %s joined with handle %u', self, object_path,
- handle)
- gobject.idle_add(self._emit_buddy_joined_signal, object_path)
- self._handle_to_buddy_path[handle] = object_path
- self._buddy_path_to_handle[object_path] = handle
-
- def _emit_buddy_left_signal(self, object_path):
- """Generate buddy-left GObject signal with presence Buddy object
-
- XXX note use of _ps_new_object instead of _ps_del_object here
- """
- self.emit('buddy-left', self._ps_new_object(object_path))
- return False
-
- def _buddy_left_cb(self, object_path):
- _logger.debug('%r: buddy %s left', self, object_path)
- gobject.idle_add(self._emit_buddy_left_signal, object_path)
- handle = self._buddy_path_to_handle.pop(object_path, None)
- if handle:
- self._handle_to_buddy_path.pop(handle, None)
-
- def _emit_new_channel_signal(self, object_path):
- """Generate new-channel GObject signal with channel object path
-
- New telepathy-python communications channel has been opened
- """
- self.emit('new-channel', object_path)
- return False
-
- def _new_channel_cb(self, object_path):
- _logger.debug('%r: new channel created at %s', self, object_path)
- gobject.idle_add(self._emit_new_channel_signal, object_path)
-
- def get_joined_buddies(self):
- """Retrieve the set of Buddy objects attached to this activity
-
- returns list of presence Buddy objects that we can successfully
- create from the buddy object paths that PS has for this activity.
- """
- resp = self._activity.GetJoinedBuddies()
- buddies = []
- for item in resp:
- try:
- buddies.append(self._ps_new_object(item))
- except dbus.DBusException:
- _logger.debug(
- 'get_joined_buddies failed to get buddy object for %r',
- item)
- return buddies
-
- def get_buddy_by_handle(self, handle):
- """Retrieve the Buddy object given a telepathy handle.
-
- buddy object paths are cached in self._handle_to_buddy_path,
- so we can get the buddy without calling PS.
- """
- object_path = self._handle_to_buddy_path.get(handle, None)
- if object_path:
- buddy = self._ps_new_object(object_path)
- return buddy
- return None
-
- def invite(self, buddy, message, response_cb):
- """Invite the given buddy to join this activity.
-
- The callback will be called with one parameter: None on success,
- or an exception on failure.
- """
- op = buddy.object_path()
- _logger.debug('%r: inviting %s', self, op)
- self._activity.Invite(op, message,
- reply_handler=lambda: response_cb(None),
- error_handler=response_cb)
-
- # Joining and sharing (FIXME: sharing is actually done elsewhere)
-
- def set_up_tubes(self, reply_handler, error_handler):
-
- chans = []
-
- def tubes_ready():
- if self.telepathy_text_chan is None or \
- self.telepathy_tubes_chan is None:
- return
-
- _logger.debug('%r: finished setting up tubes', self)
- reply_handler()
-
- def tubes_chan_ready(chan):
- _logger.debug('%r: Tubes channel %r is ready', self, chan)
- self.telepathy_tubes_chan = chan
- tubes_ready()
-
- def text_chan_ready(chan):
- _logger.debug('%r: Text channel %r is ready', self, chan)
- self.telepathy_text_chan = chan
- tubes_ready()
-
- def conn_ready(conn):
- _logger.debug('%r: Connection %r is ready', self, conn)
- self.telepathy_conn = conn
- found_text_channel = False
- found_tubes_channel = False
-
- for chan_path, chan_iface, handle_type, handle_ in chans:
- if handle_type != telepathy.HANDLE_TYPE_ROOM:
- return
-
- if chan_iface == telepathy.CHANNEL_TYPE_TEXT:
- telepathy.client.Channel(
- conn.service_name, chan_path,
- ready_handler=text_chan_ready,
- error_handler=error_handler)
- found_text_channel = True
-
- elif chan_iface == telepathy.CHANNEL_TYPE_TUBES:
- telepathy.client.Channel(
- conn.service_name, chan_path,
- ready_handler=tubes_chan_ready,
- error_handler=error_handler)
- found_tubes_channel = True
-
- if not found_text_channel:
- error_handler(AssertionError("Presence Service didn't create "
- "a chatroom"))
- elif not found_tubes_channel:
- error_handler(AssertionError("Presence Service didn't create "
- "tubes channel"))
-
- def channels_listed(bus_name, conn_path, channels):
- _logger.debug('%r: Connection on %s at %s, channels: %r',
- self, bus_name, conn_path, channels)
-
- # can't use assignment for this due to Python scoping
- chans.extend(channels)
-
- telepathy.client.Connection(bus_name, conn_path,
- ready_handler=conn_ready,
- error_handler=error_handler)
-
-
- self._activity.ListChannels(reply_handler=channels_listed,
- error_handler=error_handler)
-
- def _join_cb(self):
- _logger.debug('%r: Join finished', self)
- self._joined = True
- self.emit("joined", True, None)
-
- def _join_error_cb(self, err):
- _logger.debug('%r: Join failed because: %s', self, err)
- self.emit("joined", False, str(err))
-
- def join(self):
- """Join this activity.
-
- Emits 'joined' and otherwise does nothing if we're already joined.
- """
- if self._joined:
- self.emit("joined", True, None)
- return
-
- _logger.debug('%r: joining', self)
-
- def joined():
- self.set_up_tubes(reply_handler=self._join_cb,
- error_handler=self._join_error_cb)
-
- self._activity.Join(reply_handler=joined,
- error_handler=self._join_error_cb)
-
- # GetChannels() wrapper
-
- def get_channels(self):
- """Retrieve communications channel descriptions for the activity
-
- Returns a tuple containing:
- - the D-Bus well-known service name of the connection
- (FIXME: this is redundant; in Telepathy it can be derived
- from that of the connection)
- - the D-Bus object path of the connection
- - a list of D-Bus object paths representing the channels
- associated with this activity
- """
- (bus_name, connection, channels) = self._activity.GetChannels()
- _logger.debug('%r: bus name is %s, connection is %s, channels are %r',
- self, bus_name, connection, channels)
- return bus_name, connection, channels
-
- # Leaving
-
- def _leave_cb(self):
- """Callback for async action of leaving shared activity."""
- self.emit("joined", False, "left activity")
-
- def _leave_error_cb(self, err):
- """Callback for error in async leaving of shared activity."""
- _logger.debug('Failed to leave activity: %s', err)
-
- def leave(self):
- """Leave this shared activity"""
- _logger.debug('%r: leaving', self)
- self._joined = False
- self._activity.Leave(reply_handler=self._leave_cb,
- error_handler=self._leave_error_cb)
diff --git a/src/sugar/presence/buddy.py b/src/sugar/presence/buddy.py
deleted file mode 100644
index fab23d2..0000000
--- a/src/sugar/presence/buddy.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# Copyright (C) 2007, Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""UI interface to a buddy in the presence service
-
-STABLE.
-"""
-
-import gobject
-import gtk
-import dbus
-
-class Buddy(gobject.GObject):
- """UI interface for a Buddy in the presence service
-
- Each buddy interface tracks a set of activities and properties
- that can be queried to provide UI controls for manipulating
- the presence interface.
-
- Properties Dictionary:
- 'key': public key,
- 'nick': nickname ,
- 'color': color (XXX what format),
- 'current-activity': (XXX dbus path?),
- 'owner': (XXX dbus path?),
- 'icon': (XXX pixel data for an icon?)
- See __gproperties__
- """
- __gsignals__ = {
- 'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([])),
- 'joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'property-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- }
-
- __gproperties__ = {
- 'key' : (str, None, None, None, gobject.PARAM_READABLE),
- 'icon' : (str, None, None, None, gobject.PARAM_READABLE),
- 'nick' : (str, None, None, None, gobject.PARAM_READABLE),
- 'color' : (str, None, None, None, gobject.PARAM_READABLE),
- 'current-activity' : (object, None, None, gobject.PARAM_READABLE),
- 'owner' : (bool, None, None, False, gobject.PARAM_READABLE),
- 'ip4-address' : (str, None, None, None, gobject.PARAM_READABLE)
- }
-
- _PRESENCE_SERVICE = "org.laptop.Sugar.Presence"
- _BUDDY_DBUS_INTERFACE = "org.laptop.Sugar.Presence.Buddy"
-
- def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
- """Initialise the reference to the buddy
-
- bus -- dbus bus object
- new_obj_cb -- callback to call when this buddy joins an activity
- del_obj_cb -- callback to call when this buddy leaves an activity
- object_path -- path to the buddy object
- """
- gobject.GObject.__init__(self)
- self._object_path = object_path
- self._ps_new_object = new_obj_cb
- self._ps_del_object = del_obj_cb
- self._properties = {}
- self._activities = {}
-
- bobj = bus.get_object(self._PRESENCE_SERVICE, object_path)
- self._buddy = dbus.Interface(bobj, self._BUDDY_DBUS_INTERFACE)
-
- self._icon_changed_signal = self._buddy.connect_to_signal(
- 'IconChanged', self._icon_changed_cb, byte_arrays=True)
- self._joined_activity_signal = self._buddy.connect_to_signal(
- 'JoinedActivity', self._joined_activity_cb)
- self._left_activity_signal = self._buddy.connect_to_signal(
- 'LeftActivity', self._left_activity_cb)
- self._property_changed_signal = self._buddy.connect_to_signal(
- 'PropertyChanged', self._property_changed_cb)
-
- self._properties = self._get_properties_helper()
-
- activities = self._buddy.GetJoinedActivities()
- for op in activities:
- self._activities[op] = self._ps_new_object(op)
- self._icon = None
-
- def destroy(self):
- self._icon_changed_signal.remove()
- self._joined_activity_signal.remove()
- self._left_activity_signal.remove()
- self._property_changed_signal.remove()
-
- def _get_properties_helper(self):
- """Retrieve the Buddy's property dictionary from the service object
- """
- props = self._buddy.GetProperties(byte_arrays=True)
- if not props:
- return {}
- return props
-
- def do_get_property(self, pspec):
- """Retrieve a particular property from our property dictionary
-
- pspec -- XXX some sort of GTK specifier object with attributes
- including 'name', 'active' and 'icon-name'
- """
- if pspec.name == "key":
- return self._properties["key"]
- elif pspec.name == "nick":
- return self._properties["nick"]
- elif pspec.name == "color":
- return self._properties["color"]
- elif pspec.name == "current-activity":
- if not self._properties.has_key("current-activity"):
- return None
- curact = self._properties["current-activity"]
- if not len(curact):
- return None
- for activity in self._activities.values():
- if activity.props.id == curact:
- return activity
- return None
- elif pspec.name == "owner":
- return self._properties["owner"]
- elif pspec.name == "icon":
- if not self._icon:
- self._icon = str(self._buddy.GetIcon(byte_arrays=True))
- return self._icon
- elif pspec.name == "ip4-address":
- # IPv4 address will go away quite soon
- if not self._properties.has_key("ip4-address"):
- return None
- return self._properties["ip4-address"]
-
- def object_path(self):
- """Retrieve our dbus object path"""
- return self._object_path
-
- def _emit_icon_changed_signal(self, bytes):
- """Emit GObject signal when icon has changed"""
- self._icon = str(bytes)
- self.emit('icon-changed')
- return False
-
- def _icon_changed_cb(self, icon_data):
- """Handle dbus signal by emitting a GObject signal"""
- gobject.idle_add(self._emit_icon_changed_signal, icon_data)
-
- def _emit_joined_activity_signal(self, object_path):
- """Emit activity joined signal with Activity object"""
- self.emit('joined-activity', self._ps_new_object(object_path))
- return False
-
- def _joined_activity_cb(self, object_path):
- """Handle dbus signal by emitting a GObject signal
-
- Stores the activity in activities dictionary as well
- """
- if not self._activities.has_key(object_path):
- self._activities[object_path] = self._ps_new_object(object_path)
- gobject.idle_add(self._emit_joined_activity_signal, object_path)
-
- def _emit_left_activity_signal(self, object_path):
- """Emit activity left signal with Activity object
-
- XXX this calls self._ps_new_object instead of self._ps_del_object,
- which would seem to be the incorrect callback?
- """
- self.emit('left-activity', self._ps_new_object(object_path))
- return False
-
- def _left_activity_cb(self, object_path):
- """Handle dbus signal by emitting a GObject signal
-
- Also removes from the activities dictionary
- """
- if self._activities.has_key(object_path):
- del self._activities[object_path]
- gobject.idle_add(self._emit_left_activity_signal, object_path)
-
- def _handle_property_changed_signal(self, prop_list):
- """Emit property-changed signal with property dictionary
-
- Generates a property-changed signal with the results of
- _get_properties_helper()
- """
- self._properties = self._get_properties_helper()
- # FIXME: don't leak unexposed property names
- self.emit('property-changed', prop_list)
- return False
-
- def _property_changed_cb(self, prop_list):
- """Handle dbus signal by emitting a GObject signal"""
- gobject.idle_add(self._handle_property_changed_signal, prop_list)
-
- def get_icon_pixbuf(self):
- """Retrieve Buddy's icon as a GTK pixel buffer
-
- XXX Why aren't the icons coming in as SVG?
- """
- if self.props.icon and len(self.props.icon):
- pbl = gtk.gdk.PixbufLoader()
- pbl.write(self.props.icon)
- pbl.close()
- return pbl.get_pixbuf()
- else:
- return None
-
- def get_joined_activities(self):
- """Retrieve the set of all activities which this buddy has joined
-
- Uses the GetJoinedActivities method on the service
- object to produce object paths, wraps each in an
- Activity object.
-
- returns list of presence Activity objects
- """
- try:
- resp = self._buddy.GetJoinedActivities()
- except dbus.exceptions.DBusException:
- return []
- acts = []
- for item in resp:
- acts.append(self._ps_new_object(item))
- return acts
diff --git a/src/sugar/presence/presenceservice.py b/src/sugar/presence/presenceservice.py
deleted file mode 100644
index a7fd1a4..0000000
--- a/src/sugar/presence/presenceservice.py
+++ /dev/null
@@ -1,609 +0,0 @@
-# Copyright (C) 2007, Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""UI class to access system-level presence object
-
-STABLE.
-"""
-
-import logging
-import traceback
-
-import dbus
-import dbus.exceptions
-import dbus.glib
-import gobject
-
-from sugar.presence.buddy import Buddy
-from sugar.presence.activity import Activity
-
-
-DBUS_SERVICE = "org.laptop.Sugar.Presence"
-DBUS_INTERFACE = "org.laptop.Sugar.Presence"
-DBUS_PATH = "/org/laptop/Sugar/Presence"
-
-_logger = logging.getLogger('sugar.presence.presenceservice')
-
-
-class PresenceService(gobject.GObject):
- """UI-side interface to the dbus presence service
-
- This class provides UI programmers with simplified access
- to the dbus service of the same name. It allows for observing
- various events from the presence service as GObject events,
- as well as some basic introspection queries.
- """
- __gsignals__ = {
- 'buddy-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'buddy-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- # parameters: (activity: Activity, inviter: Buddy, message: unicode)
- 'activity-invitation': (gobject.SIGNAL_RUN_FIRST, None, ([object]*3)),
- 'private-invitation': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT, str])),
- 'activity-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'activity-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'activity-shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT]))
- }
-
- _PS_BUDDY_OP = DBUS_PATH + "/Buddies/"
- _PS_ACTIVITY_OP = DBUS_PATH + "/Activities/"
-
-
- def __init__(self, allow_offline_iface=True):
- """Initialise the service and attempt to connect to events
- """
- gobject.GObject.__init__(self)
- self._objcache = {}
- self._joined = None
-
- # Get a connection to the session bus
- self._bus = dbus.SessionBus()
- self._bus.add_signal_receiver(self._name_owner_changed_cb,
- signal_name="NameOwnerChanged",
- dbus_interface="org.freedesktop.DBus")
-
- # attempt to load the interface to the service...
- self._allow_offline_iface = allow_offline_iface
- self._get_ps()
-
- def _name_owner_changed_cb(self, name, old, new):
- if name != DBUS_SERVICE:
- return
- if (old and len(old)) and (not new and not len(new)):
- # PS went away, clear out PS dbus service wrapper
- self._ps_ = None
- elif (not old and not len(old)) and (new and len(new)):
- # PS started up
- self._get_ps()
-
- _ps_ = None
- def _get_ps(self):
- """Retrieve dbus interface to PresenceService
-
- Also registers for updates from various dbus events on the
- interface.
-
- If unable to retrieve the interface, we will temporarily
- return an _OfflineInterface object to allow the calling
- code to continue functioning as though it had accessed a
- real presence service.
-
- If successful, caches the presence service interface
- for use by other methods and returns that interface
- """
- if not self._ps_:
- try:
- # NOTE: We need to follow_name_owner_changes here
- # because we can not connect to a signal unless
- # we follow the changes or we start the service
- # before we connect. Starting the service here
- # causes a major bottleneck during startup
- ps = dbus.Interface(
- self._bus.get_object(DBUS_SERVICE,
- DBUS_PATH,
- follow_name_owner_changes=True),
- DBUS_INTERFACE
- )
- except dbus.exceptions.DBusException, err:
- _logger.error(
- """Failure retrieving %r interface from
- the D-BUS service %r %r: %s""",
- DBUS_INTERFACE, DBUS_SERVICE, DBUS_PATH, err
- )
- if self._allow_offline_iface:
- return _OfflineInterface()
- raise RuntimeError("Failed to connect to the presence service.")
- else:
- self._ps_ = ps
- ps.connect_to_signal('BuddyAppeared',
- self._buddy_appeared_cb)
- ps.connect_to_signal('BuddyDisappeared',
- self._buddy_disappeared_cb)
- ps.connect_to_signal('ActivityAppeared',
- self._activity_appeared_cb)
- ps.connect_to_signal('ActivityDisappeared',
- self._activity_disappeared_cb)
- ps.connect_to_signal('ActivityInvitation',
- self._activity_invitation_cb)
- ps.connect_to_signal('PrivateInvitation',
- self._private_invitation_cb)
- return self._ps_
-
- _ps = property(
- _get_ps, None, None,
- """DBUS interface to the PresenceService
- (services/presence/presenceservice)"""
- )
-
- def _new_object(self, object_path):
- """Turn new object path into (cached) Buddy/Activity instance
-
- object_path -- full dbus path of the new object, must be
- prefixed with either of _PS_BUDDY_OP or _PS_ACTIVITY_OP
-
- Note that this method is called throughout the class whenever
- the representation of the object is required, it is not only
- called when the object is first discovered. The point is to only have
- _one_ Python object for any D-Bus object represented by an object path,
- effectively wrapping the D-Bus object in a single Python GObject.
-
- returns presence Buddy or Activity representation
- """
- obj = None
- try:
- obj = self._objcache[object_path]
- _logger.debug('Reused proxy %r', obj)
- except KeyError:
- if object_path.startswith(self._PS_BUDDY_OP):
- obj = Buddy(self._bus, self._new_object,
- self._del_object, object_path)
- elif object_path.startswith(self._PS_ACTIVITY_OP):
- obj = Activity(self._bus, self._new_object,
- self._del_object, object_path)
- try:
- # Pre-fill the activity's ID
- activity_id = obj.props.id
- except dbus.exceptions.DBusException:
- logging.debug('Cannot get the activity ID')
- else:
- raise RuntimeError("Unknown object type")
- self._objcache[object_path] = obj
- _logger.debug('Created proxy %r', obj)
- return obj
-
- def _have_object(self, object_path):
- return object_path in self._objcache.keys()
-
- def _del_object(self, object_path):
- """Fully remove an object from the object cache when
- it's no longer needed.
- """
- del self._objcache[object_path]
-
- def _emit_buddy_appeared_signal(self, object_path):
- """Emit GObject event with presence.buddy.Buddy object"""
- self.emit('buddy-appeared', self._new_object(object_path))
- return False
-
- def _buddy_appeared_cb(self, op):
- """Callback for dbus event (forwards to method to emit GObject event)"""
- gobject.idle_add(self._emit_buddy_appeared_signal, op)
-
- def _emit_buddy_disappeared_signal(self, object_path):
- """Emit GObject event with presence.buddy.Buddy object"""
- # Don't try to create a new object here if needed; it will probably
- # fail anyway because the object has already been destroyed in the PS
- if self._have_object(object_path):
- obj = self._objcache[object_path]
- self.emit('buddy-disappeared', obj)
-
- # We cannot maintain the object in the cache because that would keep
- # a lot of objects from being collected. That includes UI objects
- # due to signals using strong references.
- # If we want to cache some despite the memory usage increase,
- # we could use a LRU cache limited to some value.
- del self._objcache[object_path]
- obj.destroy()
-
- return False
-
- def _buddy_disappeared_cb(self, object_path):
- """Callback for dbus event (forwards to method to emit GObject event)"""
- gobject.idle_add(self._emit_buddy_disappeared_signal, object_path)
-
- def _emit_activity_invitation_signal(self, activity_path, buddy_path,
- message):
- """Emit GObject event with presence.activity.Activity object"""
- self.emit('activity-invitation', self._new_object(activity_path),
- self._new_object(buddy_path), unicode(message))
- return False
-
- def _activity_invitation_cb(self, activity_path, buddy_path, message):
- """Callback for dbus event (forwards to method to emit GObject event)"""
- gobject.idle_add(self._emit_activity_invitation_signal, activity_path,
- buddy_path, message)
-
- def _emit_private_invitation_signal(self, bus_name, connection,
- channel, chan_type):
- """Emit GObject event with bus_name, connection and channel"""
- self.emit('private-invitation', bus_name, connection,
- channel, chan_type)
- return False
-
- def _private_invitation_cb(self, bus_name, connection, channel, chan_type):
- """Callback for dbus event (forwards to method to emit GObject event)"""
- gobject.idle_add(self._emit_private_invitation_signal, bus_name,
- connection, channel, chan_type)
-
- def _emit_activity_appeared_signal(self, object_path):
- """Emit GObject event with presence.activity.Activity object"""
- self.emit('activity-appeared', self._new_object(object_path))
- return False
-
- def _activity_appeared_cb(self, object_path):
- """Callback for dbus event (forwards to method to emit GObject event)"""
- gobject.idle_add(self._emit_activity_appeared_signal, object_path)
-
- def _emit_activity_disappeared_signal(self, object_path):
- """Emit GObject event with presence.activity.Activity object"""
- self.emit('activity-disappeared', self._new_object(object_path))
- return False
-
- def _activity_disappeared_cb(self, object_path):
- """Callback for dbus event (forwards to method to emit GObject event)"""
- gobject.idle_add(self._emit_activity_disappeared_signal, object_path)
-
- def get(self, object_path):
- """Return the Buddy or Activity object corresponding to the given
- D-Bus object path.
- """
- return self._new_object(object_path)
-
- def get_activities(self):
- """Retrieve set of all activities from service
-
- returns list of Activity objects for all object paths
- the service reports exist (using GetActivities)
- """
- try:
- resp = self._ps.GetActivities()
- except dbus.exceptions.DBusException, err:
- _logger.warn(
- """Unable to retrieve activity list from presence service: %s"""
- % err
- )
- return []
- else:
- acts = []
- for item in resp:
- acts.append(self._new_object(item))
- return acts
-
- def _get_activities_cb(self, reply_handler, resp):
- acts = []
- for item in resp:
- acts.append(self._new_object(item))
-
- reply_handler(acts)
-
- def _get_activities_error_cb(self, error_handler, e):
- if error_handler:
- error_handler(e)
- else:
- _logger.warn(
- """Unable to retrieve activity-list from presence service: %s"""
- % e
- )
-
- def get_activities_async(self, reply_handler=None, error_handler=None):
- """Retrieve set of all activities from service asyncronously
- """
-
- if not reply_handler:
- logging.error('Function get_activities_async called without' \
- 'a reply handler. Can not run.')
- return
-
- self._ps.GetActivities(
- reply_handler=lambda resp: \
- self._get_activities_cb(reply_handler, resp),
- error_handler=lambda e: \
- self._get_activities_error_cb(error_handler, e))
-
-
- def get_activity(self, activity_id, warn_if_none=True):
- """Retrieve single Activity object for the given unique id
-
- activity_id -- unique ID for the activity
-
- returns single Activity object or None if the activity
- is not found using GetActivityById on the service
- """
- try:
- act_op = self._ps.GetActivityById(activity_id)
- except dbus.exceptions.DBusException, err:
- if warn_if_none:
- _logger.warn("Unable to retrieve activity handle for %r from "
- "presence service: %s", activity_id, err)
- return None
- return self._new_object(act_op)
-
- def get_buddies(self):
- """Retrieve set of all buddies from service
-
- returns list of Buddy objects for all object paths
- the service reports exist (using GetBuddies)
- """
- try:
- resp = self._ps.GetBuddies()
- except dbus.exceptions.DBusException, err:
- _logger.warn(
- """Unable to retrieve buddy-list from presence service: %s"""
- % err
- )
- return []
- else:
- buddies = []
- for item in resp:
- buddies.append(self._new_object(item))
- return buddies
-
- def _get_buddies_cb(self, reply_handler, resp):
- buddies = []
- for item in resp:
- buddies.append(self._new_object(item))
-
- reply_handler(buddies)
-
- def _get_buddies_error_cb(self, error_handler, e):
- if error_handler:
- error_handler(e)
- else:
- _logger.warn(
- """Unable to retrieve buddy-list from presence service: %s"""
- % e
- )
-
- def get_buddies_async(self, reply_handler=None, error_handler=None):
- """Retrieve set of all buddies from service asyncronously
- """
-
- if not reply_handler:
- logging.error('Function get_buddies_async called without' \
- 'a reply handler. Can not run.')
- return
-
- self._ps.GetBuddies(
- reply_handler=lambda resp: \
- self._get_buddies_cb(reply_handler, resp),
- error_handler=lambda e: \
- self._get_buddies_error_cb(error_handler, e))
-
- def get_buddy(self, key):
- """Retrieve single Buddy object for the given public key
-
- key -- buddy's public encryption key
-
- returns single Buddy object or None if the activity
- is not found using GetBuddyByPublicKey on the
- service
- """
- try:
- buddy_op = self._ps.GetBuddyByPublicKey(dbus.ByteArray(key))
- except dbus.exceptions.DBusException, err:
- _logger.warn(
- """Unable to retrieve buddy handle
- for %r from presence service: %s"""
- % key, err
- )
- return None
- return self._new_object(buddy_op)
-
- def get_buddy_by_telepathy_handle(self, tp_conn_name, tp_conn_path,
- handle):
- """Retrieve single Buddy object for the given public key
-
- :Parameters:
- `tp_conn_name` : str
- The well-known bus name of a Telepathy connection
- `tp_conn_path` : dbus.ObjectPath
- The object path of the Telepathy connection
- `handle` : int or long
- The handle of a Telepathy contact on that connection,
- of type HANDLE_TYPE_CONTACT. This may not be a
- channel-specific handle.
- :Returns: the Buddy object, or None if the buddy is not found
- """
- try:
- buddy_op = self._ps.GetBuddyByTelepathyHandle(tp_conn_name,
- tp_conn_path,
- handle)
- except dbus.exceptions.DBusException, err:
- _logger.warn('Unable to retrieve buddy handle for handle %u at '
- 'conn %s:%s from presence service: %s',
- handle, tp_conn_name, tp_conn_path, err)
- return None
- return self._new_object(buddy_op)
-
- def get_owner(self):
- """Retrieves the laptop "owner" Buddy object."""
- try:
- owner_op = self._ps.GetOwner()
- except dbus.exceptions.DBusException, err:
- _logger.warn(
- """Unable to retrieve local user/owner
- from presence service: %s"""
- % err
- )
- raise RuntimeError("Could not get owner object.")
- return self._new_object(owner_op)
-
- def _share_activity_cb(self, activity, op):
- """Finish sharing the activity
- """
- # FIXME find a better way to shutup pylint
- psact = self._new_object(op)
- psact._joined = True
- _logger.debug('%r: Just shared, setting up tubes', activity)
- psact.set_up_tubes(reply_handler=lambda:
- self.emit("activity-shared", True, psact, None),
- error_handler=lambda e:
- self._share_activity_error_cb(activity, e))
-
- def _share_activity_error_cb(self, activity, err):
- """Notify with GObject event of unsuccessful sharing of activity"""
- _logger.debug("Error sharing activity %s: %s" %
- (activity.get_id(), err))
- self.emit("activity-shared", False, None, err)
-
- def share_activity(self, activity, properties=None, private=True):
- """Ask presence service to ask the activity to share itself publicly.
-
- Uses the AdvertiseActivity method on the service to ask for the
- sharing of the given activity. Arranges to emit activity-shared
- event with:
-
- (success, Activity, err)
-
- on success/failure.
-
- returns None
- """
- actid = activity.get_id()
-
- if properties is None:
- properties = {}
-
- # Ensure the activity is not already shared/joined
- for obj in self._objcache.values():
- if not isinstance(object, Activity):
- continue
- if obj.props.id == actid or obj.props.joined:
- raise RuntimeError("Activity %s is already shared." %
- actid)
-
- atype = activity.get_bundle_id()
- name = activity.props.title
- properties['private'] = bool(private)
- self._ps.ShareActivity(actid, atype, name, properties,
- reply_handler=lambda op: \
- self._share_activity_cb(activity, op),
- error_handler=lambda e: \
- self._share_activity_error_cb(activity, e))
-
- def get_preferred_connection(self):
- """Gets the preferred telepathy connection object that an activity
- should use when talking directly to telepathy
-
- returns the bus name and the object path of the Telepathy connection"""
-
- try:
- bus_name, object_path = self._ps.GetPreferredConnection()
- except dbus.exceptions.DBusException:
- logging.error(traceback.format_exc())
- return None
-
- return bus_name, object_path
-
-class _OfflineInterface( object ):
- """Offline-presence-service interface
-
- Used to mimic the behaviour of a real PresenceService sufficiently
- to avoid crashing client code that expects the given interface.
-
- XXX we could likely return a "MockOwner" object reasonably
- easily, but would it be worth it?
- """
- def raiseException( self, *args, **named ):
- """Raise dbus.exceptions.DBusException"""
- raise dbus.exceptions.DBusException(
- """PresenceService Interface not available"""
- )
- GetActivities = raiseException
- GetActivityById = raiseException
- GetBuddies = raiseException
- GetBuddyByPublicKey = raiseException
- GetOwner = raiseException
- GetPreferredConnection = raiseException
- def ShareActivity(
- self, actid, atype, name, properties,
- reply_handler, error_handler,
- ):
- """Pretend to share and fail..."""
- exc = IOError(
- """Unable to share activity as PresenceService
- is not currenly available"""
- )
- return error_handler( exc )
-
-class _MockPresenceService(gobject.GObject):
- """Test fixture allowing testing of items that use PresenceService
-
- See PresenceService for usage and purpose
- """
- __gsignals__ = {
- 'buddy-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'buddy-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'activity-invitation': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'private-invitation': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT])),
- 'activity-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'activity-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
- }
-
- def __init__(self):
- gobject.GObject.__init__(self)
-
- def get_activities(self):
- return []
-
- def get_activity(self, activity_id):
- return None
-
- def get_buddies(self):
- return []
-
- def get_buddy(self, key):
- return None
-
- def get_owner(self):
- return None
-
- def share_activity(self, activity, properties=None):
- return None
-
-_ps = None
-def get_instance(allow_offline_iface=False):
- """Retrieve this process' view of the PresenceService"""
- global _ps
- if not _ps:
- _ps = PresenceService(allow_offline_iface)
- return _ps
-
diff --git a/src/sugar/presence/sugartubeconn.py b/src/sugar/presence/sugartubeconn.py
deleted file mode 100644
index 954ef67..0000000
--- a/src/sugar/presence/sugartubeconn.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2008 One Laptop Per Child
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-"""Subclass of TubeConnection that converts handles to Sugar Buddies
-
-STABLE.
-"""
-
-from telepathy.constants import (
- CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES)
-
-from sugar.presence.tubeconn import TubeConnection
-from sugar.presence import presenceservice
-
-
-class SugarTubeConnection(TubeConnection):
- """Subclass of TubeConnection that converts handles to Sugar Buddies"""
-
- def __new__(cls, conn, tubes_iface, tube_id, address=None,
- group_iface=None, mainloop=None):
- self = super(SugarTubeConnection, cls).__new__(
- cls, conn, tubes_iface, tube_id, address=address,
- group_iface=group_iface, mainloop=mainloop)
- self._conn = conn
- self._group_iface = group_iface
- return self
-
- def get_buddy(self, cs_handle):
- """Retrieve a Buddy object given a telepathy handle.
-
- cs_handle: A channel-specific CONTACT type handle.
- returns: sugar.presence Buddy object or None
- """
- pservice = presenceservice.get_instance()
- if self.self_handle == cs_handle:
- # It's me, just get my global handle
- handle = self._conn.GetSelfHandle()
- elif self._group_iface.GetGroupFlags() & \
- CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES:
- # The group (channel) has channel specific handles
- handle = self._group_iface.GetHandleOwners([cs_handle])[0]
- else:
- # The group does not have channel specific handles
- handle = cs_handle
-
- # deal with failure to get the handle owner
- if handle == 0:
- return None
- return pservice.get_buddy_by_telepathy_handle(
- self._conn.service_name, self._conn.object_path, handle)
diff --git a/src/sugar/presence/test_presence.txt b/src/sugar/presence/test_presence.txt
deleted file mode 100644
index d0736a9..0000000
--- a/src/sugar/presence/test_presence.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-This is a test of presence.
-
-To test this service we will start up a mock dbus library:
-
- >>> from sugar.testing import mockdbus
- >>> import dbus
- >>> pres_service = mockdbus.MockService(
- ... 'org.laptop.Presence', '/org/laptop/Presence', name='pres')
- >>> pres_service.install()
- >>> pres_interface = dbus.Interface(pres_service, 'org.laptop.Presence')
-
-Then we import the library (second, to make sure it connects to our
-mocked system, though the lazy instantiation in get_instance() should
-handle it):
-
- >>> from sugar.presence import PresenceService
- >>> ps = PresenceService.get_instance()
- >>> pres_interface.make_response('getServices', [])
- >>> ps.get_services()
- Called pres.org.laptop.Presence:getServices()
- []
- >>> pres_interface.make_response('getBuddies', [])
- >>> ps.get_buddies()
- Called pres.org.laptop.Presence:getBuddies()
- []
-
diff --git a/src/sugar/presence/tubeconn.py b/src/sugar/presence/tubeconn.py
deleted file mode 100644
index 8606db6..0000000
--- a/src/sugar/presence/tubeconn.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# This should eventually land in telepathy-python, so has the same license:
-
-# Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-"""
-STABLE.
-"""
-
-__all__ = ('TubeConnection',)
-__docformat__ = 'reStructuredText'
-
-
-import logging
-
-from dbus.connection import Connection
-
-
-logger = logging.getLogger('telepathy.tubeconn')
-
-
-class TubeConnection(Connection):
-
- # pylint: disable-msg=W0212
- # Confused by __new__
- def __new__(cls, conn, tubes_iface, tube_id, address=None,
- group_iface=None, mainloop=None):
- if address is None:
- address = tubes_iface.GetDBusTubeAddress(tube_id)
- self = super(TubeConnection, cls).__new__(cls, address,
- mainloop=mainloop)
-
- self._tubes_iface = tubes_iface
- self.tube_id = tube_id
- self.participants = {}
- self.bus_name_to_handle = {}
- self._mapping_watches = []
-
- if group_iface is None:
- method = conn.GetSelfHandle
- else:
- method = group_iface.GetSelfHandle
- method(reply_handler=self._on_get_self_handle_reply,
- error_handler=self._on_get_self_handle_error)
-
- return self
-
- # pylint: disable-msg=W0201
- # Confused by __new__
- def _on_get_self_handle_reply(self, handle):
- self.self_handle = handle
- match = self._tubes_iface.connect_to_signal('DBusNamesChanged',
- self._on_dbus_names_changed)
- self._tubes_iface.GetDBusNames(self.tube_id,
- reply_handler=self._on_get_dbus_names_reply,
- error_handler=self._on_get_dbus_names_error)
- self._dbus_names_changed_match = match
-
- def _on_get_self_handle_error(self, e):
- logging.basicConfig()
- logger.error('GetSelfHandle failed: %s', e)
-
- def close(self):
- self._dbus_names_changed_match.remove()
- self._on_dbus_names_changed(self.tube_id, (), self.participants.keys())
- super(TubeConnection, self).close()
-
- def _on_get_dbus_names_reply(self, names):
- self._on_dbus_names_changed(self.tube_id, names, ())
-
- def _on_get_dbus_names_error(self, e):
- logging.basicConfig()
- logger.error('GetDBusNames failed: %s', e)
-
- def _on_dbus_names_changed(self, tube_id, added, removed):
- if tube_id == self.tube_id:
- for handle, bus_name in added:
- if handle == self.self_handle:
- # I've just joined - set my unique name
- self.set_unique_name(bus_name)
- self.participants[handle] = bus_name
- self.bus_name_to_handle[bus_name] = handle
-
- # call the callback while the removed people are still in
- # participants, so their bus names are available
- for callback in self._mapping_watches:
- callback(added, removed)
-
- for handle in removed:
- bus_name = self.participants.pop(handle, None)
- self.bus_name_to_handle.pop(bus_name, None)
-
- def watch_participants(self, callback):
- self._mapping_watches.append(callback)
- if self.participants:
- # GetDBusNames already returned: fake a participant add event
- # immediately
- added = []
- for k, v in self.participants.iteritems():
- added.append((k, v))
- callback(added, [])