]> jfr.im git - erebus.git/blob - modlib.py
modlib - use parent provided to modstop directly, instead of relying on self.parent...
[erebus.git] / modlib.py
1 # Erebus IRC bot - Author: John Runyon
2 # module helper functions, see modules/modtest.py for usage
3 # This file is released into the public domain; see http://unlicense.org/
4
5 class error(object):
6 def __init__(self, desc):
7 self.errormsg = desc
8 def __nonzero__(self):
9 return False #object will test to False
10 def __repr__(self):
11 return '<modlib.error %r>' % self.errormsg
12 def __str__(self):
13 return str(self.errormsg)
14
15 class modlib(object):
16 # default (global) access levels
17 OWNER = 100
18 MANAGER = 99
19 ADMIN = 75
20 STAFF = 50
21 AUTHED = 0
22 ANYONE = -1
23
24 # (channel) access levels
25 COWNER = 5
26 MASTER = 4
27 OP = 3
28 VOICE = 2
29 KNOWN = 1
30 PUBLIC = 0 #anyone (use glevel to control auth-needed)
31
32 # messages
33 WRONGARGS = "Wrong number of arguments."
34
35 def __init__(self, name):
36 self.hooks = {}
37 self.numhooks = {}
38 self.chanhooks = {}
39 self.helps = []
40 self.parent = None
41
42 self.name = (name.split("."))[-1]
43
44 def modstart(self, parent):
45 #modstart can return a few things...
46 # None: unspecified success
47 # False: unspecified error
48 # modlib.error (or anything else False-y): specified error
49 # True: unspecified success
50 # non-empty string (or anything else True-y): specified success
51 #"specified" values will be printed. unspecified values will result in "OK" or "failed"
52 self.parent = parent
53 for cmd, func in self.hooks.iteritems():
54 self.parent.hook(cmd, func)
55 self.parent.hook("%s.%s" % (self.name, cmd), func)
56 for num, func in self.numhooks.iteritems():
57 self.parent.hooknum(num, func)
58 for chan, func in self.chanhooks.iteritems():
59 self.parent.hookchan(chan, func)
60
61 for func, args, kwargs in self.helps:
62 try:
63 self.mod('help').reghelp(func, *args, **kwargs)
64 except:
65 pass
66 return True
67 def modstop(self, parent):
68 for cmd, func in self.hooks.iteritems():
69 parent.unhook(cmd, func)
70 parent.unhook("%s.%s" % (self.name, cmd), func)
71 for num, func in self.numhooks.iteritems():
72 parent.unhooknum(num, func)
73 for chan, func in self.chanhooks.iteritems():
74 parent.unhookchan(chan, func)
75
76 for func, args, kwargs in self.helps:
77 try:
78 self.mod('help').dereghelp(func, *args, **kwargs)
79 except:
80 pass
81 return True
82
83 def hooknum(self, num):
84 def realhook(func):
85 self.numhooks[str(num)] = func
86 if self.parent is not None:
87 self.parent.hooknum(str(num), func)
88 return func
89 return realhook
90
91 def hookchan(self, chan, glevel=ANYONE, clevel=PUBLIC):
92 def realhook(func):
93 self.chanhooks[chan] = func
94 if self.parent is not None:
95 self.parent.hookchan(chan, func)
96 return func
97 return realhook
98
99 def hook(self, cmd=None, needchan=True, glevel=ANYONE, clevel=PUBLIC):
100 _cmd = cmd #save this since it gets wiped out...
101 def realhook(func):
102 cmd = _cmd #...and restore it
103 if cmd is None:
104 cmd = func.__name__ # default to function name
105 if isinstance(cmd, basestring):
106 cmd = (cmd,)
107
108 func.needchan = needchan
109 func.reqglevel = glevel
110 func.reqclevel = clevel
111 func.cmd = cmd
112 func.module = func.__module__.split('.')[1]
113
114 for c in cmd:
115 self.hooks[c] = func
116 if self.parent is not None:
117 self.parent.hook(c, func)
118 self.parent.hook("%s.%s" % (self.name, c), func)
119 return func
120 return realhook
121
122 def mod(self, modname):
123 if self.parent is not None:
124 return self.parent.module(modname)
125 else:
126 return error('unknown parent')
127
128 def argsEQ(self, num):
129 def realhook(func):
130 def checkargs(bot, user, chan, realtarget, *args):
131 if len(args) == num:
132 return func(bot, user, chan, realtarget, *args)
133 else:
134 bot.msg(user, self.WRONGARGS)
135 checkargs.__name__ = func.__name__
136 checkargs.__module__ = func.__module__
137 return checkargs
138 return realhook
139
140 def argsGE(self, num):
141 def realhook(func):
142 def checkargs(bot, user, chan, realtarget, *args):
143 if len(args) >= num:
144 return func(bot, user, chan, realtarget, *args)
145 else:
146 bot.msg(user, self.WRONGARGS)
147 checkargs.__name__ = func.__name__
148 checkargs.__module__ = func.__module__
149 return checkargs
150 return realhook
151
152 def help(self, *args, **kwargs):
153 """help(syntax, shorthelp, longhelp?, more lines longhelp?, cmd=...?)
154 Example:
155 help("<user> <pass>", "login")
156 ^ Help will only be one line. Command name determined based on function name.
157 help("<user> <level>", "add a user", cmd=("adduser", "useradd"))
158 ^ Help will be listed under ADDUSER; USERADD will say "alias for adduser"
159 help(None, "do stuff", "This command is really complicated.")
160 ^ Command takes no args. Short description (in overall HELP listing) is "do stuff".
161 Long description (HELP <command>) will say "<command> - do stuff", newline, "This command is really complicated."
162 """
163 def realhook(func):
164 if self.parent is not None:
165 try:
166 self.mod('help').reghelp(func, *args, **kwargs)
167 except:
168 pass
169 self.helps.append((func,args,kwargs))
170 return func
171 return realhook