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@redhat.com>2006-06-12 22:31:26 (GMT)
committer Dan Williams <dcbw@redhat.com>2006-06-12 22:31:26 (GMT)
commit17c371119dfff8285775e6cb69af97433595ac55 (patch)
tree7af4ec838dff1763217b84de26f9fb4129c5fa5d /sugar/presence/Buddy.py
parentd931dca5799ee1e88ce327bf28424f9739f4ad87 (diff)
More presence service rework
Diffstat (limited to 'sugar/presence/Buddy.py')
-rw-r--r--sugar/presence/Buddy.py144
1 files changed, 82 insertions, 62 deletions
diff --git a/sugar/presence/Buddy.py b/sugar/presence/Buddy.py
index 5201a04..9d94b9d 100644
--- a/sugar/presence/Buddy.py
+++ b/sugar/presence/Buddy.py
@@ -1,46 +1,108 @@
import pwd
import os
+import base64
import pygtk
pygtk.require('2.0')
-import gtk
+import gtk, gobject
+from sugar.p2p import Stream
+from sugar.p2p import network
-#from sugar import env
PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
-class Buddy(object):
+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,
+ ([])),
+ 'service-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'service-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT]))
+ }
+
def __init__(self, service):
+ gobject.GObject.__init__(self)
self._services = {}
self._nick_name = service.get_name()
self._address = service.get_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)
+ 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)
+ return False
+
def add_service(self, service):
- """Adds a new service to this buddy's service list."""
+ """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
+ if service.get_address() != self._address:
+ return False
if service.get_type() in self._services.keys():
- return
- self._services.keys[service.get_type()] = service
- # FIXME: send out signal for new service found
+ return False
+ self._services[service.get_type()] = service
+ if self._valid:
+ self.emit("service-added", service)
if service.get_type() == PRESENCE_SERVICE_TYPE:
# A buddy isn't valid until its official presence
# service has been found and resolved
self._valid = True
+ 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_type() in self._services.keys():
+ if service.get_address() != self._address:
+ return
+ if service.get_name() != self._nick_name:
+ return
+ if self._services.has_key(service.get_type()):
+ if self._valid:
+ self.emit("service-removed", service)
del self._services[service.get_type()]
if service.get_type() == PRESENCE_SERVICE_TYPE:
self._valid = False
+ def get_service_of_type(self, stype):
+ """Return a service of a certain type, or None if the buddy
+ doesn't provide that 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
@@ -63,65 +125,23 @@ class Buddy(object):
def get_address(self):
return self._address
- def add_service(self, service):
- if service.get_name() != self._nick_name:
- return False
- if service.get_address() != self._address:
- return False
- if self._services.has_key(service.get_type()):
- return False
- self._services[service.get_type()] = service
-
- def remove_service(self, stype):
- if self._services.has_key(stype):
- del self._services[stype]
-
- def get_service(self, stype):
- if self._services.has_key(stype):
- return self._services[stype]
- return None
-
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."""
- self._icon = icon
- # FIXME: do callbacks for icon-changed
-
+ if icon != self._icon:
+ self._icon = icon
+ self.emit("icon-changed")
-class Owner(Buddy):
- """Class representing the owner of this machine/instance."""
- def __init__(self):
- nick = env.get_nick_name()
- if not nick:
- nick = pwd.getpwuid(os.getuid())[0]
- if not nick or not len(nick):
- nick = "n00b"
-
- Buddy.__init__(self)
-
- user_dir = env.get_user_dir()
- if not os.path.exists(user_dir):
- try:
- os.makedirs(user_dir)
- except OSError:
- print 'Could not create user directory.'
-
- for fname in os.listdir(user_dir):
- if not fname.startswith("buddy-icon."):
- continue
- fd = open(os.path.join(user_dir, fname), "r")
- self._icon = fd.read()
- fd.close()
- break
+ def is_owner(self):
+ return self._owner
- def set_icon(self, icon):
- """Can only set icon in constructor for now."""
- pass
-
- def add_service(self, service):
- """Do nothing here, since all services we need to know about
- are registered with us by our group."""
- pass
+
+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