Fix buddy & activity visibility leaks if they are not yet valid; add Activity color attribute and don't make activity valid until we get the color
This commit is contained in:
parent
6b232d97d8
commit
ef47f6e4c5
@ -41,6 +41,11 @@ class ActivityDBusHelper(dbus.service.Object):
|
|||||||
def getId(self):
|
def getId(self):
|
||||||
return self._parent.get_id()
|
return self._parent.get_id()
|
||||||
|
|
||||||
|
@dbus.service.method(ACTIVITY_DBUS_INTERFACE,
|
||||||
|
in_signature="", out_signature="s")
|
||||||
|
def getColor(self):
|
||||||
|
return self._parent.get_color()
|
||||||
|
|
||||||
@dbus.service.method(ACTIVITY_DBUS_INTERFACE,
|
@dbus.service.method(ACTIVITY_DBUS_INTERFACE,
|
||||||
in_signature="", out_signature="ao")
|
in_signature="", out_signature="ao")
|
||||||
def getJoinedBuddies(self):
|
def getJoinedBuddies(self):
|
||||||
@ -81,6 +86,8 @@ class Activity(object):
|
|||||||
|
|
||||||
self._buddies = []
|
self._buddies = []
|
||||||
self._services = {} # service type -> list of Services
|
self._services = {} # service type -> list of Services
|
||||||
|
self._color = None
|
||||||
|
self._valid = False
|
||||||
|
|
||||||
self._object_id = object_id
|
self._object_id = object_id
|
||||||
self._object_path = "/org/laptop/Presence/Activities/%d" % self._object_id
|
self._object_path = "/org/laptop/Presence/Activities/%d" % self._object_id
|
||||||
@ -91,9 +98,16 @@ class Activity(object):
|
|||||||
def object_path(self):
|
def object_path(self):
|
||||||
return dbus.ObjectPath(self._object_path)
|
return dbus.ObjectPath(self._object_path)
|
||||||
|
|
||||||
|
def is_valid(self):
|
||||||
|
"""An activity is only valid when it's color is available."""
|
||||||
|
return self._valid
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return self._activity_id
|
return self._activity_id
|
||||||
|
|
||||||
|
def get_color(self):
|
||||||
|
return self._color
|
||||||
|
|
||||||
def get_services(self):
|
def get_services(self):
|
||||||
ret = []
|
ret = []
|
||||||
for serv_list in self._services.values():
|
for serv_list in self._services.values():
|
||||||
@ -112,7 +126,7 @@ class Activity(object):
|
|||||||
for serv_list in self._services.values():
|
for serv_list in self._services.values():
|
||||||
for serv in serv_list:
|
for serv in serv_list:
|
||||||
owner = serv.get_owner()
|
owner = serv.get_owner()
|
||||||
if not owner in buddies:
|
if not owner in buddies and owner.is_valid():
|
||||||
buddies.append(owner)
|
buddies.append(owner)
|
||||||
return buddies
|
return buddies
|
||||||
|
|
||||||
@ -121,11 +135,17 @@ class Activity(object):
|
|||||||
if not self._services.has_key(stype):
|
if not self._services.has_key(stype):
|
||||||
self._services[stype] = []
|
self._services[stype] = []
|
||||||
|
|
||||||
|
if not self._color:
|
||||||
|
color = service.get_one_property('color')
|
||||||
|
if color:
|
||||||
|
self._color = color
|
||||||
|
self._valid = True
|
||||||
|
|
||||||
# Send out the BuddyJoined signal if this is the first
|
# Send out the BuddyJoined signal if this is the first
|
||||||
# service from the buddy that we've seen
|
# service from the buddy that we've seen
|
||||||
buddies = self.get_joined_buddies()
|
buddies = self.get_joined_buddies()
|
||||||
serv_owner = service.get_owner()
|
serv_owner = service.get_owner()
|
||||||
if serv_owner and serv_owner not in buddies:
|
if serv_owner and serv_owner not in buddies and serv_owner.is_valid():
|
||||||
self._dbus_helper.BuddyJoined(serv_owner.object_path())
|
self._dbus_helper.BuddyJoined(serv_owner.object_path())
|
||||||
serv_owner.add_activity(self)
|
serv_owner.add_activity(self)
|
||||||
|
|
||||||
@ -146,6 +166,6 @@ class Activity(object):
|
|||||||
# service from the buddy
|
# service from the buddy
|
||||||
buddies = self.get_joined_buddies()
|
buddies = self.get_joined_buddies()
|
||||||
serv_owner = service.get_owner()
|
serv_owner = service.get_owner()
|
||||||
if serv_owner and serv_owner not in buddies:
|
if serv_owner and serv_owner not in buddies and serv_owner.is_valid():
|
||||||
serv_owner.remove_activity(self)
|
serv_owner.remove_activity(self)
|
||||||
self._dbus_helper.BuddyLeft(serv_owner.object_path())
|
self._dbus_helper.BuddyLeft(serv_owner.object_path())
|
||||||
|
@ -65,6 +65,8 @@ class BuddyDBusHelper(dbus.service.Object):
|
|||||||
in_signature="", out_signature="ao")
|
in_signature="", out_signature="ao")
|
||||||
def getJoinedActivities(self):
|
def getJoinedActivities(self):
|
||||||
acts = []
|
acts = []
|
||||||
|
for act in self._parent.get_joined_activities():
|
||||||
|
acts.append(act.object_path())
|
||||||
return acts
|
return acts
|
||||||
|
|
||||||
@dbus.service.method(BUDDY_DBUS_INTERFACE,
|
@dbus.service.method(BUDDY_DBUS_INTERFACE,
|
||||||
@ -181,7 +183,8 @@ class Buddy(object):
|
|||||||
if not found:
|
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
|
||||||
self._dbus_helper.JoinedActivity(activity.object_path())
|
if activity.is_valid():
|
||||||
|
self._dbus_helper.JoinedActivity(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
|
||||||
@ -204,8 +207,15 @@ class Buddy(object):
|
|||||||
if not self._activities.has_key(actid):
|
if not self._activities.has_key(actid):
|
||||||
return
|
return
|
||||||
del self._activities[actid]
|
del self._activities[actid]
|
||||||
print "Buddy (%s) left activity %s." % (self._nick_name, actid)
|
if activity.is_valid():
|
||||||
self._dbus_helper.LeftActivity(activity.object_path())
|
self._dbus_helper.LeftActivity(activity.object_path())
|
||||||
|
|
||||||
|
def get_joined_activities(self):
|
||||||
|
acts = []
|
||||||
|
for act in self._activities.values():
|
||||||
|
if act.is_valid():
|
||||||
|
acts.append(act)
|
||||||
|
return acts
|
||||||
|
|
||||||
def get_service_of_type(self, stype=None, activity=None):
|
def get_service_of_type(self, stype=None, activity=None):
|
||||||
"""Return a service of a certain type, or None if the buddy
|
"""Return a service of a certain type, or None if the buddy
|
||||||
@ -213,6 +223,9 @@ class Buddy(object):
|
|||||||
if not stype:
|
if not stype:
|
||||||
raise RuntimeError("Need to specify a service type.")
|
raise RuntimeError("Need to specify a service type.")
|
||||||
|
|
||||||
|
if activity and not activity.is_valid():
|
||||||
|
raise RuntimeError("Activity is not yet valid.")
|
||||||
|
|
||||||
if activity:
|
if activity:
|
||||||
actid = activity.get_id()
|
actid = activity.get_id()
|
||||||
for service in self._services.values():
|
for service in self._services.values():
|
||||||
|
@ -302,24 +302,36 @@ class PresenceService(object):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_activities(self):
|
def get_activities(self):
|
||||||
return self._activities.values()
|
# Only return valid activities
|
||||||
|
ret = []
|
||||||
|
for act in self._activities.values():
|
||||||
|
if act.is_valid():
|
||||||
|
ret.append(act)
|
||||||
|
return ret
|
||||||
|
|
||||||
def get_activity(self, actid):
|
def get_activity(self, actid):
|
||||||
if self._activities.has_key(actid):
|
if self._activities.has_key(actid):
|
||||||
return self._activities[actid]
|
act = self._activities[actid]
|
||||||
|
if act.is_valid():
|
||||||
|
return act
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_buddies(self):
|
def get_buddies(self):
|
||||||
return self._buddies.values()
|
buddies = []
|
||||||
|
for buddy in self._buddies.values():
|
||||||
|
if buddy.is_valid():
|
||||||
|
buddies.append(buddy)
|
||||||
|
return buddies
|
||||||
|
|
||||||
def get_buddy_by_name(self, name):
|
def get_buddy_by_name(self, name):
|
||||||
if self._buddies.has_key(name):
|
if self._buddies.has_key(name):
|
||||||
return self._buddies[name]
|
if self._buddies[name].is_valid():
|
||||||
|
return self._buddies[name]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_buddy_by_address(self, address):
|
def get_buddy_by_address(self, address):
|
||||||
for buddy in self._buddies.values():
|
for buddy in self._buddies.values():
|
||||||
if buddy.get_address() == address:
|
if buddy.get_address() == address and buddy.is_valid():
|
||||||
return buddy
|
return buddy
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -379,17 +391,21 @@ class PresenceService(object):
|
|||||||
if not actid:
|
if not actid:
|
||||||
return
|
return
|
||||||
activity = None
|
activity = None
|
||||||
|
was_valid = False
|
||||||
if not self._activities.has_key(actid):
|
if not self._activities.has_key(actid):
|
||||||
objid = self._get_next_object_id()
|
objid = self._get_next_object_id()
|
||||||
activity = Activity.Activity(self._bus_name, objid, service)
|
activity = Activity.Activity(self._bus_name, objid, service)
|
||||||
self._activities[actid] = activity
|
self._activities[actid] = activity
|
||||||
self._dbus_helper.ActivityAppeared(activity.object_path())
|
|
||||||
else:
|
else:
|
||||||
activity = self._activities[actid]
|
activity = self._activities[actid]
|
||||||
|
was_valid = activity.is_valid()
|
||||||
|
|
||||||
if activity:
|
if activity:
|
||||||
activity.add_service(service)
|
activity.add_service(service)
|
||||||
|
|
||||||
|
if not was_valid and activity.is_valid():
|
||||||
|
self._dbus_helper.ActivityAppeared(activity.object_path())
|
||||||
|
|
||||||
def _handle_remove_activity_service(self, service):
|
def _handle_remove_activity_service(self, service):
|
||||||
actid = service.get_activity_id()
|
actid = service.get_activity_id()
|
||||||
if not actid:
|
if not actid:
|
||||||
@ -596,7 +612,11 @@ class PresenceService(object):
|
|||||||
if not len(services):
|
if not len(services):
|
||||||
raise NotFoundError("The service type %s was not present within the activity %s" % (stype, activity.object_path()))
|
raise NotFoundError("The service type %s was not present within the activity %s" % (stype, activity.object_path()))
|
||||||
act_service = services[0]
|
act_service = services[0]
|
||||||
return self._share_activity(activity.get_id(), stype, act_service.get_properties(),
|
props = act_service.get_properties()
|
||||||
|
color = activity.get_color()
|
||||||
|
if color:
|
||||||
|
props['color'] = color
|
||||||
|
return self._share_activity(activity.get_id(), stype, properties,
|
||||||
act_service.get_address(), act_service.get_port(), act_service.get_domain())
|
act_service.get_address(), act_service.get_port(), act_service.get_domain())
|
||||||
|
|
||||||
def share_activity(self, activity_id, stype, properties=None, address=None, port=-1, domain=u"local"):
|
def share_activity(self, activity_id, stype, properties=None, address=None, port=-1, domain=u"local"):
|
||||||
@ -615,6 +635,10 @@ class PresenceService(object):
|
|||||||
properties['port'] = port
|
properties['port'] = port
|
||||||
if port and port != -1 and (type(port) != type(1) or port <= 1024 or port >= 65535):
|
if port and port != -1 and (type(port) != type(1) or port <= 1024 or port >= 65535):
|
||||||
raise ValueError("port must be a number between 1024 and 65535")
|
raise ValueError("port must be a number between 1024 and 65535")
|
||||||
|
|
||||||
|
color = self._owner.get_color()
|
||||||
|
if color:
|
||||||
|
properties['color'] = color
|
||||||
|
|
||||||
logging.debug('Share activity %s, type %s, address %s, port %d, properties %s' % (activity_id, stype, address, port, properties))
|
logging.debug('Share activity %s, type %s, address %s, port %d, properties %s' % (activity_id, stype, address, port, properties))
|
||||||
return self.register_service(real_name, stype, properties, address, port, domain)
|
return self.register_service(real_name, stype, properties, address, port, domain)
|
||||||
@ -699,6 +723,7 @@ class PresenceService(object):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
from sugar import TracebackUtils
|
from sugar import TracebackUtils
|
||||||
|
env.read_profile()
|
||||||
loop = gobject.MainLoop()
|
loop = gobject.MainLoop()
|
||||||
ps = PresenceService()
|
ps = PresenceService()
|
||||||
tbh = TracebackUtils.TracebackHelper()
|
tbh = TracebackUtils.TracebackHelper()
|
||||||
|
@ -30,6 +30,7 @@ class Activity(gobject.GObject):
|
|||||||
self._activity.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
|
self._activity.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb)
|
||||||
|
|
||||||
self._id = None
|
self._id = None
|
||||||
|
self._color = None
|
||||||
|
|
||||||
def object_path(self):
|
def object_path(self):
|
||||||
return self._object_path
|
return self._object_path
|
||||||
@ -68,8 +69,10 @@ class Activity(gobject.GObject):
|
|||||||
self._id = self._activity.getId()
|
self._id = self._activity.getId()
|
||||||
return self._id
|
return self._id
|
||||||
|
|
||||||
def get_icon(self):
|
def get_color(self):
|
||||||
return self._buddy.getIcon()
|
if not self._color:
|
||||||
|
self._color = self._activity.getColor()
|
||||||
|
return self._color
|
||||||
|
|
||||||
def get_services(self):
|
def get_services(self):
|
||||||
resp = self._activity.getServices()
|
resp = self._activity.getServices()
|
||||||
|
Loading…
Reference in New Issue
Block a user