From d34a134993dce0870cc3f1220a7aa6fd0eeb5318 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 8 Jan 2011 13:39:38 -0600 Subject: [PATCH 1/7] add help functions to Module.py --- Module.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Module.py b/Module.py index 4c3cdda..e5a205c 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 None + + 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; From 763f8906d7352d49f4bbad89418aee51699f53c5 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 8 Jan 2011 21:52:59 -0600 Subject: [PATCH 2/7] Help module responds to commands Responding to !help !help module !help module [detail...] form --- modules/Help.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 modules/Help.py diff --git a/modules/Help.py b/modules/Help.py new file mode 100755 index 0000000..dd9c78f --- /dev/null +++ b/modules/Help.py @@ -0,0 +1,63 @@ +""" +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 karma strings at the start of messages""" + + match = self.helpre.search(what) + if (match): + (module, key) = match.group(2,4) + if (module == None): + return self.help_descriptions() + elif (key == None): + return self.help_module(module) + else: + return self.help_detail(module, key) + + def help_descriptions(self): + return "asked for general help" + + def help_module(self, module): + return "asked for help on module %s" % (module) + + def help_detail(self, module, key): + return "asked for help on module %s detail %s" % (module, key) + +if __name__ == "__main__": + print "Hello World" + +# vi:tabstop=4:expandtab:autoindent From 87088e67d19737422b432bd0b8e702cd04c2970f Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 8 Jan 2011 22:32:18 -0600 Subject: [PATCH 3/7] attempt to ask the modules for help text --- modules/Help.py | 50 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/modules/Help.py b/modules/Help.py index dd9c78f..d97d50d 100755 --- a/modules/Help.py +++ b/modules/Help.py @@ -39,23 +39,53 @@ class Help(Module): """look for karma strings at the start of messages""" match = self.helpre.search(what) - if (match): + if match: (module, key) = match.group(2,4) if (module == None): - return self.help_descriptions() + return self.handle_help_descriptions() elif (key == None): - return self.help_module(module) + return self.handle_help_module(module) else: - return self.help_detail(module, key) + return self.handle_help_detail(module, key) - def help_descriptions(self): - return "asked for general help" + def handle_help_descriptions(self): + 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 help_module(self, module): - return "asked for help on module %s" % (module) + def handle_help_module(self, modname): + 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 help_detail(self, module, key): - return "asked for help on module %s detail %s" % (module, key) + def handle_help_detail(self, modname, key): + 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): + for module in self.irc.modlist: + if modname == module.__class__.__name__: + return module + return None if __name__ == "__main__": print "Hello World" From fdd059ddbcbe950c261f1287f29a85010503c1b3 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 8 Jan 2011 22:32:55 -0600 Subject: [PATCH 4/7] change default module description Modules by default were returning None from help_description(), which meant that they would not display in !help Instead, return a generic not-available message. If a module really doesn't want to display in !help, override and return None --- Module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Module.py b/Module.py index e5a205c..e761e9b 100644 --- a/Module.py +++ b/Module.py @@ -158,7 +158,7 @@ class Module(object): """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 None + return "No description available" def help_summary(self): """Return a command summary or longer description of this module. From 07d37758427ab444afc92b910572a60ef14fcd49 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 8 Jan 2011 22:47:51 -0600 Subject: [PATCH 5/7] added help text to the Help module --- modules/Help.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/modules/Help.py b/modules/Help.py index d97d50d..e113cb4 100755 --- a/modules/Help.py +++ b/modules/Help.py @@ -36,7 +36,8 @@ class Help(Module): self.helpre = re.compile('^!help(\s+(\S+)(\s+(.+))?)?\s*$') def do(self, connection, event, nick, userhost, what, admin_unlocked): - """look for karma strings at the start of messages""" + """look for !help and subcommands, + and dispatch for further processing""" match = self.helpre.search(what) if match: @@ -49,6 +50,7 @@ class Help(Module): 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() @@ -58,6 +60,7 @@ class Help(Module): 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() @@ -69,6 +72,7 @@ class Help(Module): 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) @@ -82,11 +86,36 @@ class Help(Module): 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" From d68487de9529fc83f8afa586fb1e14ac5d8981bd Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 8 Jan 2011 23:21:36 -0600 Subject: [PATCH 6/7] added help for Karma module --- modules/Karma.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) 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" From 66a736b1084dee0b48d8de706e5b3e4f60de5fe9 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 8 Jan 2011 23:41:41 -0600 Subject: [PATCH 7/7] added help for the IrcAdmin module --- modules/IrcAdmin.py | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) 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;