Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar

This commit is contained in:
Marco Pesenti Gritti 2006-09-22 21:50:20 +02:00
commit fc000346e4
4 changed files with 92 additions and 23 deletions

View File

@ -10,6 +10,9 @@ PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
BUDDY_DBUS_OBJECT_PATH = "/org/laptop/Presence/Buddies/"
BUDDY_DBUS_INTERFACE = "org.laptop.Presence.Buddy"
_BUDDY_KEY_COLOR = 'color'
_BUDDY_KEY_CURACT = 'curact'
class NotFoundError(Exception):
pass
@ -85,7 +88,10 @@ class BuddyDBusHelper(dbus.service.Object):
props['owner'] = self._parent.is_owner()
color = self._parent.get_color()
if color:
props['color'] = self._parent.get_color()
props[_BUDDY_KEY_COLOR] = self._parent.get_color()
curact = self._parent.get_current_activity()
if curact:
props[_BUDDY_KEY_CURACT] = self._parent.get_current_activity()
return props
@ -113,6 +119,7 @@ class Buddy(object):
self._nick_name = service.get_name()
self._address = service.get_source_address()
self._color = None
self._current_activity = None
self._valid = False
self._icon = None
self._icon_tries = 0
@ -121,6 +128,7 @@ class Buddy(object):
self._object_path = BUDDY_DBUS_OBJECT_PATH + str(self._object_id)
self._dbus_helper = BuddyDBusHelper(self, bus_name, self._object_path)
self._buddy_presence_service = None
if service is not None:
self.add_service(service)
@ -181,25 +189,48 @@ class Buddy(object):
service_key[1]))
return False
if service.get_type() == PRESENCE_SERVICE_TYPE and self._buddy_presence_service:
# already have a presence service for this buddy
logging.debug("!!! Tried to add a buddy presence service when " \
"one already existed.")
return False
logging.debug("Buddy %s added service type %s id %s" % (self._nick_name,
service.get_type(), service.get_activity_id()))
self._services[service_key] = service
service.set_owner(self)
if service.get_type() == PRESENCE_SERVICE_TYPE:
self._buddy_presence_service = service
# 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
logging.debug('Requesting buddy icon %s' % self._nick_name)
self._request_buddy_icon(service)
self._color = service.get_one_property('color')
self._color = service.get_one_property(_BUDDY_KEY_COLOR)
if self._color:
self._dbus_helper.PropertyChanged(['color'])
self._dbus_helper.PropertyChanged([_BUDDY_KEY_COLOR])
# Monitor further buddy property changes, like current activity
# and color
service.connect('property-changed',
self.__buddy_presence_service_property_changed_cb)
if self._valid:
self._dbus_helper.ServiceAppeared(service.object_path())
return True
def __buddy_presence_service_property_changed_cb(self, service, keys):
if _BUDDY_KEY_COLOR in keys:
new_color = service.get_one_property(_BUDDY_KEY_COLOR)
if new_color and self._color != new_color:
self._color = new_color
self._dbus_helper.PropertyChanged([_BUDDY_KEY_COLOR])
if _BUDDY_KEY_CURACT in keys:
new_curact = service.get_one_property(_BUDDY_KEY_CURACT)
if new_curact and self._current_activity != new_curact:
self._current_activity = new_curact
self._dbus_helper.PropertyChanged([_BUDDY_KEY_CURACT])
def add_activity(self, activity):
actid = activity.get_id()
if activity in self._activities.values():
@ -222,6 +253,13 @@ class Buddy(object):
return
if service.get_name() != self._nick_name:
return
if service.get_type() == PRESENCE_SERVICE_TYPE \
and self._buddy_presence_service \
and service != self._buddy_presence_service:
logging.debug("!!! Tried to remove a spurious buddy presence service.")
return
service_key = self._get_service_key(service)
if self._services.has_key(service_key):
if self._valid:
@ -282,6 +320,9 @@ class Buddy(object):
def get_color(self):
return self._color
def get_current_activity(self):
return self._current_activity
def _set_icon(self, icon):
"""Can only set icon for other buddies. The Owner
takes care of setting it's own icon."""

View File

@ -5,6 +5,7 @@ from sugar import util
import dbus, dbus.service
import random
import logging
import gobject
def compose_service_name(name, activity_id):
if type(name) == type(""):
@ -135,13 +136,19 @@ class ServiceDBusHelper(dbus.service.Object):
self._parent.set_properties(values, sender)
class Service(object):
class Service(gobject.GObject):
"""Encapsulates information about a specific ZeroConf/mDNS
service as advertised on the network."""
__gsignals__ = {
'property-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
def __init__(self, bus_name, object_id, name, stype, domain=u"local",
address=None, port=-1, properties=None, source_address=None,
local_publisher=None):
gobject.GObject.__init__(self)
if not bus_name:
raise ValueError("DBus bus name must be valid")
if not object_id or type(object_id) != type(1):
@ -178,7 +185,7 @@ class Service(object):
self._domain = domain
self._port = -1
self.set_port(port)
self._properties = None
self._properties = {}
self._dbus_helper = None
self._internal_set_properties(properties)
@ -252,6 +259,11 @@ class Service(object):
properties."""
return self._properties
def __emit_properties_changed_signal(self, keys):
if self._dbus_helper:
self._dbus_helper.PublishedValueChanged(keys)
self.emit('property-changed', keys)
def set_property(self, key, value, sender=None):
"""Set one service property"""
if not self._local_publisher:
@ -290,8 +302,7 @@ class Service(object):
if self._local_publisher and self._avahi_entry_group:
self.__internal_update_avahi_properties()
if self._dbus_helper:
self._dbus_helper.PublishedValueChanged([key])
self.__emit_properties_changed_signal([key])
def set_properties(self, properties, sender=None, from_network=False):
"""Set all service properties in one call"""
@ -306,13 +317,13 @@ class Service(object):
python dictionary."""
if type(properties) != type({}):
raise ValueError("Properties must be a dictionary.")
self._properties = {}
# Make sure the properties are actually different
diff_keys = _dicts_differ(self._properties, properties)
if len(diff_keys) == 0:
return
self._properties = {}
# Set key/value pairs on internal property list
for key, value in properties.items():
if len(key) == 0:
@ -329,8 +340,7 @@ class Service(object):
if self._local_publisher and self._avahi_entry_group and not from_network:
self.__internal_update_avahi_properties()
if self._dbus_helper:
self._dbus_helper.PublishedValueChanged(diff_keys)
self.__emit_properties_changed_signal(diff_keys)
def __internal_update_avahi_properties(self):
info = _convert_properties_to_dbus_byte_array(self._properties)

View File

@ -3,12 +3,18 @@ from sugar.canvas.IconColor import IconColor
class BuddyModel:
def __init__(self, buddy=None):
if buddy:
self.set_name(buddy.get_name())
self.set_color(buddy.get_color())
self._buddy = buddy
self._cur_activity = None
self._pservice = PresenceService.get_instance()
self._buddy = buddy
if self._buddy:
self.set_name(self._buddy.get_name())
self.set_color(self._buddy.get_color())
self._buddy.connect('property-changed',
self.__buddy_property_changed_cb)
else:
# if we don't have a buddy yet, connect to the PS
# and wait until the buddy pops up on the network
self._pservice.connect('buddy-appeared', self.__buddy_appeared_cb)
def set_name(self, name):
@ -24,7 +30,11 @@ class BuddyModel:
return self._color
def get_buddy(self):
if not self._buddy:
# If we have a buddy already, just return
if self._buddy:
return self._buddy
# Otherwise try to get the buddy from the PS
self._buddy = self._pservice.get_buddy_by_name(self._name)
if self._buddy:
self._buddy.connect('property-changed',
@ -32,10 +42,12 @@ class BuddyModel:
return self._buddy
def __buddy_appeared_cb(self, pservice, buddy):
# FIXME: use public key rather than buddy name
if not self._buddy and buddy.get_name() == self._name:
self.get_buddy()
def __buddy_property_changed_cb(self, buddy, keys):
# all we care about right now is current activity
curact = self._buddy.get_current_activity()
self._cur_activity = self._pservice.get_activity(curact)

View File

@ -36,7 +36,13 @@ class Buddy(gobject.GObject):
self._buddy.connect_to_signal('JoinedActivity', self._joined_activity_cb)
self._buddy.connect_to_signal('LeftActivity', self._left_activity_cb)
self._buddy.connect_to_signal('PropertyChanged', self._property_changed_cb)
self._properties = self._buddy.getProperties()
self._properties = self._get_properties_helper()
def _get_properties_helper(self):
props = self._buddy.getProperties()
if not props:
return {}
return props
def object_path(self):
return self._object_path
@ -77,7 +83,7 @@ class Buddy(gobject.GObject):
gobject.idle_add(self._emit_left_activity_signal, object_path)
def _handle_property_changed_signal(self, prop_list):
self._properties = self._buddy.getProperties()
self._properties = self._get_properties_helper()
self.emit('property-changed', prop_list)
return False