1
# gozerbot/redispatcher.py
5
""" implement RE (regular expression) dispatcher """
7
__copyright__ = 'this file is in the public domain'
9
from gozerbot.generic import rlog, calledfrom, handle_exception, lockdec
10
import gozerbot.thr as thr
11
import sys, re, copy, types, thread
13
relock = thread.allocate_lock()
14
locked = lockdec(relock)
16
class Recallback(object):
18
""" a regular expression callback """
20
def __init__(self, index, regex, func, perm, plugname, speed=5, \
21
threaded=True, allowqueue=True, options={}):
22
# index of place of RE callback in list
27
self.compiled = re.compile(regex)
28
# the function to call if RE matches
30
# make sure perms is a list
31
if type(perm) == types.ListType:
32
self.perms = list(perm)
36
self.plugname = plugname
37
# speed at which the functin is to be dispatched
38
self.speed = copy.deepcopy(speed)
39
# flag to see if RE callback is to be run in a thread or in the main
41
self.threaded = copy.deepcopy(threaded)
42
self.allowqueue = copy.deepcopy(allowqueue)
43
self.options = dict(options)
45
class Redispatcher(object):
47
""" this is were the regexs callbacks live """
53
""" nr of callbacks """
54
return len(self.relist)
57
""" return possible permissions """
66
""" list re with permission perm """
69
for recom in self.relist:
70
if perm in recom.perms:
74
def getfuncnames(self, plug):
75
""" return function names in plugin """
78
if i.plugname == plug:
79
result.append(i.func.func_name)
82
def permoverload(self, funcname, perms):
83
""" overload permission of function with funcname """
84
perms = [perm.upper() for perm in perms]
86
for nr in range(len(self.relist)):
88
if self.relist[nr].func.func_name == funcname:
89
self.relist[nr].perms = list(perms)
90
rlog(0, 'redispatcher', '%s function overloaded with %s' \
93
except AttributeError:
94
rlog(10, 'redispatcher', 'permoverload: no %s function' % \
99
def add(self, index, regex, func, perm, speed=5, threaded=True, \
100
allowqueue=True, options={}):
101
""" add a command """
103
# get plugin name from where callback is added
104
plugname = calledfrom(sys._getframe())
106
self.relist.append(Recallback(index, regex, func, perm, plugname, \
107
speed, threaded, allowqueue, options))
108
# sort of index number
109
self.relist.sort(lambda a, b: cmp(a.index, b.index))
110
rlog(0, 'redispatcher', 'added %s (%s) ' % (regex, plugname))
114
def unload(self, plugname):
115
""" unload regexs commands """
118
for i in range(len(self.relist)-1, -1 , -1):
119
if self.relist[i].plugname == plugname:
120
rlog(1, 'redispatcher', 'unloading %s (%s)' % \
121
(self.relist[i].regex, plugname))
129
def getcallback(self, txt):
130
""" get re callback if txt matches """
131
for i in self.relist:
133
result = re.search(i.compiled, txt)
139
def dispatch(self, callback, txt):
140
""" dispatch callback on txt """
142
result = re.search(callback.compiled, txt)
144
if callback.threaded:
145
thr.start_new_thread(callback.func, (txt, result.groups()))
147
callback.func(txt, result.groups())
149
except Exception, ex:
152
class Botredispatcher(Redispatcher):
154
""" dispatcher on ircevent """
156
def dispatch(self, callback, bot, ievent):
157
""" dispatch callback on ircevent """
159
result = re.search(callback.compiled, ievent.txt)
161
ievent.groups = list(result.groups())
162
if callback.threaded:
163
thr.start_bot_command(callback.func, (bot, ievent))
165
callback.func(bot, ievent)
167
except Exception, ex:
168
handle_exception(ievent)
170
rebefore = Botredispatcher()
171
reafter = Botredispatcher()