Building an IRC bot in python: Difference between revisions
No edit summary |
(→Hello) |
||
(8 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
The [ | Somewhat redundant to example given on the [[IRC]] page. | ||
The [http://pypi.python.org/pypi/irc irc] module provides a number of useful hooks/classes for writing python IRC bots. | |||
sudo pip install irc | sudo pip install irc | ||
== Hello == | |||
Here's a simple "hello" bot which responds to all chat messages by replying "HELLO". | Here's a simple "hello" bot which responds to all chat messages by replying "HELLO". | ||
Line 8: | Line 12: | ||
class HelloBot(irc.bot.SingleServerIRCBot): | class HelloBot(irc.bot.SingleServerIRCBot): | ||
def __init__(self, channel, nickname, server, port=6667): | |||
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) | |||
self.channel = channel | |||
def on_welcome(self, c, e): | |||
c.join(self.channel) | |||
def on_privmsg(self, c, e): | |||
pass | |||
def on_pubmsg(self, c, e): | |||
# e.target, e.source, e.arguments, e.type | |||
print (e.arguments) | |||
c.privmsg(self.channel, "HELLO") | |||
if __name__ == "__main__": | |||
import argparse | |||
import sys | |||
ap = argparse.ArgumentParser("IRC Bot") | |||
ap.add_argument("--server", default="irc.freenode.net") | |||
ap.add_argument("--port", type=int, default=6667) | |||
ap.add_argument("--channel", default="#pzi") | |||
ap.add_argument("--nickname", default="hellobot") | |||
args=ap.parse_args() | |||
bot = HelloBot(args.channel, args.nickname, args.server, args.port) | |||
bot.start() | |||
</source> | |||
== Reverse Bot == | |||
<source lang="python"> | |||
import irc.bot | |||
class FileBot(irc.bot.SingleServerIRCBot): | |||
def __init__(self, channel, nickname, server, port=6667): | def __init__(self, channel, nickname, server, port=6667): | ||
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) | irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) | ||
Line 21: | Line 62: | ||
# e.target, e.source, e.arguments, e.type | # e.target, e.source, e.arguments, e.type | ||
print e.arguments | print e.arguments | ||
c.privmsg(self.channel, | msg = e.arguments[0] | ||
words = msg.split() | |||
words.reverse() | |||
msg = " ".join(words) | |||
c.privmsg(self.channel, msg) | |||
Line 27: | Line 72: | ||
import sys | import sys | ||
if len(sys.argv) != 4: | if len(sys.argv) != 4: | ||
print "Usage: | print "Usage: reversebot.py <server[:port]> <channel> <nickname>" | ||
sys.exit(1) | sys.exit(1) | ||
s = sys.argv[1].split(":", 1) | s = sys.argv[1].split(":", 1) | ||
Line 41: | Line 86: | ||
channel = sys.argv[2] | channel = sys.argv[2] | ||
nickname = sys.argv[3] | nickname = sys.argv[3] | ||
bot = | bot = FileBot(channel, nickname, server, port) | ||
bot.start() | bot.start() | ||
</source> | </source> | ||
== PIPEBOT == | |||
<source lang="python"> | |||
from __future__ import print_function | |||
import irc.bot | |||
import sys, time | |||
from thread import start_new_thread | |||
def chunks(l, n): | |||
""" Yield successive n-sized chunks from l. | |||
""" | |||
for i in xrange(0, len(l), n): | |||
yield l[i:i+n] | |||
class Bot (irc.bot.SingleServerIRCBot): | |||
def __init__(self, channel, nickname, server, input, port=6667, idle=False): | |||
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) | |||
self.input = input | |||
self.channel = channel | |||
if idle: | |||
start_new_thread(self.idle, ()) | |||
def on_welcome(self, c, e): | |||
c.join(self.channel) | |||
print ("join", file=sys.stderr) | |||
start_new_thread(self.receive, (c,)) | |||
def idle(self): | |||
while True: | |||
tstr = time.strftime("%H:%M:%S", time.localtime()) | |||
out = u"({0}) {1}: {2}".format(tstr, "_system", "idle") | |||
sys.stdout.write(out.encode("utf-8")+"\n") | |||
sys.stdout.flush() | |||
time.sleep(1) | |||
def receive (self, c): | |||
if self.input == sys.stdin: | |||
# print ("reading from stdin", file=sys.stderr) | |||
_in = sys.stdin | |||
else: | |||
# print ("reading from {0}".format(self.input), file=sys.stderr) | |||
_in = open(self.input) | |||
while True: | |||
line = _in.readline() | |||
if line == '': | |||
break | |||
line = line.rstrip().decode("utf-8") | |||
if line: | |||
# print ("read line: {0}".format(line), file=sys.stderr) | |||
# CHUNK IT | |||
for chunk in chunks(line, 400): | |||
c.privmsg(self.channel, chunk) | |||
def on_pubmsg(self, c, e): | |||
# e.target, e.source, e.arguments, e.type | |||
msg = e.arguments[0] | |||
tstr = time.strftime("%H:%M:%S", time.localtime()) | |||
nick = e.source.split("!", 1)[0] | |||
out = u"({0}) {1}: {2}".format(tstr, nick, msg) | |||
sys.stdout.write(out.encode("utf-8")+"\n") | |||
sys.stdout.flush() | |||
# print ("pubmsg: {0}".format(msg), file=sys.stderr) | |||
if __name__ == "__main__": | |||
from argparse import ArgumentParser | |||
parser = ArgumentParser() | |||
parser.add_argument('--server', default='irc.freenode.net', help='server hostname (default: localhost)') | |||
parser.add_argument('--port', default=6667, type=int, help='server port (default: 6667)') | |||
parser.add_argument('--channel', default='#botopera', help='channel to join (default: #botopera)') | |||
parser.add_argument('--nickname', default='pipebot', help='bot nickname (default: pipebot)') | |||
parser.add_argument('--input', default=sys.stdin, help='input') | |||
parser.add_argument('--idle', default=False, action="store_true", help='output idle messages') | |||
args = parser.parse_args() | |||
bot = Bot(args.channel, args.nickname, args.server, args.input, port=args.port, idle=args.idle) | |||
bot.start() | |||
</source> | |||
[[Category: Cookbook]][[Category: Python]][[Category: IRC]] |
Latest revision as of 19:43, 19 March 2018
Somewhat redundant to example given on the IRC page.
The irc module provides a number of useful hooks/classes for writing python IRC bots.
sudo pip install irc
Hello
Here's a simple "hello" bot which responds to all chat messages by replying "HELLO".
import irc.bot
class HelloBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port=6667):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel
def on_welcome(self, c, e):
c.join(self.channel)
def on_privmsg(self, c, e):
pass
def on_pubmsg(self, c, e):
# e.target, e.source, e.arguments, e.type
print (e.arguments)
c.privmsg(self.channel, "HELLO")
if __name__ == "__main__":
import argparse
import sys
ap = argparse.ArgumentParser("IRC Bot")
ap.add_argument("--server", default="irc.freenode.net")
ap.add_argument("--port", type=int, default=6667)
ap.add_argument("--channel", default="#pzi")
ap.add_argument("--nickname", default="hellobot")
args=ap.parse_args()
bot = HelloBot(args.channel, args.nickname, args.server, args.port)
bot.start()
Reverse Bot
import irc.bot
class FileBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port=6667):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel
def on_welcome(self, c, e):
c.join(self.channel)
def on_privmsg(self, c, e):
pass
def on_pubmsg(self, c, e):
# e.target, e.source, e.arguments, e.type
print e.arguments
msg = e.arguments[0]
words = msg.split()
words.reverse()
msg = " ".join(words)
c.privmsg(self.channel, msg)
if __name__ == "__main__":
import sys
if len(sys.argv) != 4:
print "Usage: reversebot.py <server[:port]> <channel> <nickname>"
sys.exit(1)
s = sys.argv[1].split(":", 1)
server = s[0]
if len(s) == 2:
try:
port = int(s[1])
except ValueError:
print "Error: Erroneous port."
sys.exit(1)
else:
port = 6667
channel = sys.argv[2]
nickname = sys.argv[3]
bot = FileBot(channel, nickname, server, port)
bot.start()
PIPEBOT
from __future__ import print_function
import irc.bot
import sys, time
from thread import start_new_thread
def chunks(l, n):
""" Yield successive n-sized chunks from l.
"""
for i in xrange(0, len(l), n):
yield l[i:i+n]
class Bot (irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, input, port=6667, idle=False):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.input = input
self.channel = channel
if idle:
start_new_thread(self.idle, ())
def on_welcome(self, c, e):
c.join(self.channel)
print ("join", file=sys.stderr)
start_new_thread(self.receive, (c,))
def idle(self):
while True:
tstr = time.strftime("%H:%M:%S", time.localtime())
out = u"({0}) {1}: {2}".format(tstr, "_system", "idle")
sys.stdout.write(out.encode("utf-8")+"\n")
sys.stdout.flush()
time.sleep(1)
def receive (self, c):
if self.input == sys.stdin:
# print ("reading from stdin", file=sys.stderr)
_in = sys.stdin
else:
# print ("reading from {0}".format(self.input), file=sys.stderr)
_in = open(self.input)
while True:
line = _in.readline()
if line == '':
break
line = line.rstrip().decode("utf-8")
if line:
# print ("read line: {0}".format(line), file=sys.stderr)
# CHUNK IT
for chunk in chunks(line, 400):
c.privmsg(self.channel, chunk)
def on_pubmsg(self, c, e):
# e.target, e.source, e.arguments, e.type
msg = e.arguments[0]
tstr = time.strftime("%H:%M:%S", time.localtime())
nick = e.source.split("!", 1)[0]
out = u"({0}) {1}: {2}".format(tstr, nick, msg)
sys.stdout.write(out.encode("utf-8")+"\n")
sys.stdout.flush()
# print ("pubmsg: {0}".format(msg), file=sys.stderr)
if __name__ == "__main__":
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('--server', default='irc.freenode.net', help='server hostname (default: localhost)')
parser.add_argument('--port', default=6667, type=int, help='server port (default: 6667)')
parser.add_argument('--channel', default='#botopera', help='channel to join (default: #botopera)')
parser.add_argument('--nickname', default='pipebot', help='bot nickname (default: pipebot)')
parser.add_argument('--input', default=sys.stdin, help='input')
parser.add_argument('--idle', default=False, action="store_true", help='output idle messages')
args = parser.parse_args()
bot = Bot(args.channel, args.nickname, args.server, args.input, port=args.port, idle=args.idle)
bot.start()