Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
This commit is contained in:
		
						commit
						ee400fa602
					
				| @ -0,0 +1,5 @@ | ||||
| """Client-code's interface to the ClipboardService | ||||
| 
 | ||||
| Provides a simplified API for accessing the dbus service | ||||
| which coordinates clipboard operations within Sugar. | ||||
| """ | ||||
| @ -0,0 +1 @@ | ||||
| """Hippo-based graphics/controls for use in Sugar""" | ||||
| @ -0,0 +1,7 @@ | ||||
| """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". | ||||
| """ | ||||
| @ -1,3 +1,4 @@ | ||||
| """UI interface to an activity in the presence service""" | ||||
| # Copyright (C) 2007, Red Hat, Inc. | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or | ||||
| @ -19,7 +20,19 @@ import gobject | ||||
| import dbus | ||||
| 
 | ||||
| class Activity(gobject.GObject): | ||||
| 
 | ||||
|     """UI interface for an Activity in the presence service | ||||
|      | ||||
|     Activities in the presence service represent other user's | ||||
|     shared activities and your own activities (XXX shared or  | ||||
|     otherwise?) | ||||
|      | ||||
|     Properties: | ||||
|         id  | ||||
|         color  | ||||
|         name  | ||||
|         type  | ||||
|         joined  | ||||
|     """ | ||||
|     __gsignals__ = { | ||||
|         'buddy-joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, | ||||
|                          ([gobject.TYPE_PYOBJECT])), | ||||
| @ -33,6 +46,7 @@ class Activity(gobject.GObject): | ||||
|     _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._object_path = object_path | ||||
|         self._ps_new_object = new_obj_cb | ||||
| @ -50,9 +64,11 @@ class Activity(gobject.GObject): | ||||
|         self._joined = False | ||||
| 
 | ||||
|     def object_path(self): | ||||
|         """Get our dbus object path""" | ||||
|         return self._object_path | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
| @ -60,6 +76,10 @@ class Activity(gobject.GObject): | ||||
|         gobject.idle_add(self._emit_buddy_joined_signal, object_path) | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
| @ -67,6 +87,10 @@ class Activity(gobject.GObject): | ||||
|         gobject.idle_add(self._emit_buddy_left_signal, object_path) | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
| @ -74,27 +98,35 @@ class Activity(gobject.GObject): | ||||
|         gobject.idle_add(self._emit_new_channel_signal, object_path) | ||||
| 
 | ||||
|     def get_id(self): | ||||
|         """Retrieve the unique identifier for this activity instance""" | ||||
|         # Cache activity ID, which should never change anyway | ||||
|         if not self._id: | ||||
|             self._id = self._activity.GetId() | ||||
|         return self._id | ||||
| 
 | ||||
|     def get_color(self): | ||||
|         """Retrieve the activity icon colour for this activity instance""" | ||||
|         if not self._color: | ||||
|             self._color = self._activity.GetColor() | ||||
|         return self._color | ||||
| 
 | ||||
|     def get_name(self): | ||||
|         """Retrieve the activity name for this activity instance""" | ||||
|         if not self._name: | ||||
|             self._name = self._activity.GetName() | ||||
|         return self._name | ||||
| 
 | ||||
|     def get_type(self): | ||||
|         """Retrieve the activity/bundle type for this activity instance""" | ||||
|         if not self._type: | ||||
|             self._type = self._activity.GetType() | ||||
|         return self._type | ||||
| 
 | ||||
|     def get_joined_buddies(self): | ||||
|         """Retrieve the set of Buddy objects attached to this activity | ||||
|          | ||||
|         returns list of presence Buddy objects | ||||
|         """ | ||||
|         resp = self._activity.GetJoinedBuddies() | ||||
|         buddies = [] | ||||
|         for item in resp: | ||||
| @ -102,15 +134,26 @@ class Activity(gobject.GObject): | ||||
|         return buddies | ||||
| 
 | ||||
|     def join(self): | ||||
|         """Join this activity  | ||||
|          | ||||
|         XXX if these are all activities, can I join my own activity? | ||||
|         """ | ||||
|         if self._joined: | ||||
|             return | ||||
|         self._activity.Join() | ||||
|         self._joined = True | ||||
| 
 | ||||
|     def get_channels(self): | ||||
|         """Retrieve communications channel descriptions for the activity  | ||||
|          | ||||
|         Returns (bus name, connection, channels) for the activity | ||||
|          | ||||
|         XXX what are those values? | ||||
|         """ | ||||
|         (bus_name, connection, channels) = self._activity.GetChannels() | ||||
|         return bus_name, connection, channels | ||||
| 
 | ||||
|     def owner_has_joined(self): | ||||
|         """Retrieve whether the owner of the activity is active within it""" | ||||
|         # FIXME | ||||
|         return False | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| """UI interface to a buddy in the presence service""" | ||||
| # Copyright (C) 2007, Red Hat, Inc. | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or | ||||
| @ -20,13 +21,33 @@ import gtk | ||||
| import dbus | ||||
| 
 | ||||
| def _bytes_to_string(bytes): | ||||
|     """Convertes an short-int (char) array to a string | ||||
|      | ||||
|     returns string or None for a null sequence | ||||
|     """ | ||||
|     if len(bytes): | ||||
|         # if there's an internal buffer, we could use  | ||||
|         # ctypes to pull it out without this... | ||||
|         return ''.join([chr(item) for item in bytes]) | ||||
|     return None | ||||
| 
 | ||||
| 
 | ||||
| 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, | ||||
|                          ([])), | ||||
| @ -51,6 +72,13 @@ class Buddy(gobject.GObject): | ||||
|     _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 | ||||
| @ -68,12 +96,19 @@ class Buddy(gobject.GObject): | ||||
|         self._icon = None | ||||
| 
 | ||||
|     def _get_properties_helper(self): | ||||
|         """Retrieve the Buddy's property dictionary from the service object | ||||
|         """ | ||||
|         props = self._buddy.GetProperties() | ||||
|         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": | ||||
| @ -97,48 +132,79 @@ class Buddy(gobject.GObject): | ||||
|             return self._icon | ||||
| 
 | ||||
|     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 = _bytes_to_string(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() | ||||
|             icon_data = "" | ||||
|             for item in self.props.icon: | ||||
|                 # XXX this is a slow way to convert the data  | ||||
|                 # under Python 2.5 and below, collect in a  | ||||
|                 # list and then join with "", see  | ||||
|                 # _bytes_to_string in this module | ||||
|                 icon_data = icon_data + chr(item) | ||||
|             pbl.write(icon_data) | ||||
|             pbl.close() | ||||
| @ -147,6 +213,14 @@ class Buddy(gobject.GObject): | ||||
|             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: | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| """UI class to access system-level presence object""" | ||||
| # Copyright (C) 2007, Red Hat, Inc. | ||||
| # | ||||
| # This library is free software; you can redistribute it and/or | ||||
| @ -18,24 +19,78 @@ | ||||
| import dbus, dbus.glib, gobject | ||||
| import logging | ||||
| 
 | ||||
| # XXX use absolute imports | ||||
| #   from sugar.presence import buddy, activity | ||||
| # this *kind* of relative import is deprecated | ||||
| # with an explicit relative import slated to be  | ||||
| # introduced (available in Python 2.5 with a __future__ | ||||
| # import), that would read as: | ||||
| #   from . import buddy, activity  | ||||
| # see PEP: http://docs.python.org/whatsnew/pep-328.html | ||||
| import buddy, activity | ||||
| 
 | ||||
| class ObjectCache(object): | ||||
|     """Path to Activity/Buddy object cache | ||||
|      | ||||
|     On notification of a new object of either type the  | ||||
|     PresenceService client stores the object's representation | ||||
|     in this object. | ||||
|      | ||||
|     XXX Why not just sub-class dict?  We're only adding two | ||||
|         methods then and we would have all of the other  | ||||
|         standard operations on dictionaries. | ||||
|     """ | ||||
|     def __init__(self): | ||||
|         """Initialise the cache""" | ||||
|         self._cache = {} | ||||
| 
 | ||||
|     def get(self, object_path): | ||||
|         """Retrieve specified object from the cache  | ||||
|          | ||||
|         object_path -- full dbus path to the object | ||||
|          | ||||
|         returns a presence.buddy.Buddy or presence.activity.Activity | ||||
|         instance or None if the object_path is not yet cached. | ||||
|          | ||||
|         XXX could be written as return self._cache.get( object_path ) | ||||
|         """ | ||||
|         try: | ||||
|             return self._cache[object_path] | ||||
|         except KeyError: | ||||
|             return None | ||||
| 
 | ||||
|     def add(self, obj): | ||||
|         """Adds given presence object to the cache  | ||||
|          | ||||
|         obj -- presence Buddy or Activity representation, the object's | ||||
|             object_path() method is used as the key for storage | ||||
|          | ||||
|         returns None  | ||||
|          | ||||
|         XXX should raise an error on collisions, shouldn't it? or  | ||||
|             return True/False to say whether the item was actually | ||||
|             added | ||||
|         """ | ||||
|         op = obj.object_path() | ||||
|         if not self._cache.has_key(op): | ||||
|             self._cache[op] = obj | ||||
| 
 | ||||
|     def remove(self, object_path): | ||||
|         """Remove the given presence object from the cache  | ||||
|          | ||||
|         object_path -- full dbus path to the object | ||||
|          | ||||
|         returns None  | ||||
|          | ||||
|         XXX does two checks instead of one with a try:except for the  | ||||
|             keyerror, normal case of deleting existing penalised as | ||||
|             a result. | ||||
|              | ||||
|             try: | ||||
|                 return self._cache.pop( key ) | ||||
|             except KeyError: | ||||
|                 return None | ||||
|         """ | ||||
|         if self._cache.has_key(object_path): | ||||
|             del self._cache[object_path] | ||||
| 
 | ||||
| @ -46,7 +101,13 @@ DBUS_PATH = "/org/laptop/Sugar/Presence" | ||||
| 
 | ||||
| 
 | ||||
| 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])), | ||||
| @ -71,6 +132,7 @@ class PresenceService(gobject.GObject): | ||||
|      | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         """Initialise the service and connect to events""" | ||||
|         gobject.GObject.__init__(self) | ||||
|         self._objcache = ObjectCache() | ||||
|         self._bus = dbus.SessionBus() | ||||
| @ -84,6 +146,17 @@ class PresenceService(gobject.GObject): | ||||
|         self._ps.connect_to_signal('PrivateInvitation', self._private_invitation_cb) | ||||
| 
 | ||||
|     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. | ||||
|          | ||||
|         returns presence Buddy or Activity representation | ||||
|         """ | ||||
|         obj = self._objcache.get(object_path) | ||||
|         if not obj: | ||||
|             if object_path.startswith(self._PS_BUDDY_OP): | ||||
| @ -102,52 +175,79 @@ class PresenceService(gobject.GObject): | ||||
|         pass | ||||
| 
 | ||||
|     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""" | ||||
|         self.emit('buddy-disappeared', self._new_object(object_path)) | ||||
|         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, object_path): | ||||
|         """Emit GObject event with presence.activity.Activity object""" | ||||
|         self.emit('activity-invitation', self._new_object(object_path)) | ||||
|         return False | ||||
| 
 | ||||
|     def _activity_invitation_cb(self, object_path): | ||||
|         """Callback for dbus event (forwards to method to emit GObject event)""" | ||||
|         gobject.idle_add(self._emit_activity_invitation_signal, object_path) | ||||
| 
 | ||||
|     def _emit_private_invitation_signal(self, bus_name, connection, channel): | ||||
|         """Emit GObject event with bus_name, connection and channel | ||||
|          | ||||
|         XXX This seems to generate the wrong GObject event?  It generates  | ||||
|             'service-disappeared' instead of private-invitation for some  | ||||
|             reason.  That event doesn't even seem to be registered? | ||||
|         """ | ||||
|         self.emit('service-disappeared', bus_name, connection, channel) | ||||
|         return False | ||||
| 
 | ||||
|     def _private_invitation_cb(self, bus_name, connection, channel): | ||||
|         """Callback for dbus event (forwards to method to emit GObject event)""" | ||||
|         gobject.idle_add(self._emit_service_disappeared_signal, bus_name, | ||||
|                 connection, channel) | ||||
| 
 | ||||
|     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): | ||||
|         """Retrieve given object path as a Buddy/Activity object | ||||
|          | ||||
|         XXX This is basically just an alias for _new_object, i.e. it  | ||||
|             just adds an extra function-call to the operation. | ||||
|         """ | ||||
|         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) | ||||
|         """ | ||||
|         resp = self._ps.GetActivities() | ||||
|         acts = [] | ||||
|         for item in resp: | ||||
| @ -155,6 +255,13 @@ class PresenceService(gobject.GObject): | ||||
|         return acts | ||||
| 
 | ||||
|     def get_activity(self, activity_id): | ||||
|         """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: | ||||
| @ -162,6 +269,11 @@ class PresenceService(gobject.GObject): | ||||
|         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) | ||||
|         """ | ||||
|         resp = self._ps.GetBuddies() | ||||
|         buddies = [] | ||||
|         for item in resp: | ||||
| @ -169,6 +281,14 @@ class PresenceService(gobject.GObject): | ||||
|         return buddies | ||||
| 
 | ||||
|     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: | ||||
| @ -176,6 +296,12 @@ class PresenceService(gobject.GObject): | ||||
|         return self._new_object(buddy_op) | ||||
| 
 | ||||
|     def get_owner(self): | ||||
|         """Retrieves "owner" as a Buddy | ||||
|          | ||||
|         XXX check that it really is a Buddy that's produced, what is  | ||||
|             this the owner of?  Shouldn't it be getting an activity  | ||||
|             and then asking who the owner of that is? | ||||
|         """ | ||||
|         try: | ||||
|             owner_op = self._ps.GetOwner() | ||||
|         except dbus.exceptions.DBusException: | ||||
| @ -183,13 +309,27 @@ class PresenceService(gobject.GObject): | ||||
|         return self._new_object(owner_op) | ||||
| 
 | ||||
|     def _share_activity_cb(self, activity, op): | ||||
|         """Notify with GObject event of successful sharing of activity""" | ||||
|         self.emit("activity-shared", True, self._new_object(op), None) | ||||
| 
 | ||||
|     def _share_activity_error_cb(self, activity, err): | ||||
|         """Notify with GObject event of unsuccessful sharing of activity""" | ||||
|         logging.debug("Error sharing activity %s: %s" % (activity.get_id(), err)) | ||||
|         self.emit("activity-shared", False, None, err) | ||||
| 
 | ||||
|     def share_activity(self, activity, properties={}): | ||||
|         """Ask presence service to ask the activity to share itself | ||||
|          | ||||
|         Uses the ShareActivity 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() | ||||
|         atype = activity.get_service_name() | ||||
|         name = activity.props.title | ||||
| @ -199,6 +339,10 @@ class PresenceService(gobject.GObject): | ||||
| 
 | ||||
| 
 | ||||
| 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])), | ||||
| @ -238,6 +382,7 @@ class _MockPresenceService(gobject.GObject): | ||||
| 
 | ||||
| _ps = None | ||||
| def get_instance(): | ||||
|     """Retrieve this process' view of the PresenceService""" | ||||
|     global _ps | ||||
|     if not _ps: | ||||
|         _ps = PresenceService() | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marco Pesenti Gritti
						Marco Pesenti Gritti