2012年4月7日土曜日

[vim][python] 社内で「vim」って発言したら、僕まで伝わっちゃうけどあしからず。

社内で交わされているvimネタはすべて押えておきたい。

そこで、いろんなチャンネルで「vim」を含む発言があったら、
「#vim」チャンネルにその発言を流すIRCボットを作った。

結構簡単に書けたけど、pingがうまく返っていなかったことで引っかかった。
try and errorで書いたから、無駄なところ結構ある。
もうチョットちゃんとpythonかけるようになろう。
っていっつも思って何もしてないorz。


この辺とか参考にした。
Python で IRC クライアント的な


ソース


#!/usr/bin/python
# coding=utf-8
 
import socket
import string
import time
import re
import sys
 
SERVER = 'irc.karino.org'
PORT = 6667
NICKNAME = 'vimbot'
CHANNEL = '#vim'
 
class IRC(object):
 
    """ init """
    def __init__(self):
        """__init__ documentation"""
        self.SERVER = SERVER
        self.PORT = PORT
 
    def connect(self):
        """__init__ documentation"""
        self.__con = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__con.connect( (self.SERVER, self.PORT) )
 
    def __send_data(self, command):
        res = self.__con.send(command + '\n')
 
    def __recv_data(self):
        res = self.__con.recv(1024)
        return res
 
    def login(self, nickname, username='hogename', password = None, realname='Hoge Hoge', hostname='host', servername='server'):
        self.__send_data("USER %s %s %s %s" % (username, hostname, servername, realname))
        self.__send_data("NICK " + nickname)
 
    def join(self, channel):
        #self.__send_data("JOIN %s" % channel)
        self.__send_data(u"JOIN " + channel)
 
    def post(self, text):
        self.__send_data((u"PRIVMSG " + CHANNEL + u" :" + text).encode('iso-2022-jp', 'ignore'))
 
    def pong(self, text):
        self.__send_data(u"PONG " + text)
 
    def part(self, channel):
        text = 'Leaving...'
        self.__send_data(u"PART " + channel + u" :" + text)
 
    def quit(self):
        text = 'Leaving...'
        self.__send_data(u"QUIT " + u" :" + text)
 
    def channel_list(self):
        _re_channel_search = re.compile(r'(#.+) \d+ :').search
        def get_channel(line):
            try:
                mo = _re_channel_search(line)
            except IndexError:
                return None
            return mo.group(1) if mo else None
 
        # send
        self.__send_data("LIST")
        buf = ""
        result = []
        flg = 0
 
        # recv
        while 1:
            buf = buf + self.__recv_data()
            tmp = string.split(buf, "\n")
            buf = tmp.pop()
 
            for line in tmp:
                #print line
                line=string.rstrip(line)
 
                if(":End of /LIST" in line):
                    flg = 1
                    break
 
                else:
                    #print line
                    if get_channel(line) != None:
                        result.append( get_channel(line) )
 
            if flg==1:
                break
 
        return result
 
    def recv(self):
 
        _re_get_message_search = re.compile(r'PRIVMSG (#.+ :.+)').search
        def get_message(line):
            try:
                mo = _re_get_message_search(line)
            except IndexError:
                return None
            return mo.group(1) if mo else None
 
        buf = ''
        buf = buf + self.__recv_data()
        tmp = string.split(buf, "\n")
        buf = tmp.pop()
 
        for line in tmp:
            print line
            line=string.rstrip(line)
            return line
 
def main():
 
    _re_get_ping_search = re.compile(r'PING :(.+)').search
    def get_ping(line):
        try:
            mo = _re_get_ping_search(line)
        except IndexError:
            return None
        return mo.group(1) if mo else None
 
    _re_get_message_search = re.compile(r'PRIVMSG (#.+ :.+)').search
    def get_message(line):
        try:
            mo = _re_get_message_search(line)
        except IndexError:
            return None
        return mo.group(1) if mo else None

    # connect irc server / irc channel
    irc = IRC()
 
    #irc.connect(SERVER, PORT)
    irc.connect()
    irc.login(NICKNAME)
 
    # getchannel
    clist = irc.channel_list() 
    print clist
 
    # join all channel
    for l in clist:
        irc.join(l)
 
    # join all channel
    while 1:
        try:
            # recv
            line = irc.recv()
 
            if ("PING" in line):
                line=get_ping(line)
                irc.pong(line)
                continue
 
            elif ("ERROR" in line):
                print "error :" + line
                irc.connect()
                irc.login(NICKNAME)
                for l in clist:
                    irc.join(l)
                continue
 
            elif (CHANNEL in line):
                continue
 
            elif ("PRIVMSG" in line):
                buf = get_message(line)
                if buf.find('vim') >= 0:
                    irc.post(buf)
                continue
 
        except:
            continue
 
if __name__ == '__main__':
    main()

0 件のコメント:

コメントを投稿