@@ -26,36 +26,23 @@ def find_hooks(parent, module):
2626 """
2727 :type parent: Plugin
2828 :type module: object
29- :rtype: (list[CommandHook], list[RegexHook], list[RawHook], list[SieveHook], List[EventHook], List[PeriodicHook], list[OnStartHook], List[OnStopHook], list[OnCapAckHook], list[OnCapAvailableHook], list[OnConnectHook])
29+ :rtype: dict
3030 """
3131 # set the loaded flag
3232 module ._cloudbot_loaded = True
33- command = []
34- regex = []
35- raw = []
36- sieve = []
37- event = []
38- periodic = []
39- on_start = []
40- on_stop = []
41- on_cap_ack = []
42- on_cap_available = []
43- on_connect = []
44- type_lists = {"command" : command , "regex" : regex , "irc_raw" : raw , "sieve" : sieve , "event" : event ,
45- "periodic" : periodic , "on_start" : on_start , "on_stop" : on_stop , "on_cap_ack" : on_cap_ack ,
46- "on_cap_available" : on_cap_available , "on_connect" : on_connect }
33+ hooks = defaultdict (list )
4734 for name , func in module .__dict__ .items ():
4835 if hasattr (func , "_cloudbot_hook" ):
4936 # if it has cloudbot hook
5037 func_hooks = func ._cloudbot_hook
5138
5239 for hook_type , func_hook in func_hooks .items ():
53- type_lists [hook_type ].append (_hook_name_to_plugin [hook_type ](parent , func_hook ))
40+ hooks [hook_type ].append (_hook_name_to_plugin [hook_type ](parent , func_hook ))
5441
5542 # delete the hook to free memory
5643 del func ._cloudbot_hook
5744
58- return command , regex , raw , sieve , event , periodic , on_start , on_stop , on_cap_ack , on_cap_available , on_connect
45+ return hooks
5946
6047
6148def find_tables (code ):
@@ -112,6 +99,7 @@ def __init__(self, bot):
11299 self .sieves = []
113100 self .cap_hooks = {"on_available" : defaultdict (list ), "on_ack" : defaultdict (list )}
114101 self .connect_hooks = []
102+ self .perm_hooks = defaultdict (list )
115103 self ._hook_waiting_queues = {}
116104
117105 @asyncio .coroutine
@@ -182,7 +170,7 @@ def load_plugin(self, path):
182170 yield from plugin .create_tables (self .bot )
183171
184172 # run on_start hooks
185- for on_start_hook in plugin .run_on_start :
173+ for on_start_hook in plugin .hooks [ "on_start" ] :
186174 success = yield from self .launch (on_start_hook , Event (bot = self .bot , hook = on_start_hook ))
187175 if not success :
188176 logger .warning ("Not registering hooks from plugin {}: on_start hook errored" .format (plugin .title ))
@@ -193,23 +181,23 @@ def load_plugin(self, path):
193181
194182 self .plugins [plugin .file_name ] = plugin
195183
196- for on_cap_available_hook in plugin .on_cap_available :
184+ for on_cap_available_hook in plugin .hooks [ " on_cap_available" ] :
197185 for cap in on_cap_available_hook .caps :
198186 self .cap_hooks ["on_available" ][cap .casefold ()].append (on_cap_available_hook )
199187 self ._log_hook (on_cap_available_hook )
200188
201- for on_cap_ack_hook in plugin .on_cap_ack :
189+ for on_cap_ack_hook in plugin .hooks [ " on_cap_ack" ] :
202190 for cap in on_cap_ack_hook .caps :
203191 self .cap_hooks ["on_ack" ][cap .casefold ()].append (on_cap_ack_hook )
204192 self ._log_hook (on_cap_ack_hook )
205193
206- for periodic_hook in plugin .periodic :
194+ for periodic_hook in plugin .hooks [ " periodic" ] :
207195 task = async_util .wrap_future (self ._start_periodic (periodic_hook ))
208196 plugin .tasks .append (task )
209197 self ._log_hook (periodic_hook )
210198
211199 # register commands
212- for command_hook in plugin .commands :
200+ for command_hook in plugin .hooks [ "command" ] :
213201 for alias in command_hook .aliases :
214202 if alias in self .commands :
215203 logger .warning (
@@ -220,7 +208,7 @@ def load_plugin(self, path):
220208 self ._log_hook (command_hook )
221209
222210 # register raw hooks
223- for raw_hook in plugin .raw_hooks :
211+ for raw_hook in plugin .hooks [ "irc_raw" ] :
224212 if raw_hook .is_catch_all ():
225213 self .catch_all_triggers .append (raw_hook )
226214 else :
@@ -232,7 +220,7 @@ def load_plugin(self, path):
232220 self ._log_hook (raw_hook )
233221
234222 # register events
235- for event_hook in plugin .events :
223+ for event_hook in plugin .hooks [ "event" ] :
236224 for event_type in event_hook .types :
237225 if event_type in self .event_type_hooks :
238226 self .event_type_hooks [event_type ].append (event_hook )
@@ -241,36 +229,42 @@ def load_plugin(self, path):
241229 self ._log_hook (event_hook )
242230
243231 # register regexps
244- for regex_hook in plugin .regexes :
232+ for regex_hook in plugin .hooks [ "regex" ] :
245233 for regex_match in regex_hook .regexes :
246234 self .regex_hooks .append ((regex_match , regex_hook ))
247235 self ._log_hook (regex_hook )
248236
249237 # register sieves
250- for sieve_hook in plugin .sieves :
238+ for sieve_hook in plugin .hooks [ "sieve" ] :
251239 self .sieves .append (sieve_hook )
252240 self ._log_hook (sieve_hook )
253241
254242 # register connect hooks
255- for connect_hook in plugin .connect_hooks :
243+ for connect_hook in plugin .hooks [ "on_connect" ] :
256244 self .connect_hooks .append (connect_hook )
257245 self ._log_hook (connect_hook )
258246
247+ for perm_hook in plugin .hooks ["perm_check" ]:
248+ for perm in perm_hook .perms :
249+ self .perm_hooks [perm ].append (perm_hook )
250+
251+ self ._log_hook (perm_hook )
252+
259253 # sort sieve hooks by priority
260254 self .sieves .sort (key = lambda x : x .priority )
261255 self .connect_hooks .sort (key = attrgetter ("priority" ))
262256
263257 # Sort hooks
264258 self .regex_hooks .sort (key = lambda x : x [1 ].priority )
265- dicts_of_lists_of_hooks = (self .event_type_hooks , self .raw_triggers )
259+ dicts_of_lists_of_hooks = (self .event_type_hooks , self .raw_triggers , self . perm_hooks )
266260 lists_of_hooks = [self .catch_all_triggers , self .sieves ]
267261 lists_of_hooks .extend (chain .from_iterable (d .values () for d in dicts_of_lists_of_hooks ))
268262
269263 for lst in lists_of_hooks :
270264 lst .sort (key = lambda x : x .priority )
271265
272266 # we don't need this anymore
273- del plugin .run_on_start
267+ del plugin .hooks [ "on_start" ]
274268
275269 @asyncio .coroutine
276270 def unload_plugin (self , path ):
@@ -298,15 +292,15 @@ def unload_plugin(self, path):
298292 for task in plugin .tasks :
299293 task .cancel ()
300294
301- for on_cap_available_hook in plugin .on_cap_available :
295+ for on_cap_available_hook in plugin .hooks [ " on_cap_available" ] :
302296 available_hooks = self .cap_hooks ["on_available" ]
303297 for cap in on_cap_available_hook .caps :
304298 cap_cf = cap .casefold ()
305299 available_hooks [cap_cf ].remove (on_cap_available_hook )
306300 if not available_hooks [cap_cf ]:
307301 del available_hooks [cap_cf ]
308302
309- for on_cap_ack in plugin .on_cap_ack :
303+ for on_cap_ack in plugin .hooks [ " on_cap_ack" ] :
310304 ack_hooks = self .cap_hooks ["on_ack" ]
311305 for cap in on_cap_ack .caps :
312306 cap_cf = cap .casefold ()
@@ -315,14 +309,14 @@ def unload_plugin(self, path):
315309 del ack_hooks [cap_cf ]
316310
317311 # unregister commands
318- for command_hook in plugin .commands :
312+ for command_hook in plugin .hooks [ "command" ] :
319313 for alias in command_hook .aliases :
320314 if alias in self .commands and self .commands [alias ] == command_hook :
321315 # we need to make sure that there wasn't a conflict, so we don't delete another plugin's command
322316 del self .commands [alias ]
323317
324318 # unregister raw hooks
325- for raw_hook in plugin .raw_hooks :
319+ for raw_hook in plugin .hooks [ "irc_raw" ] :
326320 if raw_hook .is_catch_all ():
327321 self .catch_all_triggers .remove (raw_hook )
328322 else :
@@ -333,28 +327,32 @@ def unload_plugin(self, path):
333327 del self .raw_triggers [trigger ]
334328
335329 # unregister events
336- for event_hook in plugin .events :
330+ for event_hook in plugin .hooks [ "event" ] :
337331 for event_type in event_hook .types :
338332 assert event_type in self .event_type_hooks # this can't be not true
339333 self .event_type_hooks [event_type ].remove (event_hook )
340334 if not self .event_type_hooks [event_type ]: # if that was the last hook for this event type
341335 del self .event_type_hooks [event_type ]
342336
343337 # unregister regexps
344- for regex_hook in plugin .regexes :
338+ for regex_hook in plugin .hooks [ "regex" ] :
345339 for regex_match in regex_hook .regexes :
346340 self .regex_hooks .remove ((regex_match , regex_hook ))
347341
348342 # unregister sieves
349- for sieve_hook in plugin .sieves :
343+ for sieve_hook in plugin .hooks [ "sieve" ] :
350344 self .sieves .remove (sieve_hook )
351345
352346 # unregister connect hooks
353- for connect_hook in plugin .connect_hooks :
347+ for connect_hook in plugin .hooks [ "on_connect" ] :
354348 self .connect_hooks .remove (connect_hook )
355349
350+ for perm_hook in plugin .hooks ["perm_check" ]:
351+ for perm in perm_hook .perms :
352+ self .perm_hooks [perm ].remove (perm_hook )
353+
356354 # Run on_stop hooks
357- for on_stop_hook in plugin .run_on_stop :
355+ for on_stop_hook in plugin .hooks [ "on_stop" ] :
358356 event = Event (bot = self .bot , hook = on_stop_hook )
359357 yield from self .launch (on_stop_hook , event )
360358
@@ -562,11 +560,7 @@ class Plugin:
562560 :type file_path: str
563561 :type file_name: str
564562 :type title: str
565- :type commands: list[CommandHook]
566- :type regexes: list[RegexHook]
567- :type raw_hooks: list[RawHook]
568- :type sieves: list[SieveHook]
569- :type events: list[EventHook]
563+ :type hooks: dict
570564 :type tables: list[sqlalchemy.Table]
571565 """
572566
@@ -580,12 +574,7 @@ def __init__(self, filepath, filename, title, code):
580574 self .file_path = filepath
581575 self .file_name = filename
582576 self .title = title
583- # TODO clean up hook lists
584- hooks = find_hooks (self , code )
585- self .commands , self .regexes , self .raw_hooks , * hooks = hooks
586- self .sieves , self .events , self .periodic , * hooks = hooks
587- self .run_on_start , self .run_on_stop , self .on_cap_ack , * hooks = hooks
588- self .on_cap_available , self .connect_hooks , * hooks = hooks
577+ self .hooks = find_hooks (self , code )
589578 # we need to find tables for each plugin so that they can be unloaded from the global metadata when the
590579 # plugin is reloaded
591580 self .tables = find_tables (code )
@@ -888,6 +877,18 @@ def __str__(self):
888877 return "{name} {func} from {file}" .format (name = self .type , func = self .function_name , file = self .plugin .file_name )
889878
890879
880+ class PermHook (Hook ):
881+ def __init__ (self , plugin , perm_hook ):
882+ self .perms = perm_hook .perms
883+ super ().__init__ ("perm_check" , plugin , perm_hook )
884+
885+ def __repr__ (self ):
886+ return "PermHook[{}]" .format (Hook .__repr__ (self ))
887+
888+ def __str__ (self ):
889+ return "perm hook {} from {}" .format (self .function_name , self .plugin .file_name )
890+
891+
891892_hook_name_to_plugin = {
892893 "command" : CommandHook ,
893894 "regex" : RegexHook ,
@@ -900,4 +901,5 @@ def __str__(self):
900901 "on_cap_available" : OnCapAvaliableHook ,
901902 "on_cap_ack" : OnCapAckHook ,
902903 "on_connect" : OnConnectHook ,
904+ "perm_check" : PermHook ,
903905}
0 commit comments