]>
jfr.im git - erebus.git/blob - modlib.py
b09272e89b3704d8daa3ef3f7d03b0555db3e05e
1 # Erebus IRC bot - Author: John Runyon
2 # vim: fileencoding=utf-8
3 # module helper functions, see modules/modtest.py for usage
4 # This file is released into the public domain; see http://unlicense.org/
7 from functools
import wraps
9 if sys
.version_info
.major
< 3:
10 stringbase
= basestring
14 """Used to return an error to the bot core."""
16 def __init__(self
, desc
):
18 def __nonzero__(self
):
19 return False #object will test to False
20 __bool__
= __nonzero__
#py3 compat
22 return '<modlib.error %r>' % self
.errormsg
24 return str(self
.errormsg
)
27 # default (global) access levels
33 AUTHED
= 0 # Users which have are known to be authed
34 ANYONE
= -1 # non-authed users have glevel set to -1
35 IGNORED
= -2 # The default reqglevel is ANYONE, so any commands will be ignored from IGNORED users unless the command reglevel=-2
47 # (channel) access levels
52 #KNOWN = 1 is set above by glevels
53 PUBLIC
= 0 # Anyone (use glevel to control whether auth is needed)
54 BANNED
= -1 # The default reqclevel is PUBLIC, so any commands which needchan will be ignored from BANNED users unless the command reqclevel=-1
56 clevs
= [None, 'Friend', 'Voice', 'Op', 'Master', 'Owner', None]
59 WRONGARGS
= "Wrong number of arguments."
61 def __init__(self
, name
):
65 self
.exceptionhooks
= []
69 self
.name
= (name
.split("."))[-1]
71 def modstart(self
, parent
):
72 #modstart can return a few things...
73 # None: unspecified success
74 # False: unspecified error
75 # modlib.error (or anything else False-y): specified error
76 # True: unspecified success
77 # non-empty string (or anything else True-y): specified success
78 #"specified" values will be printed. unspecified values will result in "OK" or "failed"
80 for cmd
, func
in self
.hooks
.items():
81 parent
.hook(cmd
, func
)
82 parent
.hook("%s.%s" % (self
.name
, cmd
), func
)
83 for num
, func
in self
.numhooks
.items():
84 parent
.hooknum(num
, func
)
85 for chan
, func
in self
.chanhooks
.items():
86 parent
.hookchan(chan
, func
)
87 for exc
, func
in self
.exceptionhooks
:
88 parent
.hookexception(exc
, func
)
90 for func
, args
, kwargs
in self
.helps
:
92 self
.mod('help').reghelp(func
, *args
, **kwargs
)
96 def modstop(self
, parent
):
97 for cmd
, func
in self
.hooks
.items():
98 parent
.unhook(cmd
, func
)
99 parent
.unhook("%s.%s" % (self
.name
, cmd
), func
)
100 for num
, func
in self
.numhooks
.items():
101 parent
.unhooknum(num
, func
)
102 for chan
, func
in self
.chanhooks
.items():
103 parent
.unhookchan(chan
, func
)
104 for exc
, func
in self
.exceptionhooks
:
105 parent
.unhookexception(exc
, func
)
107 for func
, args
, kwargs
in self
.helps
:
109 self
.mod('help').dereghelp(func
, *args
, **kwargs
)
114 def hookexception(self
, exc
):
116 self
.exceptionhooks
.append((exc
, func
))
117 if self
.parent
is not None:
118 self
.parent
.hookexception(exc
, func
)
122 def hooknum(self
, num
):
124 self
.numhooks
[str(num
)] = func
125 if self
.parent
is not None:
126 self
.parent
.hooknum(str(num
), func
)
130 def hookchan(self
, chan
, glevel
=ANYONE
, clevel
=PUBLIC
):
132 self
.chanhooks
[chan
] = func
133 if self
.parent
is not None:
134 self
.parent
.hookchan(chan
, func
)
138 def hook(self
, cmd
=None, needchan
=True, glevel
=ANYONE
, clevel
=PUBLIC
, wantchan
=None):
139 if wantchan
is None: wantchan
= needchan
140 _cmd
= cmd
#save this since it gets wiped out...
142 cmd
= _cmd
#...and restore it
144 cmd
= func
.__name
__ # default to function name
145 if isinstance(cmd
, stringbase
):
148 if clevel
> self
.PUBLIC
and not needchan
:
149 raise Exception('clevel must be left at default if needchan is False')
151 func
.needchan
= needchan
152 func
.wantchan
= wantchan
153 func
.reqglevel
= glevel
154 func
.reqclevel
= clevel
156 func
.module
= func
.__module
__.split('.')[1]
160 if self
.parent
is not None:
161 self
.parent
.hook(c
, func
)
162 self
.parent
.hook("%s.%s" % (self
.name
, c
), func
)
166 def mod(self
, modname
):
167 if self
.parent
is not None:
168 return self
.parent
.module(modname
)
170 return error('unknown parent')
172 def argsEQ(self
, num
):
175 def checkargs(bot
, user
, chan
, realtarget
, *args
):
177 return func(bot
, user
, chan
, realtarget
, *args
)
179 bot
.msg(user
, self
.WRONGARGS
)
183 def argsGE(self
, num
):
186 def checkargs(bot
, user
, chan
, realtarget
, *args
):
188 return func(bot
, user
, chan
, realtarget
, *args
)
190 bot
.msg(user
, self
.WRONGARGS
)
194 def help(self
, *args
, **kwargs
):
195 """help(syntax, shorthelp, longhelp?, more lines longhelp?, cmd=...?)
197 help("<user> <pass>", "login")
198 ^ Help will only be one line. Command name determined based on function name.
199 help("<user> <level>", "add a user", cmd=("adduser", "useradd"))
200 ^ Help will be listed under ADDUSER; USERADD will say "alias for adduser"
201 help(None, "do stuff", "This command is really complicated.")
202 ^ Command takes no args. Short description (in overall HELP listing) is "do stuff".
203 Long description (HELP <command>) will say "<command> - do stuff", newline, "This command is really complicated."
206 if self
.parent
is not None:
208 self
.mod('help').reghelp(func
, *args
, **kwargs
)
211 self
.helps
.append((func
, args
, kwargs
))