1 # Erebus IRC bot - Author: Erebus Team
2 # vim: fileencoding=utf-8
4 # This file is released into the public domain; see http://unlicense.org/
8 'author': 'Erebus Team',
9 'license': 'public domain',
17 lib
= modlib
.modlib(__name__
)
18 def modstart(parent
, *args
, **kwargs
):
19 if parent
.cfg
.getboolean('erebus', 'nofakelag'):
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
))
22 lib
.hook('help', needchan
=False)(lib
.help("<command>", "describes a command", "see also: showcommands")(help))
23 return lib
.modstart(parent
, *args
, **kwargs
)
32 # ! this is part of this module's API, called from modlib.help()
33 def reghelp(func
, *args
, **kwargs
):
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']
52 if syntax
is None: syntax
= ""
53 if shorthelp
is None: shorthelp
= ""
56 func
.shorthelp
= shorthelp
57 func
.longhelps
= longhelps
62 def dereghelp(func
, *args
, **kwargs
):
67 @functools.total_ordering
68 class HelpLine(object):
69 def __init__(self
, cmd
, syntax
, shorthelp
, admin
, glevel
, module
, clevel
):
72 self
.shorthelp
= shorthelp
78 def __lt__(self
, other
):
79 if self
.glevel
== other
.glevel
:
80 return self
.cmd
< other
.cmd
82 return self
.glevel
< other
.glevel
84 def __eq__(self
, other
):
85 return self
.glevel
== other
.glevel
and self
.cmd
== other
.cmd
87 def __cmp__(self
, other
):
88 if self
.glevel
== other
.glevel
:
89 return cmp(self
.cmd
, other
.cmd
)
91 return cmp(self
.glevel
, other
.glevel
)
96 ret
= "%-25s(%3s) - %-10s - " % (self
.cmd
+' '+self
.syntax
, self
.glevel
, self
.module
)
98 ret
= "%-30s - " % (self
.cmd
+' '+self
.syntax
)
100 ret
+= "(%s) " % (lib
.clevs
[self
.clevel
])
101 ret
+= str(self
.shorthelp
)
104 def _mkhelp(level
, func
):
106 if level
>= func
.reqglevel
:
107 lines
.append(HelpLine(func
.cmd
[0], func
.syntax
, func
.shorthelp
, (level
> 0), func
.reqglevel
, func
.module
, func
.reqclevel
))
108 if len(func
.cmd
) > 1:
109 for c
in func
.cmd
[1:]:
110 lines
.append(HelpLine(c
, "", "Alias of %s" % (func
.cmd
[0]), (level
> 0), func
.reqglevel
, func
.module
, func
.reqclevel
))
113 def _genhelp(bot
, user
, chan
, realtarget
, *args
):
117 filepath
= bot
.parent
.cfg
.get('help', 'path', default
='./help/%(@)s%(#)d.txt')
119 if arg
.startswith("@"):
121 raise Exception('Module option must not contain "."')
123 elif arg
.startswith("#") and user
.glevel
>= lib
.ADMIN
:
124 minlevel
= maxlevel
= int(arg
[1:])
125 elif arg
.startswith("+"):
126 maxlevel
= int(arg
[1:])
127 elif arg
.startswith("-"):
128 minlevel
= int(arg
[1:])
129 elif arg
.startswith("./"):
131 raise Exception('Filename option must not contain "./" except as the first two characters')
133 filepath
= os
.path
.join('help', arg
[2:])
135 raise Exception('Unknown option given to GENHELP: %s' % (arg
))
136 for level
in range(minlevel
, maxlevel
+1):
137 filename
= filepath
% {'#': level, '+': maxlevel, '-': minlevel, '@': module}
138 fo
= open(filename
, 'w')
140 for func
in helps
.values():
141 if module
!= '' and func
.module
!= module
:
143 lines
+= _mkhelp(level
, func
)
144 for line
in sorted(lines
):
145 fo
.write(str(line
)+"\n")
149 @lib.hook(glevel
=1, needchan
=False)
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")
151 def genhelp(bot
, user
, chan
, realtarget
, *args
):
153 _genhelp(bot
, user
, chan
, realtarget
, *args
)
154 except Exception as e
:
155 bot
.msg(user
, "Failed writing help. %s" % (e
))
157 bot
.msg(user
, "Help written.")
159 # This is hooked in modstart
160 #@lib.hook(needchan=False)
161 #@lib.help("<command>", "describes a command")
162 def help(bot
, user
, chan
, realtarget
, *args
):
164 bot
.msg(user
, "Usage: %sHELP <command>" % bot
.parent
.trigger
)
165 return showcommands(bot
, user
, chan
, realtarget
, *args
)
167 cmd
= str(' '.join(args
)).lower()
168 if cmd
in cmds
and user
.glevel
>= cmds
[cmd
].reqglevel
:
170 bot
.slowmsg(user
, str(HelpLine(func
.cmd
[0], func
.syntax
, func
.shorthelp
, (user
.glevel
> 0), func
.reqglevel
, func
.module
, func
.reqclevel
)))
171 for line
in func
.longhelps
:
172 bot
.slowmsg(user
, " %s" % (line
))
173 if len(func
.cmd
) > 1:
174 bot
.slowmsg(user
, " Aliases: %s" % (' '.join(func
.cmd
[1:])))
176 bot
.slowmsg(user
, "No help found for %s" % (cmd
))
178 @lib.hook(needchan
=False)
179 @lib.help(None, "provides command list")
180 def showcommands(bot
, user
, chan
, realtarget
, *args
):
181 if bot
.parent
.cfg
.getboolean('erebus', 'nofakelag'):
182 return help_nolag(bot
, user
, chan
, realtarget
, *args
)
183 if bot
.parent
.cfg
.getboolean('help', 'autogen'):
185 _genhelp(bot
, user
, chan
, realtarget
, *args
)
188 url
= bot
.parent
.cfg
.get('help', 'url', default
=None)
190 url
= url
% (user
.glevel
)
191 bot
.msg(user
, "Command list is at: %s" % (url
))
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 = .")
195 # This is hooked in modstart
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
):
199 if len(args
) == 0: # list commands
201 for func
in helps
.values():
202 lines
+= _mkhelp(user
.glevel
, func
)
203 for line
in sorted(lines
):
204 bot
.slowmsg(user
, str(line
))
205 bot
.slowmsg(user
, "End of command listing.")
206 elif args
[0].startswith("@"):
208 mod
= args
[0][1:].lower()
209 for func
in helps
.values():
210 if func
.module
== mod
:
211 lines
+= _mkhelp(user
.glevel
, func
)
212 for line
in sorted(lines
):
213 bot
.slowmsg(user
, str(line
))
214 bot
.slowmsg(user
, "End of command listing.")
215 else: # help for a specific command/topic
216 cmd
= str(' '.join(args
)).lower()
217 if cmd
in cmds
and user
.glevel
>= cmds
[cmd
].reqglevel
:
219 bot
.slowmsg(user
, str(HelpLine(func
.cmd
[0], func
.syntax
, func
.shorthelp
, (user
.glevel
> 0), func
.reqglevel
, func
.module
, func
.reqclevel
)))
220 for line
in func
.longhelps
:
221 bot
.slowmsg(user
, " %s" % (line
))
222 bot
.slowmsg(user
, "End of help for %s." % (func
.cmd
[0]))
224 if len(func
.cmd
) > 1:
225 bot
.slowmsg(user
, " Aliases: %s" % (' '.join(func
.cmd
[1:])))
227 bot
.slowmsg(user
, "No help found for %s" % (cmd
))