Newer
Older

Yann Leboulanger
committed
## common/events.py
##
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
##
## Copyright (C) 2006 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>

Yann Leboulanger
committed
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
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
##
## 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; version 2 only.
##
## 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.
##
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_pm
parameters is (per type_):
chat, normal: [message, subject, kind, time, encrypted, resource,
msg_id]
where kind in error, incoming
file-*: file_props
gc_msg: None
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
class Events:
'''Information concerning all events'''
def __init__(self):
self._events = {} # list of events {acct: {jid1: [E1, E2]}, }

Yann Leboulanger
committed
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)

Yann Leboulanger
committed
def fire_event_removed(self, event_list):

Yann Leboulanger
committed
for listener in self._event_removed_listeners:

Yann Leboulanger
committed
listener(event_list)

Yann Leboulanger
committed
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)

Yann Leboulanger
committed
self.fire_event_added(event)

Yann Leboulanger
committed
def remove_events(self, account, jid, event = None, types = []):
'''if event is not specified, remove all events from this jid,

Yann Leboulanger
committed
optionnaly 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)

Yann Leboulanger
committed
self.fire_event_removed([event])

Yann Leboulanger
committed
return
else:
return True
if types:
new_list = [] # list of events to keep

Yann Leboulanger
committed
removed_list = [] # list of removed events

Yann Leboulanger
committed
for ev in self._events[account][jid]:
if ev.type_ not in types:
new_list.append(ev)

Yann Leboulanger
committed
else:
removed_list.append(ev)

Yann Leboulanger
committed
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]

Yann Leboulanger
committed
self.fire_event_removed(removed_list)

Yann Leboulanger
committed
return
# no event nor type given, remove them all
del self._events[account][jid]

Yann Leboulanger
committed
self.fire_event_removed(self._events[account][jid])

Yann Leboulanger
committed

Yann Leboulanger
committed
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, ignore_types = []):
return self._get_nb_events(types = types, account = account,
ignore_types = ignore_types)

Yann Leboulanger
committed
def get_events(self, account, jid = None, types = []):
'''if event is not specified, get all events from this jid,

Yann Leboulanger
committed
optionnaly only from given type'''
if not self._events.has_key(account):
return []
if not jid:
return self._events[account]
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 = [], ignore_types = []):
'''return the number of pending events'''

Yann Leboulanger
committed
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 ignore_types and event.type_ in ignore_types:
continue

Yann Leboulanger
committed
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
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 = []):

nkour
committed
'''returns the number of events displayed in roster'''

Yann Leboulanger
committed
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'''

Yann Leboulanger
committed
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')