Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell/PresenceService/Activity.py
blob: 6aa27195227b30559c132ce555e1496768f57a87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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="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._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 get_id(self):
		return self._activity_id

	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:
					buddies.append(owner)
		return buddies

	def add_service(self, service):
		stype = service.get_type()
		if not self._services.has_key(stype):
			self._services[stype] = []

		# 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:
			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:
			serv_owner.remove_activity(self)
			self._dbus_helper.BuddyLeft(serv_owner.object_path())