Skip to content

Commit f507f0e

Browse files
committed
Implement hook actino and regex_hook priority
1 parent af8c9c2 commit f507f0e

2 files changed

Lines changed: 50 additions & 16 deletions

File tree

cloudbot/bot.py

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import re
66
import os
77
import gc
8+
from operator import not_, attrgetter, itemgetter
9+
810
from sqlalchemy import create_engine
911

1012
from sqlalchemy.orm import scoped_session, sessionmaker
@@ -14,6 +16,7 @@
1416
import cloudbot
1517
from cloudbot.client import Client
1618
from cloudbot.config import Config
19+
from cloudbot.hook import Action
1720
from cloudbot.reloader import PluginReloader
1821
from cloudbot.plugin import PluginManager
1922
from 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)

cloudbot/plugin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import sqlalchemy
1010

1111
from cloudbot.event import Event
12+
from cloudbot.hook import Priority, Action
1213
from cloudbot.util import database
1314

1415
logger = logging.getLogger("cloudbot")
@@ -594,6 +595,7 @@ def __init__(self, _type, plugin, func_hook):
594595

595596
self.permissions = func_hook.kwargs.pop("permissions", [])
596597
self.single_thread = func_hook.kwargs.pop("singlethread", False)
598+
self.action = func_hook.kwargs.pop("action", Action.CONTINUE)
597599

598600
if func_hook.kwargs:
599601
# we should have popped all the args, so warn if there are any left
@@ -650,6 +652,7 @@ def __init__(self, plugin, regex_hook):
650652
:type regex_hook: cloudbot.util.hook._RegexHook
651653
"""
652654
self.run_on_cmd = regex_hook.kwargs.pop("run_on_cmd", False)
655+
self.priority = regex_hook.kwargs.pop("priority", Priority.NORMAL)
653656

654657
self.regexes = regex_hook.regexes
655658

0 commit comments

Comments
 (0)