All pastes #21010 Raw Edit

Miscellany

public text v1 · immutable
#21010 ·published 2005-08-24 18:51 UTC
rendered paste body
#!/usr/bin/python
#hacked-up twisted example bot
#command is $mathb0t #math foo
#or something
#at least it runs
#by default it uses sc


from twisted.protocols import irc
from twisted.internet import reactor, protocol

import time,sys,re,string,commands,sc
from numarray import *

class MessageLogger:
    """
    An independant logger class (because separation of application
    and protocol logic is a good thing).
    """
    def __init__(self, file):
        self.file = file

    def log(self, message):
        """Write a message to the file."""
        timestamp = time.strftime("[%H:%M:%S]", time.localtime(time.time()))
        self.file.write('%s %s\n' % (timestamp, message))
        self.file.flush()

    def close(self):
        self.file.close()


class LogBot(irc.IRCClient):
    """A logging IRC bot."""
    
    def __init__(self):
        self.nickname = "mathb0t"

    def connectionMade(self):
        irc.IRCClient.connectionMade(self)
        self.logger = MessageLogger(open(self.factory.filename, "a"))
        self.logger.log("[connected at %s]" % 
                        time.asctime(time.localtime(time.time())))

    def connectionLost(self, reason):
        irc.IRCClient.connectionLost(self, reason)
        self.logger.log("[disconnected at %s]" % 
                        time.asctime(time.localtime(time.time())))
        self.logger.close()


    # callbacks for events

    def signedOn(self):
        """Called when bot has succesfully signed on to server."""
        self.join(self.factory.channel)

    def joined(self, channel):
        """This will get called when the bot joins the channel."""
        self.logger.log("[I have joined %s]" % channel)

    def privmsg(self, user, channel, msg): # not an irc privmsg
        """This will get called when the bot receives a message."""
        user = user.split('!', 1)[0]
        if re.search('mathematica', msg) and re.search('mathb0t', msg):
            self.say(channel, 'mathematica sucks')
            return
        if re.search('Mathematica', msg) and re.search('mathb0t', msg):
            self.say(channel, 'mathematica sucks')
            return
        if msg.startswith("%s:" % self.nickname):
            command = msg.split(':', 1)[1]
            try:
                outmsg = str(sc.sc(command))
                self.say(channel, outmsg)
            except:
                self.say(channel, "I am not programmed to respond in that area.")
                print user+" says "+msg

    def action(self, user, channel, msg):
        """This will get called when the bot sees someone do an action."""
        user = user.split('!', 1)[0]
        self.logger.log("* %s %s" % (user, msg))
        if user=='marcusU' and string.strip(msg)=='sighs':
            self.say(channel, '/me yawns')
            print yawn


    # irc callbacks

    def irc_NICK(self, prefix, params):
        """Called when an IRC user changes their nickname."""
        old_nick = prefix.split('!')[0]
        new_nick = params[0]
        self.logger.log("%s is now known as %s" % (old_nick, new_nick))


class LogBotFactory(protocol.ClientFactory):
    """A factory for LogBots.

    A new protocol instance will be created each time we connect to the server.
    """

    # the class of the protocol to build when new connection is made
    protocol = LogBot

    def __init__(self, channel, filename):
        self.channel = channel
        self.filename = filename

    def clientConnectionLost(self, connector, reason):
        """If we get disconnected, reconnect to server."""
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "connection failed:", reason
        reactor.stop()

if __name__ == '__main__':
    # initialize logging

    
    # create factory protocol and application
    f = LogBotFactory(sys.argv[1], sys.argv[2])

    # connect factory to this host and port
    reactor.connectTCP("irc.freenode.net", 6667, f)

    # run bot
    reactor.run()