55import re
66import os
77import gc
8+ from operator import not_ , attrgetter , itemgetter
9+
810from sqlalchemy import create_engine
911
1012from sqlalchemy .orm import scoped_session , sessionmaker
1416import cloudbot
1517from cloudbot .client import Client
1618from cloudbot .config import Config
19+ from cloudbot .hook import Action
1720from cloudbot .reloader import PluginReloader
1821from cloudbot .plugin import PluginManager
1922from cloudbot .event import Event , CommandEvent , RegexEvent , EventType
@@ -221,23 +224,46 @@ def process(self, event):
221224 run_before_tasks = []
222225 tasks = []
223226 command_prefix = event .conn .config .get ('command_prefix' , '.' )
227+ halted = False
228+
229+ def add_hook (hook , _event , _run_before = False ):
230+ nonlocal halted
231+ if halted :
232+ return False
233+
234+ coro = self .plugin_manager .launch (hook , _event )
235+ if _run_before :
236+ run_before_tasks .append (coro )
237+ else :
238+ tasks .append (coro )
239+
240+ if hook .action is Action .HALTALL :
241+ halted = True
242+ return False
243+ elif hook .action is Action .HALTTYPE :
244+ return False
245+ return True
224246
225247 # Raw IRC hook
226248 for raw_hook in self .plugin_manager .catch_all_triggers :
227249 # run catch-all coroutine hooks before all others - TODO: Make this a plugin argument
228- if not raw_hook .threaded :
229- run_before_tasks . append (
230- self . plugin_manager . launch ( raw_hook , Event ( hook = raw_hook , base_event = event )))
231- else :
232- tasks . append ( self . plugin_manager . launch ( raw_hook , Event ( hook = raw_hook , base_event = event )))
250+ run_before = not raw_hook .threaded
251+ if not add_hook ( raw_hook , Event ( hook = raw_hook , base_event = event ), _run_before = run_before ):
252+ # The hook has an action of Action.HALT* so stop adding new tasks
253+ break
254+
233255 if event .irc_command in self .plugin_manager .raw_triggers :
234256 for raw_hook in self .plugin_manager .raw_triggers [event .irc_command ]:
235- tasks .append (self .plugin_manager .launch (raw_hook , Event (hook = raw_hook , base_event = event )))
257+ if not add_hook (raw_hook , Event (hook = raw_hook , base_event = event )):
258+ # The hook has an action of Action.HALT* so stop adding new tasks
259+ break
236260
237261 # Event hooks
238262 if event .type in self .plugin_manager .event_type_hooks :
239263 for event_hook in self .plugin_manager .event_type_hooks [event .type ]:
240- tasks .append (self .plugin_manager .launch (event_hook , Event (hook = event_hook , base_event = event )))
264+ if not add_hook (event_hook , Event (hook = event_hook , base_event = event )):
265+ # The hook has an action of Action.HALT* so stop adding new tasks
266+ break
241267
242268 if event .type is EventType .message :
243269 # Commands
@@ -258,7 +284,7 @@ def process(self, event):
258284 command_hook = self .plugin_manager .commands [command ]
259285 command_event = CommandEvent (hook = command_hook , text = text ,
260286 triggered_command = command , base_event = event )
261- tasks . append ( self . plugin_manager . launch ( command_hook , command_event ) )
287+ add_hook ( command_hook , command_event )
262288 else :
263289 potential_matches = []
264290 for potential_match , plugin in self .plugin_manager .commands .items ():
@@ -269,20 +295,25 @@ def process(self, event):
269295 command_hook = potential_matches [0 ][1 ]
270296 command_event = CommandEvent (hook = command_hook , text = text ,
271297 triggered_command = command , base_event = event )
272- tasks . append ( self . plugin_manager . launch ( command_hook , command_event ) )
298+ add_hook ( command_hook , command_event )
273299 else :
274300 event .notice ("Possible matches: {}" .format (
275301 formatting .get_text_list ([command for command , plugin in potential_matches ])))
276302
277303 # Regex hooks
278- for regex , regex_hook in self .plugin_manager .regex_hooks :
304+ def regex_priority (t ):
305+ return t [1 ].priority
306+
307+ for regex , regex_hook in sorted (self .plugin_manager .regex_hooks , key = regex_priority , reverse = True ):
279308 if not regex_hook .run_on_cmd and cmd_match :
280- pass
281- else :
282- regex_match = regex .search (event .content )
283- if regex_match :
284- regex_event = RegexEvent (hook = regex_hook , match = regex_match , base_event = event )
285- tasks .append (self .plugin_manager .launch (regex_hook , regex_event ))
309+ continue
310+
311+ regex_match = regex .search (event .content )
312+ if regex_match :
313+ regex_event = RegexEvent (hook = regex_hook , match = regex_match , base_event = event )
314+ if not add_hook (regex_hook , regex_event ):
315+ # The hook has an action of Action.HALT* so stop adding new tasks
316+ break
286317
287318 # Run the tasks
288319 yield from asyncio .gather (* run_before_tasks , loop = self .loop )
0 commit comments