From eaef567cabc5c0dda9706faa0e17e20909131ade Mon Sep 17 00:00:00 2001 From: simpoir Date: Fri, 30 Jan 2009 04:14:48 +0000 Subject: ajout initial du tree jhbuild [jhbuild base] --- (limited to 'src/sugar/presence/buddy.py') diff --git a/src/sugar/presence/buddy.py b/src/sugar/presence/buddy.py new file mode 100644 index 0000000..fab23d2 --- /dev/null +++ b/src/sugar/presence/buddy.py @@ -0,0 +1,239 @@ +# 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 -- cgit v0.9.1