Forum Thread: Python IRC bot, v3

Beware, the code is quite ratty. A goal in this version was to be able to update/add commands without having to restart the bot. Mission accomplished.

botim.py:

import sys
import socket
import re
import select
from time import sleep
from command import command

#Global Variables
host    = "irc.darchoods.net"   #This is the IRC server variable.
port    = 6667                  #This is the port
nick    = ""             #Bot name
ident   = ""             #ID to NickServ with this name
servername = "bla"
realname= ""             #Bots real name for server identification
password= ""
channel = "#nullbytez"          #This is the channel name

CRLF = '\r\n'
# Examples
# Considered adding something to make it a little more channel independant
"""
    All functions must take one argument: args
    args[0] is the socket
    args[1] is the command object
    args[2] is a list of extra arguments
"""
def pong(args):
    args[0].sendall('PONG :' + args[1] + CRLF)
def b_quit(args):
    args[0].sendall("QUIT :Quit Leaving" + CRLF)
def addUser(args):
    args[1].addSafe('ryoh', args[2][0])
def rmUser(args):
    args[1].rmSafe('ryoh', args[2][0])
def opUser(args):
    args[0].sendall("MODE #nullbytez +o " + args[2][0] + CRLF)
def loadMod(args):
    args[1].load('ryoh', args[2][0])
def refresh(args):
    args[1].refresh('ryoh', args[2][0])

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP )
    s.connect((host, port))
    s.sendall("NICK %s\r\n" % nick) #Sets the Bot's nick name
    s.sendall("USER %s %s %s :%s\r\n" % (ident, host, servername, realname)) #Logs Bot into IRC and ID's
    # at this point I'm connected and ready to start talking
    f = s.makefile() # I do this to take advantage of readline()
    runner = command(['ryoh', 'L-'])
    runner.add('ryoh', 'pong', pong)
    runner.add('ryoh', '!quit', b_quit)
    runner.add('ryoh', '!add', addUser)
    runner.add('ryoh', '!rm', rmUser)
    runner.add('ryoh', '!op', opUser)
    runner.add('ryoh', '!load', loadMod)
    runner.add('ryoh', '!reload', refresh)
    while 1:
        ready = select.select([0, f], [], [])
        if 0 in ready[0]:
            data = sys.stdin.readline().rstrip().lstrip()
            if data: s.sendall(data + CRLF)

        if f in ready[0]:
            line = f.readline().rstrip().lstrip()
            if 'PING' in line:
                server = line.split(':')[1].lstrip().rstrip()
                runner.do('ryoh', 'pong', s, server)
            if line:
                print line
                if line[0] == ':':
                    try:
                        extras = line.split(':')[2].split(' ')[1:]
                    except IndexError: extras = ''
                    try:
                        if runner.check(line.split(':')[2].split(' ')[0]):
                            runner.do(line.split(':')[1].split('!')[0],
                            line.split(':')[2].split(' ')[0], s, runner, extras)
                    except IndexError: pass
            else: break

if __name__ == '__main__':
    main()

command.py:

class command:

    _COMMANDS = {}

    _safe = []

    def __init__(self, safe):
        self._safe = safe

    def add(self, user, command, handle):
        if user in self._safe:
            if command not in self._COMMANDS:
                self._COMMANDS[command.lower()] = handle

    def rm(self, user, command):
        if user in self._safe:
            if command.lower() in self._COMMANDS:
                del self._COMMANDS[command.lower()]

    def do(self, user, command, *args):
        if user in self._safe:
            self._COMMANDS[command.lower()](args)

    def load(self, user, module):
        self._extract(__import__(module))

    def _extract(self, module):
        for command in dir(module):
            self._COMMANDS["!" + command] = eval("module."+command)

    def refresh(self, user, module):
        m = __import__(module)
        reload(m)
        self._extract(m)

    def getSafe(self, user):
        if user in self._safe:
            return self.safe

    def addSafe(self, user, name):
        if user in self._safe:
            self._safe.append(name)

    def rmSafe(self, user, name):
        if user in self._safe:
            self._safe.remove(name)

    def check(self, command):
        if command in self._COMMANDS:
            return True
        else:
            return False

extras.py:

"""
    All functions must take one argument: args
    args[0] is the socket
    args[1] is the command object
    args[2] is a list of extra arguments
"""
CRLF = '\r\n'
def say(args):
    string = ''
    for c in args[2]:
        string += c + ' '
    args[0].sendall("PRIVMSG #nullbytez :" + string + CRLF)

def nig(args):
    args[0].sendall("PRIVMSG #nullbytez :now I can add shit on the fly" + CRLF)

1 Response

You so fly ;D. This is so great :') I love what silly creations turn into.

Share Your Thoughts

  • Hot
  • Active