Welcome to mirror list, hosted at ThFree Co, Russian Federation.

events.py « common « src - dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8dbf17a3190d0b964bc607effa5f7bb7cca5472a (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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
## common/events.py
##
## Contributors for this file:
##	- Yann Leboulanger <asterix@lagaule.org>
##
## Copyright (C) 2006 Yann Leboulanger <asterix@lagaule.org>
##                    Vincent Hanquez <tab@snarc.org>
##                    Nikos Kouremenos <kourem@gmail.com>
##                    Dimitur Kirov <dkirov@gmail.com>
##                    Travis Shirk <travis@pobox.com>
##                    Norman Rasmussen <norman@rasmussen.co.za>
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de> 
##
## This file is part of Gajim.
##
## Gajim 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; version 3 only.
##
## Gajim 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 Gajim.  If not, see <http://www.gnu.org/licenses/>.
##

import time

class Event:
	'''Information concerning each event'''
	def __init__(self, type_, time_, parameters, show_in_roster = False,
	show_in_systray = True):
		''' type_ in chat, normal, file-request, file-error, file-completed,
		file-request-error, file-send-error, file-stopped, gc_msg, pm,
		printed_chat, printed_gc_msg, printed_marked_gc_msg, printed_pm
		parameters is (per type_):
			chat, normal, pm: [message, subject, kind, time, encrypted, resource,
			msg_id]
				where kind in error, incoming
			file-*: file_props
			gc_msg: None
			printed_chat: control
			printed_*: None
				messages that are already printed in chat, but not read'''
		self.type_ = type_
		self.time_ = time_
		self.parameters = parameters
		self.show_in_roster = show_in_roster
		self.show_in_systray = show_in_systray
		# Set when adding the event
		self.jid = None
		self.account = None

class Events:
	'''Information concerning all events'''
	def __init__(self):
		self._events = {} # list of events {acct: {jid1: [E1, E2]}, }
		self._event_added_listeners = []
		self._event_removed_listeners = []

	def event_added_subscribe(self, listener):
		'''Add a listener when an event is added to the queue'''
		if not listener in self._event_added_listeners:
			self._event_added_listeners.append(listener)

	def event_added_unsubscribe(self, listener):
		'''Remove a listener when an event is added to the queue'''
		if listener in self._event_added_listeners:
			self._event_added_listeners.remove(listener)

	def event_removed_subscribe(self, listener):
		'''Add a listener when an event is removed from the queue'''
		if not listener in self._event_removed_listeners:
			self._event_removed_listeners.append(listener)

	def event_removed_unsubscribe(self, listener):
		'''Remove a listener when an event is removed from the queue'''
		if listener in self._event_removed_listeners:
			self._event_removed_listeners.remove(listener)

	def fire_event_added(self, event):
		for listener in self._event_added_listeners:
			listener(event)

	def fire_event_removed(self, event_list):
		for listener in self._event_removed_listeners:
			listener(event_list)

	def change_account_name(self, old_name, new_name):
		if self._events.has_key(old_name):
			self._events[new_name] = self._events[old_name]
			del self._events[old_name]

	def add_account(self, account):
		self._events[account] = {}

	def get_accounts(self):
		return self._events.keys()

	def remove_account(self, account):
		del self._events[account]

	def create_event(self, type_, parameters, time_ = time.time(),
	show_in_roster = False, show_in_systray = True):
		return Event(type_, time_, parameters, show_in_roster,
			show_in_systray)

	def add_event(self, account, jid, event):
		# No such account before ?
		if not self._events.has_key(account):
			self._events[account] = {jid: [event]}
		# no such jid before ?
		elif not self._events[account].has_key(jid):
			self._events[account][jid] = [event]
		else:
			self._events[account][jid].append(event)
		event.jid = jid
		event.account = account
		self.fire_event_added(event)

	def remove_events(self, account, jid, event = None, types = []):
		'''if event is not specified, remove all events from this jid,
		optionally only from given type
		return True if no such event found'''
		if not self._events.has_key(account):
			return True
		if not self._events[account].has_key(jid):
			return True
		if event: # remove only one event
			if event in self._events[account][jid]:
				if len(self._events[account][jid]) == 1:
					del self._events[account][jid]
				else:
					self._events[account][jid].remove(event)
				self.fire_event_removed([event])
				return
			else:
				return True
		if types:
			new_list = [] # list of events to keep
			removed_list = [] # list of removed events
			for ev in self._events[account][jid]:
				if ev.type_ not in types:
					new_list.append(ev)
				else:
					removed_list.append(ev)
			if len(new_list) == len(self._events[account][jid]):
				return True
			if new_list:
				self._events[account][jid] = new_list
			else:
				del self._events[account][jid]
			self.fire_event_removed(removed_list)
			return
		# no event nor type given, remove them all
		self.fire_event_removed(self._events[account][jid])
		del self._events[account][jid]

	def change_jid(self, account, old_jid, new_jid):
		if not self._events[account].has_key(old_jid):
			return
		if self._events[account].has_key(new_jid):
			self._events[account][new_jid] += self._events[account][old_jid]
		else:
			self._events[account][new_jid] = self._events[account][old_jid]
		del self._events[account][old_jid]

	def get_nb_events(self, types = [], account = None):
		return self._get_nb_events(types = types, account = account)

	def get_events(self, account, jid = None, types = []):
		'''returns all events from the given account of the form
		{jid1: [], jid2: []}
		if jid is given, returns all events from the given jid in a list: []
		optionally only from given type'''
		if not self._events.has_key(account):
			return []
		if not jid:
			events_list = {} # list of events
			for jid_ in self._events[account]:
				events = []
				for ev in self._events[account][jid_]:
					if not types or ev.type_ in types:
						events.append(ev)
				if events:
					events_list[jid_] = events
			return events_list
		if not self._events[account].has_key(jid):
			return []
		events_list = [] # list of events
		for ev in self._events[account][jid]:
			if not types or ev.type_ in types:
				events_list.append(ev)
		return events_list

	def get_first_event(self, account, jid = None, type_ = None):
		'''Return the first event of type type_ if given'''
		events_list = self.get_events(account, jid, type_)
		# be sure it's bigger than latest event
		first_event_time = time.time() + 1
		first_event = None
		for event in events_list:
			if event.time_ < first_event_time:
				first_event_time = event.time_
				first_event = event
		return first_event

	def _get_nb_events(self, account = None, jid = None, attribute = None,
		types = []):
		'''return the number of pending events'''
		nb = 0
		if account:
			accounts = [account]
		else:
			accounts = self._events.keys()
		for acct in accounts:
			if not self._events.has_key(acct):
				continue
			if jid:
				jids = [jid]
			else:
				jids = self._events[acct].keys()
			for j in jids:
				if not self._events[acct].has_key(j):
					continue
				for event in self._events[acct][j]:
					if types and event.type_ not in types:
						continue
					if not attribute or \
					attribute == 'systray' and event.show_in_systray or \
					attribute == 'roster' and event.show_in_roster:
						nb += 1
		return nb

	def _get_some_events(self, attribute):
		'''attribute in systray, roster'''
		events = {}
		for account in self._events:
			events[account] = {}
			for jid in self._events[account]:
				events[account][jid] = []
				for event in self._events[account][jid]:
					if attribute == 'systray' and event.show_in_systray or \
					attribute == 'roster' and event.show_in_roster:
						events[account][jid].append(event)
				if not events[account][jid]:
					del events[account][jid]
			if not events[account]:
				del events[account]
		return events

	def _get_first_event_with_attribute(self, events):
		'''get the first event
		events is in the form {account1: {jid1: [ev1, ev2], },. }'''
		# be sure it's bigger than latest event
		first_event_time = time.time() + 1
		first_account = None
		first_jid = None
		first_event = None
		for account in events:
			for jid in events[account]:
				for event in events[account][jid]:
					if event.time_ < first_event_time:
						first_event_time = event.time_
						first_account = account
						first_jid = jid
						first_event = event
		return first_account, first_jid, first_event

	def get_nb_systray_events(self, types = []):
		'''returns the number of events displayed in roster'''
		return self._get_nb_events(attribute = 'systray', types = types)

	def get_systray_events(self):
		'''return all events that must be displayed in systray:
		{account1: {jid1: [ev1, ev2], },. }'''
		return self._get_some_events('systray')

	def get_first_systray_event(self):
		events = self.get_systray_events()
		return self._get_first_event_with_attribute(events)

	def get_nb_roster_events(self, account = None, jid = None, types = []):
		'''returns the number of events displayed in roster'''
		return self._get_nb_events(attribute = 'roster', account = account,
			jid = jid, types = types)

	def get_roster_events(self):
		'''return all events that must be displayed in roster:
		{account1: {jid1: [ev1, ev2], },. }'''
		return self._get_some_events('roster')

# vim: se ts=3: