Refactor current activity handling to be top-level attributes and D-Bus signals, not stuck in the property dict

This commit is contained in:
Dan Williams 2006-09-26 13:31:14 -04:00
parent 31c69ed167
commit ce577a6376
2 changed files with 80 additions and 17 deletions

View File

@ -38,6 +38,11 @@ class BuddyDBusHelper(dbus.service.Object):
def Disappeared(self): def Disappeared(self):
pass pass
@dbus.service.signal(BUDDY_DBUS_INTERFACE,
signature="ao")
def CurrentActivityChanged(self, activities):
pass
@dbus.service.signal(BUDDY_DBUS_INTERFACE, @dbus.service.signal(BUDDY_DBUS_INTERFACE,
signature="") signature="")
def IconChanged(self): def IconChanged(self):
@ -94,11 +99,15 @@ class BuddyDBusHelper(dbus.service.Object):
color = self._parent.get_color() color = self._parent.get_color()
if color: if color:
props[_BUDDY_KEY_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 return props
@dbus.service.method(BUDDY_DBUS_INTERFACE,
in_signature="", out_signature="o")
def getCurrentActivity(self):
activity = self._parent.get_current_activity()
if not activity:
raise NotFoundError()
return activity.object_path()
class Buddy(object): class Buddy(object):
"""Represents another person on the network and keeps track of the """Represents another person on the network and keeps track of the
@ -226,8 +235,7 @@ class Buddy(object):
self._valid = True self._valid = True
self._get_buddy_icon(service) self._get_buddy_icon(service)
self._color = service.get_one_property(_BUDDY_KEY_COLOR) self._color = service.get_one_property(_BUDDY_KEY_COLOR)
if self._color: self._current_activity = service.get_one_property(_BUDDY_KEY_CURACT)
self._dbus_helper.PropertyChanged([_BUDDY_KEY_COLOR])
# Monitor further buddy property changes, like current activity # Monitor further buddy property changes, like current activity
# and color # and color
service.connect('property-changed', service.connect('property-changed',
@ -244,26 +252,50 @@ class Buddy(object):
self._color = new_color self._color = new_color
self._dbus_helper.PropertyChanged([_BUDDY_KEY_COLOR]) self._dbus_helper.PropertyChanged([_BUDDY_KEY_COLOR])
if _BUDDY_KEY_CURACT in keys: if _BUDDY_KEY_CURACT in keys:
# Three cases here:
# 1) Buddy didn't publish a 'curact' key at all; we do nothing
# 2) Buddy published a blank/zero-length 'curact' key; we send
# a current-activity-changed signal for no activity
# 3) Buddy published a non-zero-length 'curact' key; we send
# a current-activity-changed signal if we know about the
# activity already, if not we postpone until the activity
# is found on the network and added to the buddy
new_curact = service.get_one_property(_BUDDY_KEY_CURACT) new_curact = service.get_one_property(_BUDDY_KEY_CURACT)
if new_curact and self._current_activity != new_curact: if new_curact and self._current_activity != new_curact:
if not len(new_curact):
new_curact = None
self._current_activity = new_curact self._current_activity = new_curact
self._dbus_helper.PropertyChanged([_BUDDY_KEY_CURACT]) if self._activities.has_key(self._current_activity):
# Case (3) above, valid activity id
activity = self._activities[self._current_activity]
if activity.is_valid():
self._dbus_helper.CurrentActivityChanged([activity.object_path()])
elif not self._current_activity:
# Case (2) above, no current activity
self._dbus_helper.CurrentActivityChanged([])
def __find_service_by_activity_id(self, actid):
for serv in self._services.values():
if serv.get_activity_id() == actid:
return serv
return None
def add_activity(self, activity): def add_activity(self, activity):
actid = activity.get_id()
if activity in self._activities.values(): if activity in self._activities.values():
raise RuntimeError("Tried to add activity twice") raise RuntimeError("Tried to add activity twice")
found = False actid = activity.get_id()
for serv in self._services.values(): if not self.__find_service_by_activity_id(actid):
if serv.get_activity_id() == activity.get_id():
found = True
break
if not found:
raise RuntimeError("Tried to add activity for which we had no service") raise RuntimeError("Tried to add activity for which we had no service")
self._activities[actid] = activity self._activities[actid] = activity
if activity.is_valid(): if activity.is_valid():
self._dbus_helper.JoinedActivity(activity.object_path()) self._dbus_helper.JoinedActivity(activity.object_path())
# If when we received a current activity update from the buddy,
# but didn't know about that activity yet, and now we do know about
# it, we need to send out the changed activity signal
if actid == self._current_activity:
self._dbus_helper.CurrentActivityChanged([activity.object_path()])
def remove_service(self, service): def remove_service(self, service):
"""Remove a service from a buddy; ie, the activity was closed """Remove a service from a buddy; ie, the activity was closed
or the buddy went away.""" or the buddy went away."""
@ -296,6 +328,12 @@ class Buddy(object):
if activity.is_valid(): if activity.is_valid():
self._dbus_helper.LeftActivity(activity.object_path()) self._dbus_helper.LeftActivity(activity.object_path())
# If we just removed the buddy's current activity,
# send out a signal
if actid == self._current_activity:
self._current_activity = None
self._dbus_helper.CurrentActivityChanged([])
def get_joined_activities(self): def get_joined_activities(self):
acts = [] acts = []
for act in self._activities.values(): for act in self._activities.values():
@ -340,7 +378,11 @@ class Buddy(object):
return self._color return self._color
def get_current_activity(self): def get_current_activity(self):
return self._current_activity if not self._current_activity:
return None
if not self._activities.has_key(self._current_activity):
return None
return self._activities[self._current_activity]
def _set_icon(self, icon): def _set_icon(self, icon):
"""Can only set icon for other buddies. The Owner """Can only set icon for other buddies. The Owner

View File

@ -18,6 +18,8 @@ class Buddy(gobject.GObject):
'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])), ([gobject.TYPE_PYOBJECT])),
'property-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'property-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'current-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])) ([gobject.TYPE_PYOBJECT]))
} }
@ -39,8 +41,15 @@ class Buddy(gobject.GObject):
self._buddy.connect_to_signal('JoinedActivity', self._joined_activity_cb) 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('LeftActivity', self._left_activity_cb)
self._buddy.connect_to_signal('PropertyChanged', self._property_changed_cb) self._buddy.connect_to_signal('PropertyChanged', self._property_changed_cb)
self._buddy.connect_to_signal('CurrentActivityChanged', self._current_activity_changed_cb)
self._properties = self._get_properties_helper() self._properties = self._get_properties_helper()
self._current_activity = None
try:
self._current_activity = self._buddy.getCurrentActivity()
except Exception, e:
pass
def _get_properties_helper(self): def _get_properties_helper(self):
props = self._buddy.getProperties() props = self._buddy.getProperties()
if not props: if not props:
@ -99,6 +108,18 @@ class Buddy(gobject.GObject):
def _property_changed_cb(self, prop_list): def _property_changed_cb(self, prop_list):
gobject.idle_add(self._handle_property_changed_signal, prop_list) gobject.idle_add(self._handle_property_changed_signal, prop_list)
def _handle_current_activity_changed_signal(self, act_list):
if len(act_list) == 0:
self._current_activity = None
self.emit('current-activity-changed')
else:
self._current_activity = act_list[0]
self.emit('current-activity-changed', self._ps_new_object(act_list[0]))
return False
def _current_activity_changed_cb(self, act_list):
gobject.idle_add(self._handle_current_activity_changed_signal, act_list)
def get_name(self): def get_name(self):
return self._properties['name'] return self._properties['name']
@ -115,9 +136,9 @@ class Buddy(gobject.GObject):
return self._buddy.getIcon() return self._buddy.getIcon()
def get_current_activity(self): def get_current_activity(self):
if self._properties.has_key('curact'): if not self._current_activity:
return self._properties['curact'] return None
return None return self._ps_new_object(self._current_activity)
def get_icon_pixbuf(self): def get_icon_pixbuf(self):
icon = self._buddy.getIcon() icon = self._buddy.getIcon()