]> jfr.im git - erebus.git/blobdiff - modules/help.py
help - dont allow args to SHOWCOMMANDS
[erebus.git] / modules / help.py
index fc0dfe5392fbbc9de9f6c868233ec1747e8a5e91..252353656713c8268d7c64788c26dc8c2602dfbc 100644 (file)
@@ -1,4 +1,5 @@
 # Erebus IRC bot - Author: Erebus Team
+# vim: fileencoding=utf-8
 # help module
 # This file is released into the public domain; see http://unlicense.org/
 
@@ -18,11 +19,12 @@ def modstart(parent, *args, **kwargs):
        if parent.cfg.getboolean('erebus', 'nofakelag'):
                lib.hook('help', needchan=False)(lib.help('[@<module>|<command>]', 'lists commands or describes a command', 'with @<module>, lists all commands in <module>')(help_nolag))
        else:
-               lib.hook(needchan=False)(lib.help("<command>", "describes a command")(help))
+               lib.hook('help', needchan=False)(lib.help("<command>", "describes a command", "see also: showcommands")(help))
        return lib.modstart(parent, *args, **kwargs)
 modstop = lib.modstop
 
 # module code
+import functools
 import os.path
 helps = {}
 cmds  = {}
@@ -62,6 +64,7 @@ def dereghelp(func, *args, **kwargs):
                del cmds[c]
        del helps[func]
 
+@functools.total_ordering
 class HelpLine(object):
        def __init__(self, cmd, syntax, shorthelp, admin, glevel, module, clevel):
                self.cmd = cmd
@@ -72,6 +75,15 @@ class HelpLine(object):
                self.module = module
                self.clevel = clevel
 
+       def __lt__(self, other):
+               if self.glevel == other.glevel:
+                       return self.cmd < other.cmd
+               else:
+                       return self.glevel < other.glevel
+
+       def __eq__(self, other):
+               return self.glevel == other.glevel and self.cmd == other.cmd
+
        def __cmp__(self, other):
                if self.glevel == other.glevel:
                        return cmp(self.cmd, other.cmd)
@@ -99,28 +111,34 @@ def _mkhelp(level, func):
        return lines
 
 def _genhelp(bot, user, chan, realtarget, *args):
-       module = None
+       module = ''
        minlevel = -1
        maxlevel = 100
-       filepath = bot.parent.cfg.get('help', 'path', default='./help/%d.txt')
+       filepath = bot.parent.cfg.get('help', 'path', default='./help/%(@)s%(#)d.txt')
        for arg in args:
                if arg.startswith("@"):
+                       if "." in arg[1:]:
+                               raise Exception('Module option must not contain "."')
                        module = arg[1:]
                elif arg.startswith("#") and user.glevel >= lib.ADMIN:
                        minlevel = maxlevel = int(arg[1:])
+               elif arg.startswith("+"):
+                       maxlevel = int(arg[1:])
+               elif arg.startswith("-"):
+                       minlevel = int(arg[1:])
+               elif arg.startswith("./"):
+                       if "./" in arg[1:]:
+                               raise Exception('Filename option must not contain "./" except as the first two characters')
+                       else:
+                               filepath = os.path.join('help', arg[2:])
                else:
-                       filepath = arg
-                       if minlevel != maxlevel:
-                               minlevel = maxlevel
+                       raise Exception('Unknown option given to GENHELP: %s' % (arg))
        for level in range(minlevel, maxlevel+1):
-               if '%d' in filepath:
-                       filename = filepath % (level)
-               else:
-                       filename = filepath
+               filename = filepath % {'#': level, '+': maxlevel, '-': minlevel, '@': module}
                fo = open(filename, 'w')
                lines = []
                for func in helps.values():
-                       if module is not None and func.module != module:
+                       if module != '' and func.module != module:
                                        continue
                        lines += _mkhelp(level, func)
                for line in sorted(lines):
@@ -129,7 +147,7 @@ def _genhelp(bot, user, chan, realtarget, *args):
        return True
 
 @lib.hook(glevel=1, needchan=False)
-@lib.help("[@<module>] [#<level>] [file]", "generates help file", "arguments are all optional and may be specified in any order", "default file: ./help/<level>.txt", "config as: [help]", "path = ./help/%d.txt")
+@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")
 def genhelp(bot, user, chan, realtarget, *args):
        try:
                _genhelp(bot, user, chan, realtarget, *args)
@@ -138,10 +156,14 @@ def genhelp(bot, user, chan, realtarget, *args):
                return
        bot.msg(user, "Help written.")
 
+# This is hooked in modstart
 #@lib.hook(needchan=False)
 #@lib.help("<command>", "describes a command")
-@lib.argsGE(1)
 def help(bot, user, chan, realtarget, *args):
+       if len(args) == 0:
+               bot.msg(user, "Usage: %sHELP <command>" % bot.parent.trigger)
+               return showcommands(bot, user, chan, realtarget, *args)
+
        cmd = str(' '.join(args)).lower()
        if cmd in cmds and user.glevel >= cmds[cmd].reqglevel:
                func = cmds[cmd]
@@ -155,32 +177,30 @@ def help(bot, user, chan, realtarget, *args):
 
 @lib.hook(needchan=False)
 @lib.help(None, "provides command list")
+@lib.argsEQ(0)
 def showcommands(bot, user, chan, realtarget, *args):
+       if bot.parent.cfg.getboolean('erebus', 'nofakelag'):
+               return help_nolag(bot, user, chan, realtarget, *args)
        if bot.parent.cfg.getboolean('help', 'autogen'):
                try:
-                       _genhelp(bot, user, chan, realtarget, *args)
+                       _genhelp(bot, user, chan, realtarget)
                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))
+               bot.msg(user, "Command list is at: %s" % (url))
        else:
-               bot.msg(user, "I don't know where help is. Sorry. Contact my owner.")
+               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 = .")
 
+# This is hooked in modstart
 #@lib.hook(needchan=False)
 #@lib.help('[@<module>|<command>]', 'lists commands or describes a command', 'with @<module>, lists all commands in <module>')
 def help_nolag(bot, user, chan, realtarget, *args):
        if len(args) == 0: # list commands
                lines = []
                for func in helps.values():
-                       lines += _mkhelp(user, func)
+                       lines += _mkhelp(user.glevel, func)
                for line in sorted(lines):
                        bot.slowmsg(user, str(line))
                bot.slowmsg(user, "End of command listing.")
@@ -189,7 +209,7 @@ def help_nolag(bot, user, chan, realtarget, *args):
                mod = args[0][1:].lower()
                for func in helps.values():
                        if func.module == mod:
-                               lines += _mkhelp(user, func)
+                               lines += _mkhelp(user.glevel, func)
                for line in sorted(lines):
                        bot.slowmsg(user, str(line))
                bot.slowmsg(user, "End of command listing.")