Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services/presence/Activity.py
blob: 065fb4984f42a731b7091f6be17607303407fdac (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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# Copyright (C) 2006, Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import dbus

PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
ACTIVITY_DBUS_OBJECT_PATH = "/org/laptop/Presence/Activities/"
ACTIVITY_DBUS_INTERFACE = "org.laptop.Presence.Activity"


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):
		ret = []
		for serv in self._parent.get_services_of_type(stype):
			ret.append(serv.object_path())
		return ret

	@dbus.service.method(ACTIVITY_DBUS_INTERFACE,
						in_signature="", out_signature="ao")
	def getServices(self):
		ret = []
		for serv in self._parent.get_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):
		ret = []
		for buddy in self._parent.get_joined_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 []

	def get_joined_buddies(self):
		buddies = []
		for serv_list in self._services.values():
			for serv in serv_list:
				owner = serv.get_owner()
				if owner and 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())