Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services/presence/Activity.py
diff options
context:
space:
mode:
Diffstat (limited to 'services/presence/Activity.py')
-rw-r--r--services/presence/Activity.py171
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())