comparison src/tools/trigger.py @ 1374:0befb14ecf62

renamed tools.misc to tools.trigger
author Goffi <goffi@goffi.org>
date Thu, 19 Mar 2015 19:44:37 +0100
parents src/tools/misc.py@ba41a81d14c2
children 069ad98b360d
comparison
equal deleted inserted replaced
1373:6d0e01809893 1374:0befb14ecf62
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # SAT: a jabber client
5 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org)
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 """Misc usefull classes"""
21
22 from sat.core.i18n import _
23 from sat.core.log import getLogger
24 log = getLogger(__name__)
25
26
27 class TriggerException(Exception):
28 pass
29
30
31 class SkipOtherTriggers(Exception):
32 """ Exception to raise if normal behaviour must be followed instead of
33 following triggers list """
34 pass
35
36
37 class TriggerManager(object):
38 """This class manage triggers: code which interact to change the behaviour
39 of SàT"""
40
41 try: # FIXME: to be removed when a better solution is found
42 MIN_PRIORITY = float('-inf')
43 MAX_PRIORITY = float('+inf')
44 except: # XXX: Pyjamas will bug if you specify ValueError here
45 # Pyjamas uses the JS Float class
46 MIN_PRIORITY = Number.NEGATIVE_INFINITY
47 MAX_PRIORITY = Number.POSITIVE_INFINITY
48
49 def __init__(self):
50 self.__triggers = {}
51
52 def add(self, point_name, callback, priority=0):
53 """Add a trigger to a point
54 @param point_name: name of the point when the trigger should be run
55 @param callback: method to call at the trigger point
56 @param priority: callback will be called in priority order, biggest
57 first
58 """
59 if point_name not in self.__triggers:
60 self.__triggers[point_name] = []
61 if priority != 0 and priority in [trigger_tuple[0] for trigger_tuple in self.__triggers[point_name]]:
62 if priority in (self.MIN_PRIORITY, self.MAX_PRIORITY):
63 log.warning(_("There is already a bound priority [%s]") % point_name)
64 else:
65 log.debug(_("There is already a trigger with the same priority [%s]") % point_name)
66 self.__triggers[point_name].append((priority, callback))
67 self.__triggers[point_name].sort(key=lambda trigger_tuple:
68 trigger_tuple[0], reverse=True)
69
70 def remove(self, point_name, callback):
71 """Remove a trigger from a point
72 @param point_name: name of the point when the trigger should be run
73 @param callback: method to remove, must exists in the trigger point"""
74 for trigger_tuple in self.__triggers[point_name]:
75 if trigger_tuple[1] == callback:
76 self.__triggers[point_name].remove(trigger_tuple)
77 return
78 raise TriggerException("Trying to remove an unexisting trigger")
79
80 def point(self, point_name, *args, **kwargs):
81 """This put a trigger point
82 All the trigger for that point will be run
83 @param point_name: name of the trigger point
84 @return: True if the action must be continued, False else"""
85 if point_name not in self.__triggers:
86 return True
87
88 for priority, trigger in self.__triggers[point_name]:
89 try:
90 if not trigger(*args, **kwargs):
91 return False
92 except SkipOtherTriggers:
93 break
94 return True