--- a/irc.py Thu Mar 20 18:47:58 2008 +0200
+++ b/irc.py Thu Mar 20 19:46:04 2008 +0200
@@ -1,6 +1,7 @@
from twisted.words.protocols import irc
from twisted.internet import protocol
from twisted.python import log
+import traceback
import buffer
@@ -10,6 +11,10 @@
USERNAME = "fixme"
CHANNEL = "#fixme-test"
+class ReplyException (Exception) :
+ def __init__ (self, reply) :
+ self.reply = reply
+
class BotProtocol (irc.IRCClient, object) :
"""
Fixme IRC bot
@@ -23,6 +28,8 @@
def connectionMade (self) :
log.msg("Connected")
super(BotProtocol, self).connectionMade()
+
+ self.nexus = self.factory.nexus
def connectionLost (self, reason) :
log.msg("Connection lost: %s" % reason)
@@ -57,5 +64,76 @@
def moduleDisconnected (self, module, reason) :
self.send("{modules.%s} disconnected: %s" % (module.name, reason))
+
+ class _noDefault : pass
+ def _lookupCommand (self, command, default=_noDefault) :
+ if '.' in command :
+ raise ReplyException("No support for module commands yet :P")
+ else :
+ method = getattr(self, "cmd_%s" % command, None)
+ if method :
+ return method
+ elif default is self._noDefault :
+ raise ReplyException("No such command '%s'. See `help commands'" % command)
+ else :
+ return default
+
+ def privmsg (self, user, channel, message) :
+ if message.lower().startswith(self.nickname.lower()) :
+ me, command = message.split(":", 1)
+
+ args = command.strip().split()
+ command = args.pop(0)
+
+ try :
+ method = self._lookupCommand(command)
+
+ reply = method(*args)
+
+ if reply :
+ self.send(reply)
+
+ except ReplyException, e :
+ self.send(e.reply)
+
+ except Exception, e :
+ self.send("Error: %s: %s" % (e.__class__.__name__, e))
+ traceback.print_exc()
+
+ def cmd_help (self, cmd="help") :
+ """help <command|module> - Display help about the given command or module"""
+
+ method = self._lookupCommand(cmd, None)
+
+ if method :
+ return method.__doc__
+ else :
+ try :
+ module, addr = self.nexus.getModuleInfo(cmd)
+
+ return "%s is version %d from %s:%d. Events: %s. See `commands %s' for a list of commands" % (module.name, module.version, addr.host, addr.port, ', '.join(module.event_types), module.name)
+
+ except KeyError :
+ raise ReplyException("No command/module called `%s'. See `help commands'" % cmd)
+
+ def cmd_commands (self, module=None) :
+ """commands [<module>] - Show primary commands, or commands in the given module (see `help modules')"""
+
+ if module :
+ raise ReplyException("No support for module commands yet :P")
+ else :
+ return "Commands: %s" % ', '.join(
+ attr_name.split('_', 1)[1]
+ for attr_name in BotProtocol.__dict__.iterkeys()
+ if attr_name.startswith("cmd_")
+ )
+
+ def cmd_modules (self) :
+ """modules - Show a list of connected modules"""
+
+ return "Modules: %s" % ', '.join(
+ module.name
+ for module in self.nexus.getModules()
+ )