66import os
77import re
88from collections import defaultdict
9- from operator import attrgetter
109from itertools import chain
10+ from operator import attrgetter
1111
1212import sqlalchemy
1313
@@ -37,9 +37,10 @@ def find_hooks(parent, module):
3737 on_cap_ack = []
3838 on_cap_available = []
3939 on_connect = []
40+ out_sieve = []
4041 type_lists = {"command" : command , "regex" : regex , "irc_raw" : raw , "sieve" : sieve , "event" : event ,
4142 "periodic" : periodic , "on_start" : on_start , "on_stop" : on_stop , "on_cap_ack" : on_cap_ack ,
42- "on_cap_available" : on_cap_available , "on_connect" : on_connect }
43+ "on_cap_available" : on_cap_available , "on_connect" : on_connect , "irc_out" : out_sieve }
4344 for name , func in module .__dict__ .items ():
4445 if hasattr (func , "_cloudbot_hook" ):
4546 # if it has cloudbot hook
@@ -51,7 +52,7 @@ def find_hooks(parent, module):
5152 # delete the hook to free memory
5253 del func ._cloudbot_hook
5354
54- return command , regex , raw , sieve , event , periodic , on_start , on_stop , on_cap_ack , on_cap_available , on_connect
55+ return command , regex , raw , sieve , event , periodic , on_start , on_stop , on_cap_ack , on_cap_available , on_connect , out_sieve
5556
5657
5758def find_tables (code ):
@@ -108,6 +109,7 @@ def __init__(self, bot):
108109 self .sieves = []
109110 self .cap_hooks = {"on_available" : defaultdict (list ), "on_ack" : defaultdict (list )}
110111 self .connect_hooks = []
112+ self .out_sieves = []
111113 self ._hook_waiting_queues = {}
112114
113115 @asyncio .coroutine
@@ -429,27 +431,36 @@ def _execute_hook_sync(self, hook, event):
429431 yield from event .close ()
430432
431433 @asyncio .coroutine
432- def _execute_hook (self , hook , event ):
434+ def internal_launch (self , hook , event ):
433435 """
434- Runs the specific hook with the given bot and event.
435-
436- Returns False if the hook errored, True otherwise.
437-
438- :type hook: cloudbot.plugin.Hook
439- :type event: cloudbot.event.Event
440- :rtype: bool
436+ Launches a hook with the data from [event]
437+ :param hook: The hook to launch
438+ :param event: The event providing data for the hook
439+ :return: a tuple of (ok, result) where ok is a boolean that determines if the hook ran without error and result is the result from the hook
441440 """
442441 try :
443- # _internal_run_threaded and _internal_run_coroutine prepare the database, and run the hook.
444- # _internal_run_* will prepare parameters and the database session, but won't do any error catching.
445442 if hook .threaded :
446443 out = yield from self .bot .loop .run_in_executor (None , self ._execute_hook_threaded , hook , event )
447444 else :
448445 out = yield from self ._execute_hook_sync (hook , event )
449446 except Exception :
450447 logger .exception ("Error in hook {}" .format (hook .description ))
451- return False
448+ return False , None
449+
450+ return True , out
452451
452+ @asyncio .coroutine
453+ def _execute_hook (self , hook , event ):
454+ """
455+ Runs the specific hook with the given bot and event.
456+
457+ Returns False if the hook errored, True otherwise.
458+
459+ :type hook: cloudbot.plugin.Hook
460+ :type event: cloudbot.event.Event
461+ :rtype: bool
462+ """
463+ ok , out = yield from self .internal_launch (hook , event )
453464 if out is not None :
454465 if isinstance (out , (list , tuple )):
455466 # if there are multiple items in the response, return them on multiple lines
@@ -878,6 +889,17 @@ def __str__(self):
878889 return "{name} {func} from {file}" .format (name = self .type , func = self .function_name , file = self .plugin .file_name )
879890
880891
892+ class IrcOutHook (Hook ):
893+ def __init__ (self , plugin , out_hook ):
894+ super ().__init__ ("irc_out" , plugin , out_hook )
895+
896+ def __repr__ (self ):
897+ return "Irc_Out[{}]" .format (Hook .__repr__ (self ))
898+
899+ def __str__ (self ):
900+ return "irc_out {} from {}" .format (self .function_name , self .plugin .file_name )
901+
902+
881903_hook_name_to_plugin = {
882904 "command" : CommandHook ,
883905 "regex" : RegexHook ,
@@ -890,4 +912,5 @@ def __str__(self):
890912 "on_cap_available" : OnCapAvaliableHook ,
891913 "on_cap_ack" : OnCapAckHook ,
892914 "on_connect" : OnConnectHook ,
915+ "irc_out" : IrcOutHook ,
893916}
0 commit comments