implement RE (regular expression) dispatcher.
Bases: gozerbot.redispatcher.REDispatcher
dispatcher on Event.
dispatch callback on event.
Bases: object
a regular expression callback.
Bases: object
this is were the regexs callbacks live.
enable a REcallback.
add a regular expression command.
disable a REcallback.
try to dispatch callback on txt.
get re callback if txt matches.
return function names in plugin.
list RECallbacks with permission perm.
overload permission of function with funcname.
nr of callbacks.
unload regex commands.
return possible permissions.
# gozerbot/redispatcher.py # # """ implement RE (regular expression) dispatcher. """ __status__ = "seen"
from config import config from utils.log import rlog from utils.trace import calledfrom from utils.exception import handle_exception from utils.locking import lockdec from runner import cmndrunners import threads.thr as thr
import sys import re import copy import types import thread
relock = thread.allocate_lock() locked = lockdec(relock)
class RECallback(object): """ a regular expression callback. """ def __init__(self, index, regex, func, perm, plugname, speed=5, threaded=True, allowqueue=True, options={}): self.name = thr.getname(func) # name of the callback self.index = index # index into the list self.regex = regex # the RE to match self.compiled = re.compile(regex) # compiled RE self.func = func # the function to call if RE matches if type(perm) == types.ListType: self.perms = list(perm) else: self.perms = [perm, ] self.plugname = plugname # plugname where RE callbacks is registered self.speed = copy.deepcopy(speed) # speed at which the function runs self.threaded = copy.deepcopy(threaded) # set when run threaade self.allowqueue = copy.deepcopy(allowqueue) # set when pipeline is allowed self.options = dict(options) # options set on the callback self.activate = True class REDispatcher(object): """ this is were the regexs callbacks live. """ def __init__(self): self.relist = [] def size(self): """ nr of callbacks. """ return len(self.relist) def activate(self, plugname): """ enable a REcallback. """ for i in self.relist: if i.plugname == plugname: i.activate = True def disable(self, plugname): """ disable a REcallback. """ for i in self.relist: if i.plugname == plugname: i.activate = False def whatperms(self): """ return possible permissions. """ result = [] for i in self.relist: for j in i.perms: if j not in result: result.append(j) return result def list(self, perm): """ list RECallbacks with permission perm. """ result = [] perm = perm.upper() for recom in self.relist: if perm in recom.perms: result.append(recom) return result def getfuncnames(self, plug): """ return function names in plugin. """ result = [] for i in self.relist: if i.plugname == plug: result.append(i.func.func_name) return result def permoverload(self, funcname, perms): """ overload permission of function with funcname. """ perms = [perm.upper() for perm in perms] got = 0 for nr in range(len(self.relist)): try: if self.relist[nr].func.func_name == funcname: self.relist[nr].perms = list(perms) rlog(0, 'redispatcher', '%s function overloaded with %s' % (funcname, perms)) got = 1 except AttributeError: rlog(10, 'redispatcher', 'permoverload: no %s function' % funcname) if got: return True return False def add(self, index, regex, func, perm, speed=5, threaded=True, allowqueue=True, options={}): """ add a regular expression command. """ try: plugname = calledfrom(sys._getframe()) if config['loadlist'] and plugname not in config['loadlist']: return self.relist.append(RECallback(index, regex, func, perm, plugname, speed, threaded, allowqueue, options)) self.relist.sort(lambda a, b: cmp(a.index, b.index)) rlog(0, 'redispatcher', 'added %s (%s) ' % (regex, plugname)) except Exception, ex: handle_exception() def unload(self, plugname): """ unload regex commands. """ got = False try: for i in range(len(self.relist)-1, -1 , -1): if self.relist[i].plugname == plugname: rlog(1, 'redispatcher', 'unloading %s (%s)' % (self.relist[i].regex, plugname)) del self.relist[i] got = True finally: pass return got def getcallback(self, txt): """ get re callback if txt matches. """ for i in self.relist: try: result = re.search(i.compiled, txt) if result: return i except: pass def dispatch(self, callback, txt, wait=False): """ try to dispatch callback on txt. """ try: result = re.search(callback.compiled, txt) if result: if callback.threaded: thread = thr.start_new_thread(callback.func, (txt, result.groups())) if wait: thread.join() else: cmndrunners.put(callback.plugname, callback.func, txt, result.groups()) return 1 except Exception, ex: handle_exception() class BotREDispatcher(REDispatcher): """ dispatcher on Event. """ def dispatch(self, callback, bot, ievent, wait=False): """ dispatch callback on event. """ if not self.activate: return False try: result = re.search(callback.compiled, ievent.txt.strip()) if result: ievent.groups = list(result.groups()) if callback.threaded or ievent.threaded: thread = thr.start_bot_command(callback.func, (bot, ievent)) if thread and wait: thread.join() else: cmndrunners.put(callback.plugname, callback.func, bot, ievent) return True except Exception, ex: handle_exception(ievent) return False
rebefore = BotREDispatcher() reafter = BotREDispatcher()