All pastes #385582 Raw Edit

Python IRC bot

public python v1 · immutable
·published 2007-03-07 22:42 UTC
rendered paste body
I've just added a tiny bit to the skeleton irc client example that comes bundled with twisted.# Copyright (c) 2001-2004 Twisted Matrix Laboratories.# See LICENSE for details.# twisted importsfrom twisted.words.protocols import ircfrom twisted.internet import reactor, protocol, task, utilsfrom twisted.python import logfrom twisted.web import client# system importsimport time, sysfrom xml.dom.minidom import parseStringclass MessageLogger:    """    An independent 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."""    nickname = "monkeybot"    lastCallout = None    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 _monitorDigg(self):        d = client.getPage('http://services.digg.com/stories/1298237')        def _foo(result):            dom = parseString(result)            story = dom.getElementsByTagName('story')[0]            digs = int(story.getAttribute('digs'))            print 'last callout: %-6s this poll: %-6s' % (                self.lastCallout, digs)            if self.lastCallout == None or digs - self.lastCallout > 50:                self.msg('#%s' % self.factory.channel.split()[0], '%s digs!' % digs)                self.lastCallout = digs            return result        d.addCallback(_foo)        return d    def _monitorMunin(self):        d = utils.getProcessOutput('/usr/bin/ssh',            ['jb01x', '/etc/munin/plugins/events_sqlite'])        def _foo(result):            lag = result.split('\n')[0].split()[1]            self.msg('#%s' % self.factory.channel.split()[0],                'current qt event flush lag: %s ... ook' % lag)        d.addCallback(_foo)        return d    def joined(self, channel):        """This will get called when the bot joins the channel."""        self.logger.log("[I have joined %s]" % channel)        # self.loop = task.LoopingCall(self._monitorDigg)        # self.loop.start(60.0)        self.loop = task.LoopingCall(self._monitorMunin)        self.loop.start(60*30)    def privmsg(self, user, channel, msg):        """This will get called when the bot receives a message."""        user = user.split('!', 1)[0]        self.logger.log("<%s> %s" % (user, msg))        # Check to see if they're sending me a private message        if channel == self.nickname:            msg = "It isn't nice to whisper!  Play nice with the group."            self.msg(user, msg)            return        # Otherwise check to see if it is a message directed at me        if msg.startswith(self.nickname + ":"):            msg = "%s: ook ook" % user            self.msg(channel, msg)            self.logger.log("<%s> %s" % (self.nickname, 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))    # 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    log.startLogging(sys.stdout)    # create factory protocol and application    f = LogBotFactory(sys.argv[1], sys.argv[2])    # connect factory to this host and port    reactor.connectTCP("irc.revver.com", 6667, f)    # run bot    reactor.run()