jueves, 1 de julio de 2010

Un bot IRC

Aprovechando el PyIC escribí un bot que se une a un canal y responde a los típicos mensajes de "@loquesea" y "!loquesea", que están definidos en una base de datos SQLite3, la idea es algo así:
Se crea un archivo SQLite3 (por defecto el nombre es "dbase.db", si quieres puedes cambiarlo en la línea 12) con 2 tablas, "talks" y "commands".
La tabla "talks" tendría como mínimo 2 columnas, la primera es la palabra a la que responde, y la segunda, con lo que responde, por ejemplo, si la base de datos tiene esta fila:


busca | http://www.lmgtfy.com/?q=


El chat sería algo así


<humano>: @busca loquesea
< bot >: humano: http://www.lmgtfy.com/?q=loquesea


La tabla "commands" es mas o menos igual, dos columnas, la primera el comando, y la segunda lo que se ejecuta, por ejemplo...


info | uname



<humano>: !info -a
< bot >: humano: Linux blablabla 2.6.32-22-generic #36trisquel1 SMP Sat Jun 5 02:09:43 UTC 2010 i686 GNU/Linux


Solo decir que si despues del simbolo ('@'/'!') se escribe un nick seguido de ':', este será al que se hable...



<humano>: @humano2:busca loquesea
< bot >: humano2: http://www.lmgtfy.com/?q=loquesea


Y no se me ocurre que más comentar :P, aqui está el código [yabot.py], o coloreado...



#!/usr/bin/env python
# Ejemplo de cliente IRC con pyIC

from pyic import *
import sqlite3, os

botName = "vagoBot" # Nombre del bot
server = "irc.freenode.net" # Adivina xD
channel = "#bot_testing" # Canal al que se une el Bot

global db_file
db_file = "dbase.db" # Archivo sqlite3

def sayIt(irc, msg, ex):
    to = msg.by
    via = msg.to
    mmsg = msg.msg
    if ( via == irc.nick ):
        via = msg.by
    cc = 0
    try:
        cc = mmsg.index(":")
        try:
            sc = mmsg.index(" ")
            if (sc > cc):
                to = mmsg[ 0 : cc ]
        except:
            to = mmsg[ 0 : cc ]
        cc += 1
        mmsg = mmsg[ cc : ]
    except:
        pass

    try:
        i = mmsg.index(" ")
        command = mmsg[ : i ]
        args = mmsg[ i + 1 : ]
    except:
        command = mmsg
        args = ""

    conn = sqlite3.connect(db_file)
    cur = conn.cursor()
    if (not ex):
        cur.execute("select * from talks")
    else:
        cur.execute("select * from commands")
    for line in cur:
        if (line[ 0 ] == command):
            if ( not ex):
                irc.notice( via, to + ": " + line[ 1 ] + args )
            else:
                p = os.popen( line[ 1 ] + args , "r" )
                l = p.readline()
                while ( len( l ) > 0 ):
                    while (l [ -1 ] == "\r" ) or (l [ -1 ] == "\n"):
                        l = l [ : -1 ]
                    irc.notice(via, to + ": " + l )
                    l = p.readline()

irc = irc_client(botName,server)
# Esperar por que acabe de "presentarse" el servidor
print "Esperando a que acabe de presentarse..."
while ( True ):
    msg = irc.getmsg()
    if ( msg.type == RPL_ENDOFMOTD ): # Fin del mensaje del dia
        break
    elif (msg.type == ERR_NOMOTD): # No hay mensaje del dia
        break

print "Entrando a",channel
irc.join( channel ) # Se une al canal
# Saluda a todos los que hay en el canal
while ( True ):
    msg = irc.getmsg()
    if (msg.type.upper() == "PRIVMSG") or (msg.type.upper() == "NOTICE"):
        msg.msg = msg.msg.strip()
        if (msg.msg[ 0 ] == "!"):
            msg.msg = msg.msg [ 1 : ]
            sayIt(irc, msg, True)
        elif (msg.msg[ 0 ] == "@" ):
            msg.msg = msg.msg [ 1 : ]
            sayIt(irc, msg, False)


Hasta otra!

2 comentarios:

  1. Genial :). No se si conoces phenny, es un bot para irc bastante completo y modular. Este codigo viene bien para fabricarse uno y da mucho juego para ejecutar ciertos scripts o programas y ofrecer un resultado. Me lo llevo ¡¡¡. :)

    ResponderEliminar
  2. Ando echandole un vistazo al phenny y tiene muy buena pinta :D, gracias por comentarlo

    ResponderEliminar