]>
Commit | Line | Data |
---|---|---|
0f8352dd | 1 | # Erebus IRC bot - Author: Erebus Team |
4477123d | 2 | # vim: fileencoding=utf-8 |
0f8352dd | 3 | # help module |
4 | # This file is released into the public domain; see http://unlicense.org/ | |
5 | ||
6 | # module info | |
7 | modinfo = { | |
8 | 'author': 'Erebus Team', | |
9 | 'license': 'public domain', | |
fa93b933 | 10 | 'compatible': [0], |
a62d0d18 | 11 | 'depends': [], |
12 | 'softdeps': [], | |
0f8352dd | 13 | } |
14 | ||
15 | # preamble | |
16 | import modlib | |
17 | lib = modlib.modlib(__name__) | |
3569ead3 | 18 | def modstart(parent, *args, **kwargs): |
19 | if parent.cfg.getboolean('erebus', 'nofakelag'): | |
b367d0c5 | 20 | lib.hook('help', needchan=False)(lib.help('[@<module>|<command>]', 'lists commands or describes a command', 'with @<module>, lists all commands in <module>')(help_nolag)) |
3569ead3 | 21 | else: |
88a9e314 | 22 | lib.hook('help', needchan=False)(lib.help("<command>", "describes a command", "see also: showcommands")(help)) |
3569ead3 | 23 | return lib.modstart(parent, *args, **kwargs) |
0f8352dd | 24 | modstop = lib.modstop |
25 | ||
26 | # module code | |
321c1b02 | 27 | import functools |
bc68cb5e | 28 | import os.path |
0f8352dd | 29 | helps = {} |
30 | cmds = {} | |
31 | ||
32 | # ! this is part of this module's API, called from modlib.help() | |
0f8352dd | 33 | def reghelp(func, *args, **kwargs): |
34 | syntax = None | |
35 | shorthelp = None | |
36 | longhelps = [] | |
37 | ||
38 | if len(args) > 0: | |
39 | syntax = args[0] | |
40 | if len(args) > 1: | |
41 | shorthelp = args[1] | |
42 | if len(args) > 2: | |
43 | longhelps = args[2:] | |
44 | ||
45 | if 'syntax' in kwargs: | |
46 | syntax = kwargs['syntax'] | |
47 | if 'shorthelp' in kwargs: | |
48 | shorthelp = kwargs['shorthelp'] | |
49 | if 'longhelps' in kwargs: | |
50 | longhelps = kwargs['longhelps'] | |
51 | ||
52 | if syntax is None: syntax = "" | |
53 | if shorthelp is None: shorthelp = "" | |
54 | ||
55 | func.syntax = syntax | |
56 | func.shorthelp = shorthelp | |
57 | func.longhelps = longhelps | |
58 | helps[func] = func | |
59 | for c in func.cmd: | |
60 | cmds[c] = func | |
61 | ||
62 | def dereghelp(func, *args, **kwargs): | |
63 | for c in func.cmd: | |
bc68cb5e | 64 | del cmds[c] |
0f8352dd | 65 | del helps[func] |
66 | ||
321c1b02 | 67 | @functools.total_ordering |
7d0de55e | 68 | class HelpLine(object): |
d58c924f | 69 | def __init__(self, cmd, syntax, shorthelp, admin, glevel, module, clevel): |
7d0de55e | 70 | self.cmd = cmd |
71 | self.syntax = syntax | |
72 | self.shorthelp = shorthelp | |
58401d09 | 73 | self.admin = admin |
d58c924f | 74 | self.glevel = glevel |
58401d09 | 75 | self.module = module |
d58c924f | 76 | self.clevel = clevel |
7d0de55e | 77 | |
321c1b02 JR |
78 | def __lt__(self, other): |
79 | if self.glevel == other.glevel: | |
80 | return self.cmd < other.cmd | |
81 | else: | |
82 | return self.glevel < other.glevel | |
83 | ||
84 | def __eq__(self, other): | |
85 | return self.glevel == other.glevel and self.cmd == other.cmd | |
86 | ||
7d0de55e | 87 | def __cmp__(self, other): |
d58c924f | 88 | if self.glevel == other.glevel: |
7d0de55e | 89 | return cmp(self.cmd, other.cmd) |
90 | else: | |
d58c924f | 91 | return cmp(self.glevel, other.glevel) |
7d0de55e | 92 | |
93 | ||
94 | def __str__(self): | |
58401d09 | 95 | if self.admin: |
e6b60193 | 96 | ret = "%-25s(%3s) - %-10s - " % (self.cmd+' '+self.syntax, self.glevel, self.module) |
7d0de55e | 97 | else: |
e6b60193 | 98 | ret = "%-30s - " % (self.cmd+' '+self.syntax) |
d58c924f | 99 | if self.clevel != 0: |
100 | ret += "(%s) " % (lib.clevs[self.clevel]) | |
101 | ret += str(self.shorthelp) | |
102 | return ret | |
7d0de55e | 103 | |
bc68cb5e | 104 | def _mkhelp(level, func): |
105 | lines = [] | |
106 | if level >= func.reqglevel: | |
d58c924f | 107 | lines.append(HelpLine(func.cmd[0], func.syntax, func.shorthelp, (level > 0), func.reqglevel, func.module, func.reqclevel)) |
bc68cb5e | 108 | if len(func.cmd) > 1: |
109 | for c in func.cmd[1:]: | |
d58c924f | 110 | lines.append(HelpLine(c, "", "Alias of %s" % (func.cmd[0]), (level > 0), func.reqglevel, func.module, func.reqclevel)) |
bc68cb5e | 111 | return lines |
112 | ||
113 | def _genhelp(bot, user, chan, realtarget, *args): | |
caa333c3 | 114 | module = '' |
898cf6a5 | 115 | minlevel = -1 |
116 | maxlevel = 100 | |
caa333c3 | 117 | filepath = bot.parent.cfg.get('help', 'path', default='./help/%(@)s%(#)d.txt') |
898cf6a5 | 118 | for arg in args: |
fd07173d | 119 | if arg.startswith("@"): |
caa333c3 | 120 | if "." in arg[1:]: |
121 | raise Exception('Module option must not contain "."') | |
898cf6a5 | 122 | module = arg[1:] |
fd07173d | 123 | elif arg.startswith("#") and user.glevel >= lib.ADMIN: |
898cf6a5 | 124 | minlevel = maxlevel = int(arg[1:]) |
caa333c3 | 125 | elif arg.startswith("+"): |
126 | maxlevel = int(arg[1:]) | |
127 | elif arg.startswith("-"): | |
128 | minlevel = int(arg[1:]) | |
129 | elif arg.startswith("./"): | |
130 | if "./" in arg[1:]: | |
131 | raise Exception('Filename option must not contain "./" except as the first two characters') | |
132 | else: | |
133 | filepath = os.path.join('help', arg[2:]) | |
898cf6a5 | 134 | else: |
caa333c3 | 135 | raise Exception('Unknown option given to GENHELP: %s' % (arg)) |
898cf6a5 | 136 | for level in range(minlevel, maxlevel+1): |
caa333c3 | 137 | filename = filepath % {'#': level, '+': maxlevel, '-': minlevel, '@': module} |
0d93d7b4 | 138 | fo = open(filename, 'w') |
139 | lines = [] | |
a28e2ae9 | 140 | for func in helps.values(): |
caa333c3 | 141 | if module != '' and func.module != module: |
898cf6a5 | 142 | continue |
0d93d7b4 | 143 | lines += _mkhelp(level, func) |
144 | for line in sorted(lines): | |
145 | fo.write(str(line)+"\n") | |
898cf6a5 | 146 | fo.close() |
bc68cb5e | 147 | return True |
148 | ||
149 | @lib.hook(glevel=1, needchan=False) | |
4d925ae3 | 150 | @lib.help("[@<module>] [#<exact_level>] [+<max_level>] [-<min_level>] [./<filename>]", "generates help file", "arguments are all optional and may be specified in any order", "default file: ./<module><level>.txt, with module blank if not supplied. will always be under help/", "filename can also contain %(@)s, %(#)s, %(+)s, %(-)s", "for module, current (single) level, max and min level, respectively") |
bc68cb5e | 151 | def genhelp(bot, user, chan, realtarget, *args): |
0d93d7b4 | 152 | try: |
153 | _genhelp(bot, user, chan, realtarget, *args) | |
154 | except Exception as e: | |
155 | bot.msg(user, "Failed writing help. %s" % (e)) | |
156 | return | |
157 | bot.msg(user, "Help written.") | |
bc68cb5e | 158 | |
a148e37f | 159 | # This is hooked in modstart |
3569ead3 | 160 | #@lib.hook(needchan=False) |
161 | #@lib.help("<command>", "describes a command") | |
bc68cb5e | 162 | def help(bot, user, chan, realtarget, *args): |
a148e37f | 163 | if len(args) == 0: |
164 | bot.msg(user, "Usage: %sHELP <command>" % bot.parent.trigger) | |
165 | return showcommands(bot, user, chan, realtarget, *args) | |
166 | ||
bc68cb5e | 167 | cmd = str(' '.join(args)).lower() |
168 | if cmd in cmds and user.glevel >= cmds[cmd].reqglevel: | |
169 | func = cmds[cmd] | |
d58c924f | 170 | bot.slowmsg(user, str(HelpLine(func.cmd[0], func.syntax, func.shorthelp, (user.glevel > 0), func.reqglevel, func.module, func.reqclevel))) |
bc68cb5e | 171 | for line in func.longhelps: |
172 | bot.slowmsg(user, " %s" % (line)) | |
bc68cb5e | 173 | if len(func.cmd) > 1: |
174 | bot.slowmsg(user, " Aliases: %s" % (' '.join(func.cmd[1:]))) | |
175 | else: | |
176 | bot.slowmsg(user, "No help found for %s" % (cmd)) | |
177 | ||
178 | @lib.hook(needchan=False) | |
179 | @lib.help(None, "provides command list") | |
180 | def showcommands(bot, user, chan, realtarget, *args): | |
662003f2 JR |
181 | if bot.parent.cfg.getboolean('erebus', 'nofakelag'): |
182 | return help_nolag(bot, user, chan, realtarget, *args) | |
dcc5bde3 | 183 | if bot.parent.cfg.getboolean('help', 'autogen'): |
0d93d7b4 | 184 | try: |
185 | _genhelp(bot, user, chan, realtarget, *args) | |
186 | except: pass | |
187 | ||
bc68cb5e | 188 | url = bot.parent.cfg.get('help', 'url', default=None) |
bc68cb5e | 189 | if url is not None: |
190 | url = url % (user.glevel) | |
a148e37f | 191 | bot.msg(user, "Command list is at: %s" % (url)) |
bc68cb5e | 192 | else: |
a148e37f | 193 | bot.msg(user, "I don't know where help is. Sorry. Contact my owner and tell him to set in the config file [help] url = .") |
bc68cb5e | 194 | |
a148e37f | 195 | # This is hooked in modstart |
3569ead3 | 196 | #@lib.hook(needchan=False) |
197 | #@lib.help('[@<module>|<command>]', 'lists commands or describes a command', 'with @<module>, lists all commands in <module>') | |
198 | def help_nolag(bot, user, chan, realtarget, *args): | |
5f03d045 | 199 | if len(args) == 0: # list commands |
7d0de55e | 200 | lines = [] |
a28e2ae9 | 201 | for func in helps.values(): |
3df2045a | 202 | lines += _mkhelp(user.glevel, func) |
bc68cb5e | 203 | for line in sorted(lines): |
204 | bot.slowmsg(user, str(line)) | |
205 | bot.slowmsg(user, "End of command listing.") | |
fd07173d | 206 | elif args[0].startswith("@"): |
bc68cb5e | 207 | lines = [] |
208 | mod = args[0][1:].lower() | |
a28e2ae9 | 209 | for func in helps.values(): |
bc68cb5e | 210 | if func.module == mod: |
2564f208 | 211 | lines += _mkhelp(user.glevel, func) |
7d0de55e | 212 | for line in sorted(lines): |
213 | bot.slowmsg(user, str(line)) | |
954cae0b | 214 | bot.slowmsg(user, "End of command listing.") |
5f03d045 | 215 | else: # help for a specific command/topic |
bc68cb5e | 216 | cmd = str(' '.join(args)).lower() |
0f8352dd | 217 | if cmd in cmds and user.glevel >= cmds[cmd].reqglevel: |
218 | func = cmds[cmd] | |
d4cfb340 | 219 | bot.slowmsg(user, str(HelpLine(func.cmd[0], func.syntax, func.shorthelp, (user.glevel > 0), func.reqglevel, func.module, func.reqclevel))) |
0f8352dd | 220 | for line in func.longhelps: |
221 | bot.slowmsg(user, " %s" % (line)) | |
954cae0b | 222 | bot.slowmsg(user, "End of help for %s." % (func.cmd[0])) |
0f8352dd | 223 | |
224 | if len(func.cmd) > 1: | |
225 | bot.slowmsg(user, " Aliases: %s" % (' '.join(func.cmd[1:]))) | |
226 | else: | |
227 | bot.slowmsg(user, "No help found for %s" % (cmd)) |