Python で実装する IRCボット
たまたま作る機会があった IRCボットを Python で実装してみたメモ。
環境は CentOS 5.4、Python 2.4
python-irclib
IRCボットを簡単に作成できるライブラリ、python-irclib をインストールする。
$ wget http://sourceforge.net/projects/python-irclib/files/python-irclib/0.4.8/python-irclib-0.4.8.zip/download
$ unzip python-irclib-0.4.8.zip
$ cd python-irclib-0.4.8
$ python setup.py build
$ sudo python setup.py install
ソースコード
下のコードは、ある時間になったら挨拶するボットのサンプルコード。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from ircbot import SingleServerIRCBot
from irclib import nm_to_n
import datetime
IRC_SERVER = "192.168.11.30"
IRC_PORT = 6667
IRC_CHANNEL = "#HOGE"
IRC_NICK = "botpy"
IRC_TIMER_SEC = 60
class BotPy(SingleServerIRCBot):
"""
bot class
"""
def __init__(self):
"""
コネクションを張る
"""
SingleServerIRCBot.__init__(self, [(IRC_SERVER, IRC_PORT)], IRC_NICK, IRC_NICK)
self.channel = IRC_CHANNEL
def on_nicknameinuse(self, c, e):
"""
ニックネームが被ってたら末尾に _ を付ける
"""
c.nick( c.get_nickname() + "_" )
def on_welcome(self, c, e):
"""
サーバに接続成功。指定チャンネルに入る
"""
print "welcome"
c.join( self.channel )
def on_privmsg(self, c, e):
"""
メッセージを検知
"""
try:
nick = nm_to_n( e.source() )
msg = unicode( e.arguments()[0], "iso-2022-jp" ).encode("utf-8")
except:
print str(e)
return
print "%s: %s" % (nick, msg)
on_pubmsg = on_privmsg
def on_ping(self, c, e):
self.connection.pong( self.channel )
def privmsg(self, str):
"""
チャット発言
"""
self.connection.privmsg( self.channel, unicode(str, "utf8").encode("iso-2022-jp", "ignore") )
def notice(self, str):
"""
通知発言
"""
self.connection.notice( self.channel, unicode(str, "utf8").encode("iso-2022-jp", "ignore") )
def add_execute_delayed(self, sec, callback, obj):
"""
遅延実行関数(指定秒たったら、指定関数を実行)
"""
self.ircobj.execute_delayed(sec, callback, obj)
def call_timer( bot ):
"""
タイマー関数
9時と12時と19時に挨拶する
指定秒間隔でポーリング
"""
d = datetime.datetime.today()
# 時報
if( d.hour == 9 and d.minute == 0 ):
bot.notice( "おはようございます" )
elif( d.hour == 12 and d.minute == 0 ):
bot.notice( "こんにちわ" )
elif( d.hour == 19 and d.minute == 0 ):
bot.notice( "こんばんわ" )
bot.add_execute_delayed( IRC_TIMER_SEC, call_timer, (bot,))
bot = BotPy()
bot.add_execute_delayed( IRC_TIMER_SEC, call_timer, (bot,))
bot.start()
↑のコードを書いてるときに一番悩んだのが、タイマー的な処理の仕方。
結局、BotPy::add_execute_delayed()で呼び出しているself.ircobj.execute_delayed()を使って、解決した。
このメソッドは irclib::IRC クラスのメソッドで、
第一引数が秒数、第二引数がコールバック関数、第三引数がコールバック関数に渡す引数になっている。
「第二引数に設定した関数」を「第一引数に設定した秒数」ごとに呼び出してくれる素敵メソッドだ。
登録したコールバック関数は、内部で勝手に始末してくれるのでリーク的な心配もない。
文字コード周りが、地味に面倒だったず。