baab37b8 |
"""
An example IRC log bot - logs a channel's events to a file.
If someone says the bot's name in the channel followed by a ':',
e.g.
<foo> logbot: hello!
the bot will reply:
<logbot> foo: I am a log bot
Run this script with two arguments, the channel name the bot should
connect to, and file to log to, e.g.:
$ python ircLogBot.py test test.log
will log channel #test to the file 'test.log'.
To run the script:
$ python ircLogBot.py <channel> <file>
"""
# twisted imports
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol, threads
from twisted.python import log
import base64
# system imports
import time, sys
class MessageLogger:
"""
An independent logger class (because separation of application
and protocol logic is a good thing).
"""
def __init__(self, bot):
self.bot = bot
self.user_queue = []
def get_message(self):
"""Write a message to the file."""
try:
inp = raw_input('irc> ')
return map(str.strip, inp.partition(':')[::2])
except (EOFError, KeyboardInterrupt):
reactor.callFromThread(reactor.stop)
return (None,None)
def send_message(self, res):
user, message = res
if user is not None:
print '<%s> %s: %s' % (self.bot.nickname, user, message)
self.user_queue.append(user)
reactor.callFromThread(self.bot.msg, user, message)
def handle(self, user, message):
handled = self.user_queue != [] and self.user_queue.pop(0) == user
if handled:
print '\r<%s> %s: %s' % (user, self.bot.nickname, message)
return handled
class LogBot(irc.IRCClient):
"""A logging IRC bot."""
nickname = base64.encodestring('fiddlerwoaroof')[:len('fiddlerwoaroof')]
def connectionMade(self):
irc.IRCClient.connectionMade(self)
|
baab37b8 |
def privmsg(self, user, channel, msg):
"""This will get called when the bot receives a message."""
user = user.split('!', 1)[0]
# Check to see if they're sending me a private message
if channel == self.nickname:
handled = self.handler.handle(user, msg)
if handled:
d = threads.deferToThread(self.handler.get_message)
d.addCallback(self.handler.send_message)
# For fun, override the method that determines how a nickname is changed on
# collisions. The default method appends an underscore.
def alterCollidedNick(self, nickname):
"""
Generate an altered version of a nickname that caused a collision in an
effort to create an unused related name for subsequent registration.
"""
return base64.encodestring(nickname)[:len(nickname)].strip()
class LogBotFactory(protocol.ClientFactory):
"""A factory for LogBots.
A new protocol instance will be created each time we connect to the server.
"""
def buildProtocol(self, addr):
p = LogBot()
p.factory = self
return p
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__':
# create factory protocol and application
f = LogBotFactory()
# connect factory to this host and port
reactor.connectTCP("irc.freenode.net", 6667, f)
# run bot
reactor.run()
|