66import os
77import re
88from collections import defaultdict
9+ from operator import attrgetter
910
1011import sqlalchemy
1112
@@ -19,7 +20,7 @@ def find_hooks(parent, module):
1920 """
2021 :type parent: Plugin
2122 :type module: object
22- :rtype: (list[CommandHook], list[RegexHook], list[RawHook], list[SieveHook], List[EventHook], List[PeriodicHook], list[OnStartHook], List[OnStopHook], list[OnCapAckHook], list[OnCapAvailableHook])
23+ :rtype: (list[CommandHook], list[RegexHook], list[RawHook], list[SieveHook], List[EventHook], List[PeriodicHook], list[OnStartHook], List[OnStopHook], list[OnCapAckHook], list[OnCapAvailableHook], list[OnConnectHook] )
2324 """
2425 # set the loaded flag
2526 module ._cloudbot_loaded = True
@@ -33,9 +34,10 @@ def find_hooks(parent, module):
3334 on_stop = []
3435 on_cap_ack = []
3536 on_cap_available = []
37+ on_connect = []
3638 type_lists = {"command" : command , "regex" : regex , "irc_raw" : raw , "sieve" : sieve , "event" : event ,
3739 "periodic" : periodic , "on_start" : on_start , "on_stop" : on_stop , "on_cap_ack" : on_cap_ack ,
38- "on_cap_available" : on_cap_available }
40+ "on_cap_available" : on_cap_available , "on_connect" : on_connect }
3941 for name , func in module .__dict__ .items ():
4042 if hasattr (func , "_cloudbot_hook" ):
4143 # if it has cloudbot hook
@@ -47,7 +49,7 @@ def find_hooks(parent, module):
4749 # delete the hook to free memory
4850 del func ._cloudbot_hook
4951
50- return command , regex , raw , sieve , event , periodic , on_start , on_stop , on_cap_ack , on_cap_available
52+ return command , regex , raw , sieve , event , periodic , on_start , on_stop , on_cap_ack , on_cap_available , on_connect
5153
5254
5355def find_tables (code ):
@@ -103,6 +105,7 @@ def __init__(self, bot):
103105 self .regex_hooks = []
104106 self .sieves = []
105107 self .cap_hooks = {"on_available" : defaultdict (list ), "on_ack" : defaultdict (list )}
108+ self .connect_hooks = []
106109 self ._hook_waiting_queues = {}
107110
108111 @asyncio .coroutine
@@ -242,8 +245,14 @@ def load_plugin(self, path):
242245 self .sieves .append (sieve_hook )
243246 self ._log_hook (sieve_hook )
244247
248+ # register connect hooks
249+ for connect_hook in plugin .connect_hooks :
250+ self .connect_hooks .append (connect_hook )
251+ self ._log_hook (connect_hook )
252+
245253 # sort sieve hooks by priority
246254 self .sieves .sort (key = lambda x : x .priority )
255+ self .connect_hooks .sort (key = attrgetter ("priority" ))
247256
248257 # we don't need this anymore
249258 del plugin .run_on_start
@@ -325,6 +334,10 @@ def unload_plugin(self, path):
325334 for sieve_hook in plugin .sieves :
326335 self .sieves .remove (sieve_hook )
327336
337+ # unregister connect hooks
338+ for connect_hook in plugin .connect_hooks :
339+ self .connect_hooks .remove (connect_hook )
340+
328341 # Run on_stop hooks
329342 for on_stop_hook in plugin .run_on_stop :
330343 event = Event (bot = self .bot , hook = on_stop_hook )
@@ -552,8 +565,11 @@ def __init__(self, filepath, filename, title, code):
552565 self .file_path = filepath
553566 self .file_name = filename
554567 self .title = title
555- self .commands , self .regexes , self .raw_hooks , self .sieves , self .events , self .periodic , self .run_on_start , self .run_on_stop , self .on_cap_ack , self .on_cap_available = find_hooks (
556- self , code )
568+ hooks = find_hooks (self , code )
569+ self .commands , self .regexes , self .raw_hooks , * hooks = hooks
570+ self .sieves , self .events , self .periodic , * hooks = hooks
571+ self .run_on_start , self .run_on_stop , self .on_cap_ack , * hooks = hooks
572+ self .on_cap_available , self .connect_hooks , * hooks = hooks
557573 # we need to find tables for each plugin so that they can be unloaded from the global metadata when the
558574 # plugin is reloaded
559575 self .tables = find_tables (code )
@@ -830,6 +846,23 @@ def __init__(self, plugin, base_hook):
830846 super ().__init__ ("ack" , plugin , base_hook )
831847
832848
849+ class OnConnectHook (Hook ):
850+ def __init__ (self , plugin , sieve_hook ):
851+ """
852+ :type plugin: Plugin
853+ :type sieve_hook: cloudbot.util.hook._Hook
854+ """
855+
856+ self .priority = sieve_hook .kwargs .pop ("priority" , 100 )
857+ super ().__init__ ("on_connect" , plugin , sieve_hook )
858+
859+ def __repr__ (self ):
860+ return "{name}[{base!r}]" .format (name = self .type , base = super ())
861+
862+ def __str__ (self ):
863+ return "{name} {func} from {file}" .format (name = self .type , func = self .function_name , file = self .plugin .file_name )
864+
865+
833866_hook_name_to_plugin = {
834867 "command" : CommandHook ,
835868 "regex" : RegexHook ,
@@ -841,4 +874,5 @@ def __init__(self, plugin, base_hook):
841874 "on_stop" : OnStopHook ,
842875 "on_cap_available" : OnCapAvaliableHook ,
843876 "on_cap_ack" : OnCapAckHook ,
877+ "on_connect" : OnConnectHook ,
844878}
0 commit comments