diff --git a/Module.py b/Module.py
index f26b84a..4316b8b 100644
--- a/Module.py
+++ b/Module.py
@@ -1,18 +1,20 @@
-# Module - dr.botzo modular functionality base class
-# Copyright (C) 2010 Brian S. Stephan
-#
-# 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 .
+"""
+Module - dr.botzo modular functionality base class
+Copyright (C) 2010 Brian S. Stephan
+
+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 inspect
import re
@@ -20,20 +22,21 @@ import sys
from irclib import irclib
-# Base class used for creating classes that have real functionality.
-
class Module(object):
-
- # Constructor for a feature module. Inheritors should not do anything special
- # here, instead they should implement register_handlers and do, or else this will
- # be a very uneventful affair.
- #
- # Classes that are interested in allowing an indirect call to their do routine
- # should add themselves to modlist inside their __init__. This will allow other
- # modules to call do and see if anything can handle text they may have seen (such
- # as in recursive commands).
+ """Declare a base class used for creating classes that have real functionality."""
def __init__(self, config, server, modlist):
+ """
+ Construct a feature module. Inheritors should not do anything special
+ here, instead they should implement register_handlers and do, or else this will
+ be a very uneventful affair.
+
+ Classes that are interested in allowing an indirect call to their do routine
+ should add themselves to modlist inside their __init__. This will allow other
+ modules to call do and see if anything can handle text they may have seen (such
+ as in recursive commands).
+ """
+
self.config = config
self.server = server
self.modlist = modlist
@@ -45,32 +48,41 @@ class Module(object):
# print what was loaded, for debugging
print("loaded " + self.__class__.__name__)
- # This is called by __init__ and sets up server.add_global_handlers. Classes
- # inheriting from Module should implement this and set up the appropriate handlers,
- # e.g.:
- #
- # server.add_global_handler('privmsg', self.on_privmsg)
- #
- # Module.on_pubmsg and Module.on_privmsg are defined so far, the rest, you're on your
- # own.
-
def register_handlers(self, server):
+ """
+ Hook handler functions into the IRC library. This is called by __init__ and sets
+ up server.add_global_handlers. Classes inheriting from Module should implement this
+ and set up the appropriate handlers, e.g.:
+
+ server.add_global_handler('privmsg', self.on_privmsg)
+
+ Module.on_pubmsg and Module.on_privmsg are defined so far, the rest, you're on your
+ own.
+ """
+
print "looks like someone forgot to implement register_handlers!"
- # This is called by reload, to remove the soon-to-be old object from the server
- # global handlers (or whatever has been added via register_handlers). Classes
- # inheriting from Module should implement this, e.g.:
- #
- # server.remove_global_handler('privmsg', self.on_privmsg)
-
def unregister_handlers(self):
+ """
+ Unhook handler functions from the IRC library. Inverse of the above.
+ This is called by reload, to remove the soon-to-be old object from the server
+ global handlers (or whatever has been added via register_handlers). Classes
+ inheriting from Module should implement this, e.g.:
+
+ server.remove_global_handler('privmsg', self.on_privmsg)
+ """
+
print "looks like someone forgot to implement unregister_handlers!"
- # Does some variable setup and initial sanity checking before calling Module.do,
- # which should be implemented by subclasses and what can be ultimately responsible
- # for the work. Of course, you are free to reimplement on_pubmsg on your own too.
-
def on_pubmsg(self, connection, event):
+ """
+ Handle pubmsg events. Does some variable setup and initial sanity checking before
+ calling Module.do, which should be implemented by subclasses and what can be
+ ultimately responsible for the work.
+
+ Of course, you are free to reimplement on_pubmsg on your own too.
+ """
+
nick = irclib.nm_to_n(event.source())
userhost = irclib.nm_to_uh(event.source())
replypath = event.target()
@@ -100,11 +112,15 @@ class Module(object):
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
- # Does some variable setup and initial sanity checking before calling Module.do,
- # which should be implemented by subclasses and what can be ultimately responsible
- # for the work. Of course, you are free to reimplement on_privmsg on your own too.
-
def on_privmsg(self, connection, event):
+ """
+ Handle privmsg events. Does some variable setup and initial sanity checking before
+ calling Module.do, which should be implemented by subclasses and what can be
+ ultimately responsible for the work.
+
+ Of course, you are free to reimplement on_privmsg on your own too.
+ """
+
nick = irclib.nm_to_n(event.source())
userhost = irclib.nm_to_uh(event.source())
replypath = nick
@@ -122,9 +138,9 @@ class Module(object):
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
- # If the command given was to reload, reload this module.
-
def reload(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
+ """Reload this module's code and then create a new object of it, removing the old."""
+
whats = what.split(' ')
if whats[0] == 'reload' and admin_unlocked:
# re-read and re-compile module from source on disk
@@ -140,29 +156,35 @@ class Module(object):
# create new object, like how we did initially
obj(self.config, self.server, self.modlist)
- # Utility method to do the proper type of reply (either to IRC, or as a return
- # to caller) depending on the target. Pretty simple, and included in the base
- # class for convenience. It should be the last step for callers:
- #
- # return self.reply(connection, replypath, 'hello')
-
def reply(self, connection, replypath, replystr):
+ """
+ Reply over IRC to replypath or return a string with the reply.
+ Utility method to do the proper type of reply (either to IRC, or as a return
+ to caller) depending on the target. Pretty simple, and included in the base
+ class for convenience. It should be the last step for callers:
+
+ return self.reply(connection, replypath, 'hello')
+ """
+
if replypath is None:
return replystr
else:
connection.privmsg(replypath, replystr)
- # Upon seeing a line intended for this module, see if there are subcommands
- # that we should do what is basically a text replacement on. The intent is to
- # allow things like the following:
- #
- # command arg1 [anothercommand arg1 arg2]
- #
- # where the output of anothercommand is command's arg2..n. It's mostly for
- # amusement purposes, but maybe there are legitimate uses. This is intended to
- # be attempted after you've determined the line should be handled by your module.
-
def try_recursion(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
+ """
+ Scan message for subcommands to execute and use as part of this command.
+ Upon seeing a line intended for this module, see if there are subcommands
+ that we should do what is basically a text replacement on. The intent is to
+ allow things like the following:
+
+ command arg1 [anothercommand arg1 arg2]
+
+ where the output of anothercommand is command's arg2..n. It's mostly for
+ amusement purposes, but maybe there are legitimate uses. This is intended to
+ be attempted after you've determined the line should be handled by your module.
+ """
+
start_idx = what.find('[')
subcmd = what[start_idx+1:]
end_idx = subcmd.rfind(']')
@@ -195,10 +217,13 @@ class Module(object):
else:
return attempt
- # Implement this method in your subclass to have a fairly-automatic hook into
- # IRC functionality. This is called by the default on_pubmsg and on_privmsg
-
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
+ """
+ Do the primary thing this module was intended to do.
+ Implement this method in your subclass to have a fairly-automatic hook into
+ IRC functionality. This is called by the default on_pubmsg and on_privmsg
+ """
+
print "looks like someone forgot to implement do!"
# vi:tabstop=4:expandtab:autoindent
diff --git a/dr.botzo.py b/dr.botzo.py
index 88aa853..899187a 100644
--- a/dr.botzo.py
+++ b/dr.botzo.py
@@ -1,18 +1,20 @@
-# dr.botzo - a pluggable IRC bot written in Python
-# Copyright (C) 2010 Brian S. Stephan
-#
-# 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 .
+"""
+dr.botzo - a pluggable IRC bot written in Python
+Copyright (C) 2010 Brian S. Stephan
+
+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 .
+"""
from ConfigParser import ConfigParser, NoSectionError, NoOptionError
import os
@@ -28,13 +30,11 @@ modlist = []
moduleList = [ "Countdown", "Dice", "IrcAdmin", "GoogleTranslate", "Seen", "FactFile" ]
modObjs = []
-# DrBotServerConnection subclasses irclib's ServerConnection, in order to expand
-# privmsg.
-
class DrBotServerConnection(irclib.ServerConnection):
+ """Subclass irclib's ServerConnection, in order to expand privmsg."""
def privmsg(self, target, text):
- # Send a PRIVMSG command.
+ """Send a PRIVMSG command."""
splitter = "..."
# split messages that are too long. Max length is 512.
@@ -55,9 +55,8 @@ class DrBotServerConnection(irclib.ServerConnection):
else:
self.send_raw("PRIVMSG %s :%s" % (target, text))
-# DrBotIRC subclasses irclib's IRC, in order to create a DrBotServerConnection.
-
class DrBotIRC(irclib.IRC):
+ """Subclass irclib's IRC, in order to create a DrBotServerConnection."""
def server(self):
c = DrBotServerConnection(self)