]> jfr.im git - erebus.git/blame - modlib.py
further py3 compatibility work
[erebus.git] / modlib.py
CommitLineData
931c88a4 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
a28e2ae9 5import sys
6
7if sys.version_info.major < 3:
8 stringbase = basestring
9else:
10 stringbase = str
11
e4255e70 12class error(object):
13 def __init__(self, desc):
14 self.errormsg = desc
15 def __nonzero__(self):
16 return False #object will test to False
71ef8273 17 __bool__ = __nonzero__ #py3 compat
e4255e70 18 def __repr__(self):
19 return '<modlib.error %r>' % self.errormsg
20 def __str__(self):
e3878612 21 return str(self.errormsg)
e4255e70 22
6c70d82c 23class modlib(object):
839d2b35 24 # default (global) access levels
69071d33 25 OWNER = 100
26 MANAGER = 99
27 ADMIN = 75
28 STAFF = 50
29 AUTHED = 0
30 ANYONE = -1
8b8ff79e 31 IGNORED = -2
931c88a4 32
839d2b35 33 # (channel) access levels
a290635a 34 COWNER = 5
69071d33 35 MASTER = 4
36 OP = 3
37 VOICE = 2
38 KNOWN = 1
39 PUBLIC = 0 #anyone (use glevel to control auth-needed)
8b8ff79e 40 BANNED = -1
f164fd1c 41 # [ 0 1 2 3 4 5 -1]
42 clevs = [None, 'Friend', 'Voice', 'Op', 'Master', 'Owner', None]
839d2b35 43
d431e543 44 # messages
45 WRONGARGS = "Wrong number of arguments."
46
6c70d82c 47 def __init__(self, name):
db50981b 48 self.hooks = {}
61b67f0f 49 self.numhooks = {}
2a1a69a6 50 self.chanhooks = {}
0f8352dd 51 self.helps = []
db50981b 52 self.parent = None
53
a8553c45 54 self.name = (name.split("."))[-1]
6c70d82c 55
56 def modstart(self, parent):
a62d0d18 57 #modstart can return a few things...
58 # None: unspecified success
59 # False: unspecified error
60 # modlib.error (or anything else False-y): specified error
61 # True: unspecified success
62 # non-empty string (or anything else True-y): specified success
63 #"specified" values will be printed. unspecified values will result in "OK" or "failed"
6c70d82c 64 self.parent = parent
a28e2ae9 65 for cmd, func in self.hooks.items():
6c70d82c 66 self.parent.hook(cmd, func)
a290635a 67 self.parent.hook("%s.%s" % (self.name, cmd), func)
a28e2ae9 68 for num, func in self.numhooks.items():
61b67f0f 69 self.parent.hooknum(num, func)
a28e2ae9 70 for chan, func in self.chanhooks.items():
2a1a69a6 71 self.parent.hookchan(chan, func)
0f8352dd 72
73 for func, args, kwargs in self.helps:
74 try:
75 self.mod('help').reghelp(func, *args, **kwargs)
76 except:
77 pass
d431e543 78 return True
db50981b 79 def modstop(self, parent):
a28e2ae9 80 for cmd, func in self.hooks.items():
1bdecfcd 81 parent.unhook(cmd, func)
82 parent.unhook("%s.%s" % (self.name, cmd), func)
a28e2ae9 83 for num, func in self.numhooks.items():
1bdecfcd 84 parent.unhooknum(num, func)
a28e2ae9 85 for chan, func in self.chanhooks.items():
1bdecfcd 86 parent.unhookchan(chan, func)
0f8352dd 87
88 for func, args, kwargs in self.helps:
89 try:
90 self.mod('help').dereghelp(func, *args, **kwargs)
91 except:
92 pass
d431e543 93 return True
6c70d82c 94
61b67f0f 95 def hooknum(self, num):
96 def realhook(func):
36411de9 97 self.numhooks[str(num)] = func
61b67f0f 98 if self.parent is not None:
36411de9 99 self.parent.hooknum(str(num), func)
61b67f0f 100 return func
101 return realhook
102
2a1a69a6 103 def hookchan(self, chan, glevel=ANYONE, clevel=PUBLIC):
104 def realhook(func):
105 self.chanhooks[chan] = func
106 if self.parent is not None:
107 self.parent.hookchan(chan, func)
108 return func
109 return realhook
110
827ec8f0 111 def hook(self, cmd=None, needchan=True, glevel=ANYONE, clevel=PUBLIC, wantchan=None):
112 if wantchan is None: wantchan = needchan
3a8b7b5f 113 _cmd = cmd #save this since it gets wiped out...
6c70d82c 114 def realhook(func):
3a8b7b5f 115 cmd = _cmd #...and restore it
116 if cmd is None:
117 cmd = func.__name__ # default to function name
a28e2ae9 118 if isinstance(cmd, stringbase):
0f8352dd 119 cmd = (cmd,)
3a8b7b5f 120
839d2b35 121 func.needchan = needchan
827ec8f0 122 func.wantchan = wantchan
839d2b35 123 func.reqglevel = glevel
124 func.reqclevel = clevel
0f8352dd 125 func.cmd = cmd
179c06a9 126 func.module = func.__module__.split('.')[1]
839d2b35 127
9ea2be43 128 for c in cmd:
129 self.hooks[c] = func
130 if self.parent is not None:
131 self.parent.hook(c, func)
a290635a 132 self.parent.hook("%s.%s" % (self.name, c), func)
6c70d82c 133 return func
134 return realhook
d431e543 135
36411de9 136 def mod(self, modname):
137 if self.parent is not None:
138 return self.parent.module(modname)
139 else:
140 return error('unknown parent')
141
d431e543 142 def argsEQ(self, num):
143 def realhook(func):
144 def checkargs(bot, user, chan, realtarget, *args):
145 if len(args) == num:
146 return func(bot, user, chan, realtarget, *args)
147 else:
148 bot.msg(user, self.WRONGARGS)
3a8b7b5f 149 checkargs.__name__ = func.__name__
11ef6fed 150 checkargs.__module__ = func.__module__
d431e543 151 return checkargs
152 return realhook
153
154 def argsGE(self, num):
155 def realhook(func):
156 def checkargs(bot, user, chan, realtarget, *args):
157 if len(args) >= num:
158 return func(bot, user, chan, realtarget, *args)
159 else:
160 bot.msg(user, self.WRONGARGS)
3a8b7b5f 161 checkargs.__name__ = func.__name__
11ef6fed 162 checkargs.__module__ = func.__module__
d431e543 163 return checkargs
164 return realhook
b670c2f4 165
984fc310 166 def help(self, *args, **kwargs):
0f8352dd 167 """help(syntax, shorthelp, longhelp?, more lines longhelp?, cmd=...?)
b670c2f4 168 Example:
169 help("<user> <pass>", "login")
170 ^ Help will only be one line. Command name determined based on function name.
171 help("<user> <level>", "add a user", cmd=("adduser", "useradd"))
172 ^ Help will be listed under ADDUSER; USERADD will say "alias for adduser"
173 help(None, "do stuff", "This command is really complicated.")
174 ^ Command takes no args. Short description (in overall HELP listing) is "do stuff".
175 Long description (HELP <command>) will say "<command> - do stuff", newline, "This command is really complicated."
176 """
0f8352dd 177 def realhook(func):
178 if self.parent is not None:
179 try:
180 self.mod('help').reghelp(func, *args, **kwargs)
181 except:
182 pass
71ef8273 183 self.helps.append((func, args, kwargs))
0f8352dd 184 return func
185 return realhook