Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar/presence/Buddy.py
diff options
context:
space:
mode:
authorDan Williams <dcbw@localhost.localdomain>2006-07-19 19:27:37 (GMT)
committer Dan Williams <dcbw@localhost.localdomain>2006-07-19 19:27:37 (GMT)
commit766b82d46706c0a9f4e32635e27db8aa55a1b820 (patch)
tree4e02886931de5a0d37fd57216fe47641f2337173 /sugar/presence/Buddy.py
parentd2fdd6400348b2adc08b99e69e67c64aa092ac65 (diff)
Switch sugar/presence module over to a thin API wrapper around the PresenceService dbus API
Diffstat (limited to 'sugar/presence/Buddy.py')
-rw-r--r--sugar/presence/Buddy.py253
1 files changed, 79 insertions, 174 deletions
diff --git a/sugar/presence/Buddy.py b/sugar/presence/Buddy.py
index b91cb7d..ca26946 100644
--- a/sugar/presence/Buddy.py
+++ b/sugar/presence/Buddy.py
@@ -1,189 +1,94 @@
-import base64
-import logging
-
-import gtk
import gobject
-
-from sugar.p2p import Stream
-from sugar.p2p import network
-from sugar.presence import Service
-
-PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
+import dbus, dbus_bindings
class Buddy(gobject.GObject):
- """Represents another person on the network and keeps track of the
- activities and resources they make available for sharing."""
+
__gsignals__ = {
- 'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ 'IconChanged': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([])),
- 'service-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ 'ServiceAppeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'ServiceDisappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
- 'service-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ 'JoinedActivity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
- 'joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_STRING])),
- 'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_STRING]))
+ 'LeftActivity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT]))
}
- def __init__(self, service):
+ _PRESENCE_SERVICE = "org.laptop.Presence"
+ _BUDDY_DBUS_INTERFACE = "org.laptop.Presence.Buddy"
+
+ def __init__(self, bus, new_obj_cb, del_obj_cb, object_path):
gobject.GObject.__init__(self)
- self._services = {}
- self._nick_name = service.get_name()
- self._address = service.get_publisher_address()
- self._valid = False
- self._icon = None
- self._icon_tries = 0
- self._owner = False
- self.add_service(service)
-
- def _request_buddy_icon_cb(self, result_status, response, user_data):
- """Callback when icon request has completed."""
- icon = response
- service = user_data
- if result_status == network.RESULT_SUCCESS:
- if icon and len(icon):
- icon = base64.b64decode(icon)
- print "Buddy icon for '%s' is size %d" % (self._nick_name, len(icon))
- self.set_icon(icon)
-
- if (result_status == network.RESULT_FAILED or not icon) and self._icon_tries < 3:
- self._icon_tries = self._icon_tries + 1
- print "Failed to retrieve buddy icon for '%s' on try %d of %d" % (self._nick_name, \
- self._icon_tries, 3)
- gobject.timeout_add(1000, self._request_buddy_icon, service)
+ 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._buddy = dbus.Interface(bobj, self._BUDDY_DBUS_INTERFACE)
+ self._buddy.connect_to_signal('IconChanged', self._icon_changed_cb)
+ self._buddy.connect_to_signal('ServiceAppeared', self._service_appeared_cb)
+ self._buddy.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
+ self._buddy.connect_to_signal('JoinedActivity', self._joined_activity_cb)
+ self._buddy.connect_to_signal('LeftActivity', self._left_activity_cb)
+
+ def object_path(self):
+ return self._object_path
+
+ def _emit_icon_changed_signal(self):
+ self.emit('IconChanged')
return False
- def _request_buddy_icon(self, service):
- """Contact the buddy to retrieve the buddy icon."""
- buddy_stream = Stream.Stream.new_from_service(service, start_reader=False)
- writer = buddy_stream.new_writer(service)
- success = writer.custom_request("get_buddy_icon", self._request_buddy_icon_cb, service)
- if not success:
- del writer, buddy_stream
- gobject.timeout_add(1000, self._request_buddy_icon, service)
+ def _icon_changed_cb(self):
+ gobject.idle_add(self._emit_icon_changed_signal)
+
+ def _emit_service_appeared_signal(self, object_path):
+ self.emit('ServiceAppeared', self._ps_new_object(object_path))
return False
- def add_service(self, service):
- """Adds a new service to this buddy's service list, returning
- True if the service was successfully added, and False if it was not."""
- if service.get_name() != self._nick_name:
- return False
- publisher_addr = service.get_publisher_address()
- if publisher_addr != self._address:
- logging.error('Service publisher and buddy address doesnt match: %s %s' % (publisher_addr, self._address))
- return False
- stype = service.get_type()
- if stype in self._services.keys():
- return False
- self._services[stype] = service
- if self._valid:
- self.emit("service-added", service)
-
- # If this is the first service we've seen that's owned by
- # a particular activity, send out the 'joined-activity' signal
- actid = service.get_activity_id()
- if actid is not None:
- found = False
- for serv in self._services.values():
- if serv.get_activity_id() == actid and serv.get_type() != stype:
- found = True
- break
- if not found:
- print "Buddy (%s) joined activity %s." % (self._nick_name, actid)
- self.emit("joined-activity", service)
-
- if stype == PRESENCE_SERVICE_TYPE:
- # A buddy isn't valid until its official presence
- # service has been found and resolved
- self._valid = True
- print 'Requesting buddy icon %s' % self._nick_name
- self._request_buddy_icon(service)
- return True
-
- def remove_service(self, service):
- """Remove a service from a buddy; ie, the activity was closed
- or the buddy went away."""
- if service.get_publisher_address() != self._address:
- return
- if service.get_name() != self._nick_name:
- return
- stype = service.get_type()
- if self._services.has_key(stype):
- if self._valid:
- self.emit("service-removed", service)
- del self._services[stype]
-
- # If this is the lase service owned by a particular activity,
- # and it's just been removed, send out the 'left-actvity' signal
- actid = service.get_activity_id()
- if actid is not None:
- found = False
- for serv in self._services.values():
- if serv.get_activity_id() == actid:
- found = True
- break
- if not found:
- print "Buddy (%s) left activity %s." % (self._nick_name, actid)
- self.emit("left-activity", service)
-
- if stype == PRESENCE_SERVICE_TYPE:
- self._valid = False
-
- def get_service_of_type(self, stype=None, activity=None):
- """Return a service of a certain type, or None if the buddy
- doesn't provide that service."""
- if not stype:
- raise RuntimeError("Need to specify a service type.")
-
- if activity:
- actid = activity.get_id()
- for service in self._services.values():
- if service.get_type() == stype and service.get_activity_id() == actid:
- return service
- if self._services.has_key(stype):
- return self._services[stype]
- return None
-
- def is_valid(self):
- """Return whether the buddy is valid or not. A buddy is
- not valid until its official presence service has been found
- and successfully resolved."""
- return self._valid
-
- def get_icon_pixbuf(self):
- if self._icon:
- pbl = gtk.gdk.PixbufLoader()
- pbl.write(self._icon)
- pbl.close()
- return pbl.get_pixbuf()
- else:
- return None
+ def _service_appeared_cb(self, object_path):
+ gobject.idle_add(self._emit_service_appeared_signal, object_path)
+
+ def _emit_service_disappeared_signal(self, object_path):
+ self.emit('ServiceDisappeared', self._ps_new_object(object_path))
+ return False
- def get_icon(self):
- """Return the buddies icon, if any."""
- return self._icon
-
- def get_address(self):
- return self._address
-
- def get_nick_name(self):
- return self._nick_name
-
- def set_icon(self, icon):
- """Can only set icon for other buddies. The Owner
- takes care of setting it's own icon."""
- if icon != self._icon:
- self._icon = icon
- self.emit("icon-changed")
-
- def is_owner(self):
- return self._owner
-
-
-class Owner(Buddy):
- """Class representing the owner of the machine. This is the client
- portion of the Owner, paired with the server portion in Owner.py."""
- def __init__(self, service):
- Buddy.__init__(self, service)
- self._owner = True
+ def _service_disappeared_cb(self, object_path):
+ gobject.idle_add(self._emit_service_disappeared_signal, object_path)
+
+ def _emit_joined_activity_signal(self, object_path):
+ self.emit('JoinedActivity', self._ps_new_object(object_path))
+ return False
+
+ def _joined_activity_cb(self, object_path):
+ gobject.idle_add(self._emit_joined_activity_signal, object_path)
+
+ def _emit_left_activity_signal(self, object_path):
+ self.emit('LeftActivity', self._ps_new_object(object_path))
+ return False
+
+ def _left_activity_cb(self, object_path):
+ gobject.idle_add(self._emit_left_activity_signal, object_path)
+
+ def getProperties(self):
+ return self._buddy.getProperties()
+
+ def getIcon(self):
+ return self._buddy.getIcon()
+
+ def getServiceOfType(self, stype):
+ try:
+ object_path = self._buddy.getServiceOfType(stype)
+ except dbus_bindings.DBusException:
+ return None
+ return self._ps_new_object(object_path)
+
+ def getJoinedActivities(self):
+ try:
+ resp = self._buddy.getJoinedActivities()
+ except dbus_bindings.DBusException:
+ return []
+ acts = []
+ for item in resp:
+ acts.append(self._ps_new_object(item))
+ return acts