1# This file is part of Gajim. 2# 3# Gajim is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published 5# by the Free Software Foundation; version 3 only. 6# 7# Gajim is distributed in the hope that it will be useful, 8# but WITHOUT ANY WARRANTY; without even the implied warranty of 9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# GNU General Public License for more details. 11# 12# You should have received a copy of the GNU General Public License 13# along with Gajim. If not, see <http://www.gnu.org/licenses/>. 14 15''' 16Network Events Controller. 17 18:author: Mateusz Biliński <mateusz@bilinski.it> 19:since: 10th August 2008 20:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it> 21:copyright: Copyright (2011) Yann Leboulanger <asterix@lagaule.org> 22:license: GPL 23''' 24 25from typing import List # pylint: disable=unused-import 26 27from gajim.common import app 28 29 30class NetworkEventsController: 31 def __init__(self): 32 self.incoming_events_generators = {} 33 ''' 34 Keys: names of events 35 Values: list of class objects that are subclasses 36 of `NetworkIncomingEvent` 37 ''' 38 self.outgoing_events_generators = {} 39 ''' 40 Keys: names of events 41 Values: list of class objects that are subclasses 42 of `NetworkOutgoingEvent` 43 ''' 44 45 def register_incoming_event(self, event_class): 46 for base_event_name in event_class.base_network_events: 47 event_list = self.incoming_events_generators.setdefault( 48 base_event_name, []) 49 if event_class not in event_list: 50 event_list.append(event_class) 51 52 def unregister_incoming_event(self, event_class): 53 for base_event_name in event_class.base_network_events: 54 if base_event_name in self.incoming_events_generators: 55 self.incoming_events_generators[base_event_name].remove( 56 event_class) 57 58 def register_outgoing_event(self, event_class): 59 for base_event_name in event_class.base_network_events: 60 event_list = self.outgoing_events_generators.setdefault( 61 base_event_name, []) 62 if event_class not in event_list: 63 event_list.append(event_class) 64 65 def unregister_outgoing_event(self, event_class): 66 for base_event_name in event_class.base_network_events: 67 if base_event_name in self.outgoing_events_generators: 68 self.outgoing_events_generators[base_event_name].remove( 69 event_class) 70 71 def push_incoming_event(self, event_object): 72 if event_object.generate(): 73 if not app.ged.raise_event(event_object.name, event_object): 74 self._generate_events_based_on_incoming_event(event_object) 75 76 def push_outgoing_event(self, event_object): 77 if event_object.generate(): 78 if not app.ged.raise_event(event_object.name, event_object): 79 self._generate_events_based_on_outgoing_event(event_object) 80 81 def _generate_events_based_on_incoming_event(self, event_object): 82 ''' 83 :return: True if even_object should be dispatched through Global 84 Events Dispatcher, False otherwise. This can be used to replace 85 base events with those that more data computed (easier to use 86 by handlers). 87 :note: replacing mechanism is not implemented currently, but will be 88 based on attribute in new network events object. 89 ''' 90 base_event_name = event_object.name 91 if base_event_name in self.incoming_events_generators: 92 for new_event_class in self.incoming_events_generators[ 93 base_event_name]: 94 new_event_object = new_event_class( 95 None, base_event=event_object) 96 if new_event_object.generate(): 97 if not app.ged.raise_event(new_event_object.name, 98 new_event_object): 99 self._generate_events_based_on_incoming_event( 100 new_event_object) 101 102 def _generate_events_based_on_outgoing_event(self, event_object): 103 ''' 104 :return: True if even_object should be dispatched through Global 105 Events Dispatcher, False otherwise. This can be used to replace 106 base events with those that more data computed (easier to use 107 by handlers). 108 :note: replacing mechanism is not implemented currently, but will be 109 based on attribute in new network events object. 110 ''' 111 base_event_name = event_object.name 112 if base_event_name in self.outgoing_events_generators: 113 for new_event_class in self.outgoing_events_generators[ 114 base_event_name]: 115 new_event_object = new_event_class( 116 None, base_event=event_object) 117 if new_event_object.generate(): 118 if not app.ged.raise_event(new_event_object.name, 119 new_event_object): 120 self._generate_events_based_on_outgoing_event( 121 new_event_object) 122 123 124class EventHelper: 125 def __init__(self): 126 self.__event_handlers = [] 127 128 def register_event(self, event_name, priority, handler): 129 self.__event_handlers.append((event_name, priority, handler)) 130 app.ged.register_event_handler(event_name, priority, handler) 131 132 def register_events(self, events): 133 for handler in events: 134 self.__event_handlers.append(handler) 135 app.ged.register_event_handler(*handler) 136 137 def unregister_event(self, event_name, priority, handler): 138 self.__event_handlers.remove((event_name, priority, handler)) 139 app.ged.register_event_handler(event_name, priority, handler) 140 141 def unregister_events(self): 142 for handler in self.__event_handlers: 143 app.ged.remove_event_handler(*handler) 144 self.__event_handlers.clear() 145 146 147class NetworkEvent: 148 name = '' 149 150 def __init__(self, new_name, **kwargs): 151 if new_name: 152 self.name = new_name 153 154 self.init() 155 156 self._set_kwargs_as_attributes(**kwargs) 157 158 def init(self): 159 pass 160 161 def generate(self): 162 ''' 163 Generates new event (sets it's attributes) based on event object. 164 165 Base event object name is one of those in `base_network_events`. 166 167 Reference to base event object is stored in `self.base_event` 168 attribute. 169 170 Note that this is a reference, so modifications to that event object 171 are possible before dispatching to Global Events Dispatcher. 172 173 :return: True if generated event should be dispatched, False otherwise. 174 ''' 175 return True 176 177 def _set_kwargs_as_attributes(self, **kwargs): 178 for k, v in kwargs.items(): 179 if k not in ('name', 'base_network_events'): 180 setattr(self, k, v) 181 182 def _set_base_event_vars_as_attributes(self, event): 183 for k, v in vars(event).items(): 184 if k not in ('name', 'base_network_events'): 185 setattr(self, k, v) 186 187 188class NetworkIncomingEvent(NetworkEvent): 189 base_network_events = [] # type: List[str] 190 ''' 191 Names of base network events that new event is going to be generated on. 192 ''' 193 194 195class NetworkOutgoingEvent(NetworkEvent): 196 base_network_events = [] # type: List[str] 197 ''' 198 Names of base network events that new event is going to be generated on. 199 ''' 200