X-Git-Url: https://jfr.im/git/erebus.git/blobdiff_plain/58401d098f1e48416cf01b87b31e6ab2c9725f57..fa93b93394adc45f4b3bd1694c960df127cfc4da:/modules/help.py diff --git a/modules/help.py b/modules/help.py index ff64cf0..dc4e1b2 100644 --- a/modules/help.py +++ b/modules/help.py @@ -6,22 +6,28 @@ modinfo = { 'author': 'Erebus Team', 'license': 'public domain', - 'compatible': [1], # compatible module API versions - 'depends': [], # other modules required to work properly? + 'compatible': [0], + 'depends': [], + 'softdeps': [], } # preamble import modlib lib = modlib.modlib(__name__) -modstart = lib.modstart +def modstart(parent, *args, **kwargs): + if parent.cfg.getboolean('erebus', 'nofakelag'): + lib.hook('help', needchan=False)(lib.help('[@|]', 'lists commands or describes a command', 'with @, lists all commands in ')(help_nolag)) + else: + lib.hook(needchan=False)(lib.help("", "describes a command")(help)) + return lib.modstart(parent, *args, **kwargs) modstop = lib.modstop # module code +import os.path helps = {} cmds = {} # ! this is part of this module's API, called from modlib.help() -# this function only handles the command name and aliases - the rest is passed directly to _reghelp() def reghelp(func, *args, **kwargs): syntax = None shorthelp = None @@ -53,54 +59,148 @@ def reghelp(func, *args, **kwargs): def dereghelp(func, *args, **kwargs): for c in func.cmd: - del cmds[cmd] + del cmds[c] del helps[func] class HelpLine(object): - def __init__(self, cmd, syntax, shorthelp, admin, level, module): + def __init__(self, cmd, syntax, shorthelp, admin, glevel, module, clevel): self.cmd = cmd self.syntax = syntax self.shorthelp = shorthelp self.admin = admin - self.level = level + self.glevel = glevel self.module = module + self.clevel = clevel def __cmp__(self, other): - if self.level == other.level: + if self.glevel == other.glevel: return cmp(self.cmd, other.cmd) else: - return cmp(self.level, other.level) + return cmp(self.glevel, other.glevel) def __str__(self): if self.admin: - return "%-35s(%3s) - %-10s - %-50s" % (self.cmd+' '+self.syntax, self.level, self.module, self.shorthelp) + ret = "%-25s(%3s) - %-10s - " % (self.cmd+' '+self.syntax, self.glevel, self.module) else: - return "%-40s - %-50s" % (self.cmd+' '+self.syntax, self.shorthelp) + ret = "%-30s - " % (self.cmd+' '+self.syntax) + if self.clevel != 0: + ret += "(%s) " % (lib.clevs[self.clevel]) + ret += str(self.shorthelp) + return ret + +def _mkhelp(level, func): + lines = [] + if level >= func.reqglevel: + lines.append(HelpLine(func.cmd[0], func.syntax, func.shorthelp, (level > 0), func.reqglevel, func.module, func.reqclevel)) + if len(func.cmd) > 1: + for c in func.cmd[1:]: + lines.append(HelpLine(c, "", "Alias of %s" % (func.cmd[0]), (level > 0), func.reqglevel, func.module, func.reqclevel)) + return lines + +def _genhelp(bot, user, chan, realtarget, *args): + module = None + minlevel = -1 + maxlevel = 100 + filepath = bot.parent.cfg.get('help', 'path', default='./help/%d.txt') + for arg in args: + if arg.startswith("@"): + module = arg[1:] + elif arg.startswith("#") and user.glevel >= lib.ADMIN: + minlevel = maxlevel = int(arg[1:]) + else: + filepath = arg + if minlevel != maxlevel: + minlevel = maxlevel + for level in range(minlevel, maxlevel+1): + if '%d' in filepath: + filename = filepath % (level) + else: + filename = filepath + fo = open(filename, 'w') + lines = [] + for func in helps.itervalues(): + if module is not None and func.module != module: + continue + lines += _mkhelp(level, func) + for line in sorted(lines): + fo.write(str(line)+"\n") + fo.close() + return True + +@lib.hook(glevel=1, needchan=False) +@lib.help("[@] [#] [file]", "generates help file", "arguments are all optional and may be specified in any order", "default file: ./help/.txt", "config as: [help]", "path = ./help/%d.txt") +def genhelp(bot, user, chan, realtarget, *args): + try: + _genhelp(bot, user, chan, realtarget, *args) + except Exception as e: + bot.msg(user, "Failed writing help. %s" % (e)) + return + bot.msg(user, "Help written.") + +#@lib.hook(needchan=False) +#@lib.help("", "describes a command") +@lib.argsGE(1) +def help(bot, user, chan, realtarget, *args): + cmd = str(' '.join(args)).lower() + if cmd in cmds and user.glevel >= cmds[cmd].reqglevel: + func = cmds[cmd] + bot.slowmsg(user, str(HelpLine(func.cmd[0], func.syntax, func.shorthelp, (user.glevel > 0), func.reqglevel, func.module, func.reqclevel))) + for line in func.longhelps: + bot.slowmsg(user, " %s" % (line)) + if len(func.cmd) > 1: + bot.slowmsg(user, " Aliases: %s" % (' '.join(func.cmd[1:]))) + else: + bot.slowmsg(user, "No help found for %s" % (cmd)) @lib.hook(needchan=False) -@lib.help('[]', 'lists commands or describes a command') -def help(bot, user, chan, realtarget, *args): #TODO add ordering - by access level, then alphabetic? +@lib.help(None, "provides command list") +def showcommands(bot, user, chan, realtarget, *args): + if bot.parent.cfg.getboolean('help', 'autogen'): + try: + _genhelp(bot, user, chan, realtarget, *args) + except: pass + + url = bot.parent.cfg.get('help', 'url', default=None) + if url is None: + try: + import urllib2 + myip = urllib2.urlopen("https://api.ipify.org").read() + url = "http://%s/help/%%d.txt (maybe)" % (myip) + except: url = None + if url is not None: + url = url % (user.glevel) + bot.msg(user, "Help is at: %s" % (url)) + else: + bot.msg(user, "I don't know where help is. Sorry. Contact my owner.") + +#@lib.hook(needchan=False) +#@lib.help('[@|]', 'lists commands or describes a command', 'with @, lists all commands in ') +def help_nolag(bot, user, chan, realtarget, *args): if len(args) == 0: # list commands lines = [] for func in helps.itervalues(): - if user.glevel >= func.reqglevel: - lines.append(HelpLine(func.cmd[0], func.syntax, func.shorthelp, (user.glevel > 0), func.reqglevel, func.__module__)) - if len(func.cmd) > 1: - for c in func.cmd[1:]: - lines.append(HelpLine(c, "", "Alias of %s" % (func.cmd[0]), (user.glevel > 0), func.reqglevel, func.__module__)) + lines += _mkhelp(user, func) + for line in sorted(lines): + bot.slowmsg(user, str(line)) + bot.slowmsg(user, "End of command listing.") + elif args[0].startswith("@"): + lines = [] + mod = args[0][1:].lower() + for func in helps.itervalues(): + if func.module == mod: + lines += _mkhelp(user, func) for line in sorted(lines): bot.slowmsg(user, str(line)) + bot.slowmsg(user, "End of command listing.") else: # help for a specific command/topic - cmd = str(' '.join(args)) + cmd = str(' '.join(args)).lower() if cmd in cmds and user.glevel >= cmds[cmd].reqglevel: func = cmds[cmd] - if func.reqglevel <= 0: - bot.slowmsg(user, "%-40s - %-50s" % (func.cmd[0]+' '+func.syntax, func.shorthelp)) - else: - bot.slowmsg(user, "%-40s - %-50s (%5s)" % (func.cmd[0]+' '+func.syntax, func.shorthelp, func.reqglevel)) + bot.slowmsg(user, str(HelpLine(func.cmd[0], func.syntax, func.shorthelp, (user.glevel > 0), func.reqglevel, func.module))) for line in func.longhelps: bot.slowmsg(user, " %s" % (line)) + bot.slowmsg(user, "End of help for %s." % (func.cmd[0])) if len(func.cmd) > 1: bot.slowmsg(user, " Aliases: %s" % (' '.join(func.cmd[1:])))