diff --git a/Module.py b/Module.py index 4c3cdda..e761e9b 100644 --- a/Module.py +++ b/Module.py @@ -154,5 +154,23 @@ class Module(object): print("looks like someone forgot to implement do!") + def help_description(self): + """Return a quick list of commands or other summary, should be + less than two lines. If you want the module hidden from "!help", + return None here""" + return "No description available" + + def help_summary(self): + """Return a command summary or longer description of this module. + If this returns None, the summary will be + "no help available for module foo" + """ + return None + + def help_detail(self, command): + """Return detailed help for the given command. Return None if there + is no suitable help available""" + return None + # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on; diff --git a/modules/Help.py b/modules/Help.py new file mode 100755 index 0000000..e113cb4 --- /dev/null +++ b/modules/Help.py @@ -0,0 +1,122 @@ +""" +Help - handle !help commands by interrogating modules for help text +Copyright (C) 2011 Mike Bloy + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" + +import re +import sqlite3 + +from Module import Module + +__author__ = "Mike Bloy " +__date__ = "2011-01-08" + +class Help(Module): + + def __init__(self, irc, config, server): + """ + Upon creation, determine the save file location + """ + + Module.__init__(self, irc, config, server) + + self.helpre = re.compile('^!help(\s+(\S+)(\s+(.+))?)?\s*$') + + def do(self, connection, event, nick, userhost, what, admin_unlocked): + """look for !help and subcommands, + and dispatch for further processing""" + + match = self.helpre.search(what) + if match: + (module, key) = match.group(2,4) + if (module == None): + return self.handle_help_descriptions() + elif (key == None): + return self.handle_help_module(module) + else: + return self.handle_help_detail(module, key) + + def handle_help_descriptions(self): + """print the general help""" + message = "General Help:\n" + for module in self.irc.modlist: + description = module.help_description() + if description: + message += " %s - %s\n" % (module.__class__.__name__, + description) + return message + + def handle_help_module(self, modname): + """handle the module level help processing""" + module = self.find_module(modname) + if module: + helptext = module.help_summary() + if helptext: + return "%s - %s" % (modname, helptext) + else: + return "no help available for module %s" % (modname) + else: + return "no module named '%s' is loaded" % (modname) + + def handle_help_detail(self, modname, key): + """handle the help detail message""" + module = self.find_module(modname) + if module: + helptext = module.help_detail(key) + if helptext: + return "%s (%s) - %s" % (modname, key, helptext) + else: + return "no help available for module '%s', command '%s'" % (modname, key) + else: + return "no module named '%s' is loaded" % (modname) + + return "asked for help on module %s detail %s" % (modname, key) + + def find_module(self, modname): + """find a module in the server's list of loaded modules""" + for module in self.irc.modlist: + if modname == module.__class__.__name__: + return module + return None + + def help_description(self): + """Return a quick list of commands or other summary, should be + less than two lines. If you want the module hidden from "!help", + return None here""" + return "Display module and command help" + + def help_summary(self): + """Return a command summary or longer description of this module. + If this returns None, the summary will be + "no help available for module foo" + """ + return """!help [module [detail]] +type '!help Help module' or '!help Help detail' for more information""" + + def help_detail(self, command): + """Return detailed help for the given command. Return None if there + is no suitable help available""" + if command == 'module': + return """get a summary of a module's commands or function""" + elif command == 'detail': + return """get information on a specific module-defined detail""" + else: + return None + +if __name__ == "__main__": + print "Hello World" + +# vi:tabstop=4:expandtab:autoindent diff --git a/modules/IrcAdmin.py b/modules/IrcAdmin.py index f8279c8..3685faa 100644 --- a/modules/IrcAdmin.py +++ b/modules/IrcAdmin.py @@ -166,5 +166,51 @@ class IrcAdmin(Module): return ', '.join(self.irc.list_modules()) + def help_description(self): + """Return a quick list of commands or other summary, should be + less than two lines. If you want the module hidden from "!help", + return None here""" + return "Perform admin-related functions." + + def help_summary(self): + """Return a command summary or longer description of this module. + If this returns None, the summary will be + "no help available for module foo" + """ + return """Bot admin commands (do '!help IrcAdmin [cmd] for details): +!join, !part, !quit, !autojoin, !save, !nick, !load, !reload, !unload, !modules""" + + def help_detail(self, command): + """Return detailed help for the given command. Return None if there + is no suitable help available""" + key = command.strip() + if key[0] == '!': + key = key[1:] + words = key.split() + if len(words) == 0: + return None + elif words[0] == 'join': + return "!join [channel] - cause the bot to /join [channel]" + elif words[0] == 'part': + return "!part [channel] - cause the bot to /part from [channel]" + elif words[0] == 'quit': + return "!quit - cause the bot to save itself and quit" + elif words[0] == 'autojoin': + return "!autojoin [channel] - cause the bot to join [channel] on startup" + elif words[0] == 'save': + return "!save - cause the bot to save config data to the config file" + elif words[0] == 'nick': + return "!nick - cause the bot to change its nick" + elif words[0] == 'load': + return "!load - make the bot load a module dynamically" + elif words[0] == 'reload': + return "!reload - reload an already-loaded module" + elif words[0] == 'unload': + return "!unload - unload a loaded module, removing its functionality" + elif words[0] == 'modules': + return "!modules - list the currently loaded modules" + else: + return None + # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on; diff --git a/modules/Karma.py b/modules/Karma.py index 98269a7..07a85c7 100644 --- a/modules/Karma.py +++ b/modules/Karma.py @@ -18,6 +18,7 @@ along with this program. If not, see . import re import sqlite3 +import string from Module import Module @@ -228,6 +229,43 @@ class Karma(Module): return reply + def help_description(self): + """Return a quick list of commands or other summary, should be + less than two lines. If you want the module hidden from "!help", + return None here""" + return "record karma and report on recorded karma" + + def help_summary(self): + """Return a command summary or longer description of this module. + If this returns None, the summary will be + "no help available for module foo" + """ + return """Watches channels for words (or parenthesized phrases) followed by one of ++, --, +-, or -+, and records an increment, decrement, or combination of karma for the word or phrase, as well as the identity of the karma giver. Supports the following commands: + !rank [item] - get the current karma value for item + !karma stat [nick] - report on the karma-giving statistics of nick + !karma report (highest|lowest) - report on the highest or lowest karma recipients + !karma report (positive|negative) - report on the biggest optimists or pessimists""" + + def help_detail(self, command): + """Return detailed help for the given command. Return None if there + is no suitable help available""" + key = command.strip() + if key[0] == '!': + key = key[1:] + words = key.split() + if len(words) == 0: + return None + elif words[0] == 'rank': + return "!rank [item] - get the current karma value and rank of [item]" + elif words[0] == 'karma': + return """!karma stat [nick] - report on the positive, negative, and total karma given by [nick] +!karma report highest - report on the top 5 karma recipients +!karma report lowest - report on the bottom 5 karma recipients +!karma report positive - report on the 5 most positive karma givers +!karma report negative - report on the 5 most negative karma givers""" + else: + return None + if __name__ == "__main__": print "Hello World"