diff options
author | Marco Pesenti Gritti <marco@localhost.localdomain> | 2006-09-15 11:54:16 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <marco@localhost.localdomain> | 2006-09-15 11:54:16 (GMT) |
commit | 5f99dcf9a5375847c970cfd769b3c85b84cf66b0 (patch) | |
tree | 69ebda2095a13a9fdef14eda2daa0b08da24a268 /services/presence/Activity.py | |
parent | bcc1740f7f514f04629cecb7536c93d4feaf83cf (diff) |
Move the presence service out of the shell
Diffstat (limited to 'services/presence/Activity.py')
-rw-r--r-- | services/presence/Activity.py | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/services/presence/Activity.py b/services/presence/Activity.py new file mode 100644 index 0000000..6dc9497 --- /dev/null +++ b/services/presence/Activity.py @@ -0,0 +1,171 @@ +import dbus + +PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp" +ACTIVITY_DBUS_OBJECT_PATH = "/org/laptop/Presence/Activities/" +ACTIVITY_DBUS_INTERFACE = "org.laptop.Presence.Activity" + +class NotFoundError(Exception): + pass + +class ActivityDBusHelper(dbus.service.Object): + def __init__(self, parent, bus_name, object_path): + self._parent = parent + self._bus_name = bus_name + self._object_path = object_path + dbus.service.Object.__init__(self, bus_name, self._object_path) + + @dbus.service.method(ACTIVITY_DBUS_INTERFACE, + in_signature="s", out_signature="ao") + def getServicesOfType(self, stype): + services = self._parent.get_services_of_type(stype) + if not services: + raise NotFoundError("Not found") + ret = [] + for serv in services: + ret.append(serv.object_path()) + return ret + + @dbus.service.method(ACTIVITY_DBUS_INTERFACE, + in_signature="", out_signature="ao") + def getServices(self): + services = self._parent.get_services() + if not services: + raise NotFoundError("Not found") + ret = [] + for serv in services: + ret.append(serv.object_path()) + return ret + + @dbus.service.method(ACTIVITY_DBUS_INTERFACE, + in_signature="", out_signature="s") + def getId(self): + 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, + in_signature="", out_signature="ao") + def getJoinedBuddies(self): + buddies = self._parent.get_joined_buddies() + if not buddies: + raise NotFoundError("Not found") + ret = [] + for buddy in buddies: + ret.append(buddy.object_path()) + return ret + + @dbus.service.signal(ACTIVITY_DBUS_INTERFACE, + signature="o") + def ServiceAppeared(self, object_path): + pass + + @dbus.service.signal(ACTIVITY_DBUS_INTERFACE, + signature="o") + def ServiceDisappeared(self, object_path): + pass + + @dbus.service.signal(ACTIVITY_DBUS_INTERFACE, + signature="o") + def BuddyJoined(self, object_path): + pass + + @dbus.service.signal(ACTIVITY_DBUS_INTERFACE, + signature="o") + def BuddyLeft(self, object_path): + pass + + +class Activity(object): + def __init__(self, bus_name, object_id, initial_service): + if not initial_service.get_activity_id(): + raise ValueError("Service must have a valid Activity ID") + self._activity_id = initial_service.get_activity_id() + + self._buddies = [] + self._services = {} # service type -> list of Services + self._color = None + self._valid = False + + self._object_id = object_id + self._object_path = "/org/laptop/Presence/Activities/%d" % self._object_id + self._dbus_helper = ActivityDBusHelper(self, bus_name, self._object_path) + + self.add_service(initial_service) + + def object_path(self): + 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): + return self._activity_id + + def get_color(self): + return self._color + + def get_services(self): + ret = [] + for serv_list in self._services.values(): + for service in serv_list: + if service not in ret: + ret.append(service) + return ret + + def get_services_of_type(self, stype): + if self._services.has_key(stype): + return self._services[stype] + return None + + def get_joined_buddies(self): + buddies = [] + for serv_list in self._services.values(): + for serv in serv_list: + owner = serv.get_owner() + if not owner in buddies and owner.is_valid(): + buddies.append(owner) + return buddies + + def add_service(self, service): + stype = service.get_type() + if not self._services.has_key(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 + # service from the buddy that we've seen + buddies = self.get_joined_buddies() + serv_owner = service.get_owner() + if serv_owner and serv_owner not in buddies and serv_owner.is_valid(): + self._dbus_helper.BuddyJoined(serv_owner.object_path()) + serv_owner.add_activity(self) + + if not service in self._services[stype]: + self._services[stype].append(service) + self._dbus_helper.ServiceAppeared(service.object_path()) + + def remove_service(self, service): + stype = service.get_type() + if not self._services.has_key(stype): + return + self._services[stype].remove(service) + self._dbus_helper.ServiceDisappeared(service.object_path()) + if len(self._services[stype]) == 0: + del self._services[stype] + + # Send out the BuddyLeft signal if this is the last + # service from the buddy + buddies = self.get_joined_buddies() + serv_owner = service.get_owner() + if serv_owner and serv_owner not in buddies and serv_owner.is_valid(): + serv_owner.remove_activity(self) + self._dbus_helper.BuddyLeft(serv_owner.object_path()) |