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 クラスのメソッドで、
第一引数が秒数、第二引数がコールバック関数、第三引数がコールバック関数に渡す引数になっている。

「第二引数に設定した関数」を「第一引数に設定した秒数」ごとに呼び出してくれる素敵メソッドだ。
登録したコールバック関数は、内部で勝手に始末してくれるのでリーク的な心配もない。

文字コード周りが、地味に面倒だったず。

コメントを残す

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt="">