@@ -27,39 +27,23 @@ def find_hooks(parent, module):
2727 """
2828 :type parent: Plugin
2929 :type module: object
30- :rtype: (list[CommandHook], list[RegexHook], list[RawHook], list[SieveHook], List[EventHook], List[PeriodicHook], list[OnStartHook], List[OnStopHook], list[OnCapAckHook], list[OnCapAvailableHook], list[OnConnectHook])
30+ :rtype: dict
3131 """
3232 # set the loaded flag
3333 module ._cloudbot_loaded = True
34- command = []
35- regex = []
36- raw = []
37- sieve = []
38- event = []
39- periodic = []
40- on_start = []
41- on_stop = []
42- on_cap_ack = []
43- on_cap_available = []
44- on_connect = []
45- out_sieve = []
46- post_hooks = []
47- type_lists = {"command" : command , "regex" : regex , "irc_raw" : raw , "sieve" : sieve , "event" : event ,
48- "periodic" : periodic , "on_start" : on_start , "on_stop" : on_stop , "on_cap_ack" : on_cap_ack ,
49- "on_cap_available" : on_cap_available , "on_connect" : on_connect , "irc_out" : out_sieve ,
50- "post_hook" : post_hooks }
34+ hooks = defaultdict (list )
5135 for name , func in module .__dict__ .items ():
5236 if hasattr (func , "_cloudbot_hook" ):
5337 # if it has cloudbot hook
5438 func_hooks = func ._cloudbot_hook
5539
5640 for hook_type , func_hook in func_hooks .items ():
57- type_lists [hook_type ].append (_hook_name_to_plugin [hook_type ](parent , func_hook ))
41+ hooks [hook_type ].append (_hook_name_to_plugin [hook_type ](parent , func_hook ))
5842
5943 # delete the hook to free memory
6044 del func ._cloudbot_hook
6145
62- return command , regex , raw , sieve , event , periodic , on_start , on_stop , on_cap_ack , on_cap_available , on_connect , out_sieve , post_hooks
46+ return hooks
6347
6448
6549def find_tables (code ):
@@ -118,6 +102,7 @@ def __init__(self, bot):
118102 self .connect_hooks = []
119103 self .out_sieves = []
120104 self .hook_hooks = defaultdict (list )
105+ self .perm_hooks = defaultdict (list )
121106 self ._hook_waiting_queues = {}
122107
123108 @asyncio .coroutine
@@ -188,7 +173,7 @@ def load_plugin(self, path):
188173 yield from plugin .create_tables (self .bot )
189174
190175 # run on_start hooks
191- for on_start_hook in plugin .run_on_start :
176+ for on_start_hook in plugin .hooks [ "on_start" ] :
192177 success = yield from self .launch (on_start_hook , Event (bot = self .bot , hook = on_start_hook ))
193178 if not success :
194179 logger .warning ("Not registering hooks from plugin {}: on_start hook errored" .format (plugin .title ))
@@ -199,23 +184,23 @@ def load_plugin(self, path):
199184
200185 self .plugins [plugin .file_name ] = plugin
201186
202- for on_cap_available_hook in plugin .on_cap_available :
187+ for on_cap_available_hook in plugin .hooks [ " on_cap_available" ] :
203188 for cap in on_cap_available_hook .caps :
204189 self .cap_hooks ["on_available" ][cap .casefold ()].append (on_cap_available_hook )
205190 self ._log_hook (on_cap_available_hook )
206191
207- for on_cap_ack_hook in plugin .on_cap_ack :
192+ for on_cap_ack_hook in plugin .hooks [ " on_cap_ack" ] :
208193 for cap in on_cap_ack_hook .caps :
209194 self .cap_hooks ["on_ack" ][cap .casefold ()].append (on_cap_ack_hook )
210195 self ._log_hook (on_cap_ack_hook )
211196
212- for periodic_hook in plugin .periodic :
197+ for periodic_hook in plugin .hooks [ " periodic" ] :
213198 task = async_util .wrap_future (self ._start_periodic (periodic_hook ))
214199 plugin .tasks .append (task )
215200 self ._log_hook (periodic_hook )
216201
217202 # register commands
218- for command_hook in plugin .commands :
203+ for command_hook in plugin .hooks [ "command" ] :
219204 for alias in command_hook .aliases :
220205 if alias in self .commands :
221206 logger .warning (
@@ -226,7 +211,7 @@ def load_plugin(self, path):
226211 self ._log_hook (command_hook )
227212
228213 # register raw hooks
229- for raw_hook in plugin .raw_hooks :
214+ for raw_hook in plugin .hooks [ "irc_raw" ] :
230215 if raw_hook .is_catch_all ():
231216 self .catch_all_triggers .append (raw_hook )
232217 else :
@@ -238,7 +223,7 @@ def load_plugin(self, path):
238223 self ._log_hook (raw_hook )
239224
240225 # register events
241- for event_hook in plugin .events :
226+ for event_hook in plugin .hooks [ "event" ] :
242227 for event_type in event_hook .types :
243228 if event_type in self .event_type_hooks :
244229 self .event_type_hooks [event_type ].append (event_hook )
@@ -247,40 +232,50 @@ def load_plugin(self, path):
247232 self ._log_hook (event_hook )
248233
249234 # register regexps
250- for regex_hook in plugin .regexes :
235+ for regex_hook in plugin .hooks [ "regex" ] :
251236 for regex_match in regex_hook .regexes :
252237 self .regex_hooks .append ((regex_match , regex_hook ))
253238 self ._log_hook (regex_hook )
254239
255240 # register sieves
256- for sieve_hook in plugin .sieves :
241+ for sieve_hook in plugin .hooks [ "sieve" ] :
257242 self .sieves .append (sieve_hook )
258243 self ._log_hook (sieve_hook )
259244
260245 # register connect hooks
261- for connect_hook in plugin .connect_hooks :
246+ for connect_hook in plugin .hooks [ "on_connect" ] :
262247 self .connect_hooks .append (connect_hook )
263248 self ._log_hook (connect_hook )
264249
265- for out_hook in plugin .irc_out_hooks :
250+ for out_hook in plugin .hooks [ "irc_out" ] :
266251 self .out_sieves .append (out_hook )
267252 self ._log_hook (out_hook )
268253
269- for post_hook in plugin .post_hook_hooks :
254+ for post_hook in plugin .hooks [ "post_hook" ] :
270255 self .hook_hooks ["post" ].append (post_hook )
271256 self ._log_hook (post_hook )
272257
258+ for perm_hook in plugin .hooks ["perm_check" ]:
259+ for perm in perm_hook .perms :
260+ self .perm_hooks [perm ].append (perm_hook )
261+
262+ self ._log_hook (perm_hook )
263+
264+ # sort sieve hooks by priority
265+ self .sieves .sort (key = lambda x : x .priority )
266+ self .connect_hooks .sort (key = attrgetter ("priority" ))
267+
273268 # Sort hooks
274269 self .regex_hooks .sort (key = lambda x : x [1 ].priority )
275- dicts_of_lists_of_hooks = (self .event_type_hooks , self .raw_triggers , self .hook_hooks )
270+ dicts_of_lists_of_hooks = (self .event_type_hooks , self .raw_triggers , self .perm_hooks , self . hook_hooks )
276271 lists_of_hooks = [self .catch_all_triggers , self .sieves , self .connect_hooks , self .out_sieves ]
277272 lists_of_hooks .extend (chain .from_iterable (d .values () for d in dicts_of_lists_of_hooks ))
278273
279274 for lst in lists_of_hooks :
280275 lst .sort (key = attrgetter ("priority" ))
281276
282277 # we don't need this anymore
283- del plugin .run_on_start
278+ del plugin .hooks [ "on_start" ]
284279
285280 @asyncio .coroutine
286281 def unload_plugin (self , path ):
@@ -308,15 +303,15 @@ def unload_plugin(self, path):
308303 for task in plugin .tasks :
309304 task .cancel ()
310305
311- for on_cap_available_hook in plugin .on_cap_available :
306+ for on_cap_available_hook in plugin .hooks [ " on_cap_available" ] :
312307 available_hooks = self .cap_hooks ["on_available" ]
313308 for cap in on_cap_available_hook .caps :
314309 cap_cf = cap .casefold ()
315310 available_hooks [cap_cf ].remove (on_cap_available_hook )
316311 if not available_hooks [cap_cf ]:
317312 del available_hooks [cap_cf ]
318313
319- for on_cap_ack in plugin .on_cap_ack :
314+ for on_cap_ack in plugin .hooks [ " on_cap_ack" ] :
320315 ack_hooks = self .cap_hooks ["on_ack" ]
321316 for cap in on_cap_ack .caps :
322317 cap_cf = cap .casefold ()
@@ -325,14 +320,14 @@ def unload_plugin(self, path):
325320 del ack_hooks [cap_cf ]
326321
327322 # unregister commands
328- for command_hook in plugin .commands :
323+ for command_hook in plugin .hooks [ "command" ] :
329324 for alias in command_hook .aliases :
330325 if alias in self .commands and self .commands [alias ] == command_hook :
331326 # we need to make sure that there wasn't a conflict, so we don't delete another plugin's command
332327 del self .commands [alias ]
333328
334329 # unregister raw hooks
335- for raw_hook in plugin .raw_hooks :
330+ for raw_hook in plugin .hooks [ "irc_raw" ] :
336331 if raw_hook .is_catch_all ():
337332 self .catch_all_triggers .remove (raw_hook )
338333 else :
@@ -343,34 +338,38 @@ def unload_plugin(self, path):
343338 del self .raw_triggers [trigger ]
344339
345340 # unregister events
346- for event_hook in plugin .events :
341+ for event_hook in plugin .hooks [ "event" ] :
347342 for event_type in event_hook .types :
348343 assert event_type in self .event_type_hooks # this can't be not true
349344 self .event_type_hooks [event_type ].remove (event_hook )
350345 if not self .event_type_hooks [event_type ]: # if that was the last hook for this event type
351346 del self .event_type_hooks [event_type ]
352347
353348 # unregister regexps
354- for regex_hook in plugin .regexes :
349+ for regex_hook in plugin .hooks [ "regex" ] :
355350 for regex_match in regex_hook .regexes :
356351 self .regex_hooks .remove ((regex_match , regex_hook ))
357352
358353 # unregister sieves
359- for sieve_hook in plugin .sieves :
354+ for sieve_hook in plugin .hooks [ "sieve" ] :
360355 self .sieves .remove (sieve_hook )
361356
362357 # unregister connect hooks
363- for connect_hook in plugin .connect_hooks :
358+ for connect_hook in plugin .hooks [ "on_connect" ] :
364359 self .connect_hooks .remove (connect_hook )
365360
366- for out_hook in plugin .irc_out_hooks :
361+ for out_hook in plugin .hooks [ "irc_out" ] :
367362 self .out_sieves .remove (out_hook )
368363
369- for post_hook in plugin .post_hook_hooks :
364+ for post_hook in plugin .hooks [ "post_hook" ] :
370365 self .hook_hooks ["post" ].remove (post_hook )
371366
367+ for perm_hook in plugin .hooks ["perm_check" ]:
368+ for perm in perm_hook .perms :
369+ self .perm_hooks [perm ].remove (perm_hook )
370+
372371 # Run on_stop hooks
373- for on_stop_hook in plugin .run_on_stop :
372+ for on_stop_hook in plugin .hooks [ "on_stop" ] :
374373 event = Event (bot = self .bot , hook = on_stop_hook )
375374 yield from self .launch (on_stop_hook , event )
376375
@@ -592,11 +591,7 @@ class Plugin:
592591 :type file_path: str
593592 :type file_name: str
594593 :type title: str
595- :type commands: list[CommandHook]
596- :type regexes: list[RegexHook]
597- :type raw_hooks: list[RawHook]
598- :type sieves: list[SieveHook]
599- :type events: list[EventHook]
594+ :type hooks: dict
600595 :type tables: list[sqlalchemy.Table]
601596 """
602597
@@ -610,13 +605,7 @@ def __init__(self, filepath, filename, title, code):
610605 self .file_path = filepath
611606 self .file_name = filename
612607 self .title = title
613- # TODO clean up hook lists
614- hooks = find_hooks (self , code )
615- self .commands , self .regexes , self .raw_hooks , * hooks = hooks
616- self .sieves , self .events , self .periodic , * hooks = hooks
617- self .run_on_start , self .run_on_stop , self .on_cap_ack , * hooks = hooks
618- self .on_cap_available , self .connect_hooks , self .irc_out_hooks , * hooks = hooks
619- self .post_hook_hooks , * hooks = hooks
608+ self .hooks = find_hooks (self , code )
620609 # we need to find tables for each plugin so that they can be unloaded from the global metadata when the
621610 # plugin is reloaded
622611 self .tables = find_tables (code )
@@ -936,6 +925,18 @@ def __str__(self):
936925 return "post_hook {} from {}" .format (self .function_name , self .plugin .file_name )
937926
938927
928+ class PermHook (Hook ):
929+ def __init__ (self , plugin , perm_hook ):
930+ self .perms = perm_hook .perms
931+ super ().__init__ ("perm_check" , plugin , perm_hook )
932+
933+ def __repr__ (self ):
934+ return "PermHook[{}]" .format (Hook .__repr__ (self ))
935+
936+ def __str__ (self ):
937+ return "perm hook {} from {}" .format (self .function_name , self .plugin .file_name )
938+
939+
939940_hook_name_to_plugin = {
940941 "command" : CommandHook ,
941942 "regex" : RegexHook ,
@@ -950,4 +951,5 @@ def __str__(self):
950951 "on_connect" : OnConnectHook ,
951952 "irc_out" : IrcOutHook ,
952953 "post_hook" : PostHookHook ,
954+ "perm_check" : PermHook ,
953955}
0 commit comments