h/plugins/util/hook.py

101 lines
2.7 KiB
Python
Raw Normal View History

2010-02-02 04:42:34 +00:00
import inspect
import re
2010-03-01 02:32:41 +00:00
2010-03-11 23:34:54 +00:00
def _hook_add(func, add, name=''):
if not hasattr(func, '_hook'):
func._hook = []
func._hook.append(add)
2010-03-11 23:34:54 +00:00
if not hasattr(func, '_filename'):
func._filename = func.func_code.co_filename
2010-03-11 23:34:54 +00:00
if not hasattr(func, '_args'):
2010-02-02 04:42:34 +00:00
argspec = inspect.getargspec(func)
if name:
n_args = len(argspec.args)
if argspec.defaults:
n_args -= len(argspec.defaults)
if argspec.keywords:
n_args -= 1
if argspec.varargs:
n_args -= 1
if n_args != 1:
2010-03-01 02:32:41 +00:00
err = '%ss must take 1 non-keyword argument (%s)' % (name,
2010-02-02 04:42:34 +00:00
func.__name__)
raise ValueError(err)
args = []
if argspec.defaults:
end = bool(argspec.keywords) + bool(argspec.varargs)
args.extend(argspec.args[-len(argspec.defaults):
end if end else None])
if argspec.keywords:
2010-03-01 02:32:41 +00:00
args.append(0) # means kwargs present
2010-03-11 23:34:54 +00:00
func._args = args
2010-03-11 23:34:54 +00:00
if not hasattr(func, '_skybot_thread'): # does function run in its own thread?
func._thread = False
def sieve(func):
2010-03-11 23:34:54 +00:00
if func.func_code.co_argcount != 5:
raise ValueError(
2010-03-11 23:34:54 +00:00
'sieves must take 5 arguments: (bot, input, func, type, args)')
_hook_add(func, ['sieve', (func,)])
return func
2010-03-11 23:34:54 +00:00
def command(arg, **kwargs):
args = {}
def command_wrapper(func):
args.setdefault('name', func.func_name)
2010-03-11 23:34:54 +00:00
_hook_add(func, ['command', (func, args)], 'command')
return func
2010-03-11 23:34:54 +00:00
if kwargs or not inspect.isfunction(arg):
if arg is not None:
args['name'] = arg
args.update(kwargs)
return command_wrapper
else:
2010-03-11 23:34:54 +00:00
return command_wrapper(arg)
2009-04-17 21:54:11 +00:00
def event(arg=None, **kwargs):
args = kwargs
def event_wrapper(func):
args['name'] = func.func_name
2010-03-11 23:34:54 +00:00
args.setdefault('events', ['*'])
_hook_add(func, ['event', (func, args)], 'event')
return func
2010-03-11 23:34:54 +00:00
if inspect.isfunction(arg):
2009-04-17 21:54:11 +00:00
return event_wrapper(arg, kwargs)
else:
2009-04-17 21:54:11 +00:00
if arg is not None:
args['events'] = arg.split()
return event_wrapper
2009-11-19 00:39:27 +00:00
2010-03-11 23:34:54 +00:00
def thread(func):
func._thread = True
2009-11-19 00:39:27 +00:00
return func
def regex(regex, flags=0, **kwargs):
args = kwargs
def regex_wrapper(func):
args['name'] = func.func_name
args['regex'] = regex
args['re'] = re.compile(regex, flags)
_hook_add(func, ['regex', (func, args)], 'regex')
return func
if inspect.isfunction(regex):
raise ValueError("regex decorators require a regex to match against")
else:
return regex_wrapper