#!/usr/bin/env python from re import sub from time import ctime, time from sys import exit from os import system, path from subprocess import Popen, PIPE import random, signal s = None NICK = None nick = None channel = None CHAN = None ops = None pts = None plugins = ['help','echo','loop','quote','say','do','hi','poop','music_shuffle','botsnack','assicon','chkop','lart/pwn/shoot/esplode','hunger','woot','ddate','time/date','owner/propertyof/property','whoami/whatami'] plugins.sort() depplugins = ['hungernum'] depplugins.sort() opplugins = ['join','part','quit','nick','sys','addop/s','removeop/s','updateop/s','ping','server'] opplugins.sort() personalplugins = ['ftp','sys/system/comm/command'] personalplugins.sort() channel = '' t = None n = None poll = [] hunger = 0 hungertimer = 5 * 60 def update_hunger(): global hunger a = open('hungerfile','w') a.write(str(hunger)); a.close() def change_hunger(*args): global hunger if hunger != 0: hunger -= 1 elif hunger == 0: #if random.randint(1, 5) == 1: if True: global channel hungryphrase = ["I'm hungry!", 'I need some yummy in my tummy'] hungryaction = ['wants to be fed', 'is hungry', 'needs food'] if random.randint(1, 3) == 1: phrase = random.choice(hungryphrase) else: phrase = random.choice(hungryaction) send(random.choice(hungryphrase), channel) update_hunger() signal.alarm(hungertimer) try: hunger = int(open('hungerfile','r').readline().strip()) except IOError: open('hungerfile','w').write(str(hunger)); signal.signal(signal.SIGALRM, change_hunger) # alarm signal signal.alarm(hungertimer) # five minutes def irctext(l): a = ' '.join(l[3:]) if a != '' and a[0] == ':': a = a[1:] return a def comm(l): return parse(l).split(' ') def del_misc(s): return sub(r'^[^a-zA-Z]*', '', s) def parse(l): text = irctext(l) if text == None or text == '': return '' if text.startswith(NICK): # If NICK..... written in channel text = text.lstrip(NICK) elif text.startswith('~'): # If '~.....' written in channel text = text.lstrip('~') elif l[2] == NICK: # If sent a private message global channel, nick; if nick != None: channel = nick else: return '' text = del_misc(text) # Replaced by above: #while not text[0].lower() in 'abcdefghijklmnopqrstuvwxyz': # text = text[1:] return text def ops_func(s, *args): global ops global channel if len(args) > 0 and type(args[0]) == list: args = args[0] opsfile = open('ops','r+') if s == '' or s == None: return False elif s == 'reload': ops = [] for i in opsfile.readlines(): i = i.strip() if i != None or i != '': ops += [i] opsfile.close() return True elif s == 'add': try: ops += args opsfile.write('\n'.join(ops)) except: send('Unable to add op/s: ' + ' '.join(args), channel) opsfile.close() ops_func('reload') return True elif s == 'remove': ops_func('reload') for i in args: try: if len(ops) > 1: ops.remove(i) else: send('Could not remove op ' + i + ' -- there must be at least one op', channel) except: send('Unable to remove op ' + i, channel) opsfile.truncate(0) opsfile.write('\n'.join(ops)) opsfile.close() return True elif s == 'update': opsfile.truncate(0) opsfile.write('\n'.join(ops)) opsfile.close() return True elif s == 'check': for i in args: if i not in ops: send(i + ' is not an op', channel) return False break else: return True else: if s in ops: return True else: return False print ops def chkpw(password): storedpassword = open('pw', 'r').read().strip() if password == storedpassword: return True else: return False def get_nick(l): if type(l) == str: try: return l[1:l.index('!')] except: return None elif type(l) == list: return get_nick(l[0]) def chks(): if s == None or NICK == None or ops == None or CHAN == None: return False else: return True def send(message, channel): s.send('PRIVMSG %s :%s\r\n' % (channel, message)) def splitsend(message, split, channel): for i in message.split(split): if i.strip() == '' or i.strip() == None: break s.send('PRIVMSG %s :%s\r\n' % (channel, message)) def action(message, channel): s.send('PRIVMSG %s :%s\r\n' % (channel, '\x01ACTION ' + message + '\x01')) def name(s, l): if s.lower() == 'me': return get_nick(l=l) elif s.lower() in ['yourself', 'you']: return NICK elif s.lower() == 'here': global channel; return channel else: return s def chk(i): # Init stuff if chks() == False: return global channel, t, n, nick, poll # Parse text and other stuff into vars if len(i) > 2: channel = i[2] # channel/pm'er (ie '#botisland') nick = get_nick(i) # nick/sender (ie 'pianoboy3333') text = parse(i) # text sent to bot (ie 'echo FOO bar') if len(text) == 1: return args = comm(i) # split text (ie ['echo', 'FOO', 'bar']) command = args[0].lower() # command sent to bot (ie 'echo') phrase = text.lower() # line sent to bot (ie 'echo foo bar') #password = chk_password(command) # if command is a password modargs = [] # Modified args, so that stuff changes, like me to for a in args: modargs += [name(a, i)] if i[0] == 'PING': s.send("PONG %s\r\n" % i[1]) print 'PING recieved at ' + ctime() + ' from ' + i[1] return elif i[1] == 'PONG': print 'PING recieved at ' + ctime() + ' from ' + i[2] n = time() - t send('Ping took ' + str(n)[:4] + 's', channel) return # if '~' is typed or just 'bassoonbot:' if text == '' or text == None: return else: print 'command:', text # "Plugins" if command == 'echo': send(' '.join(args[1:]), channel) elif text == 'linefancey': send('hi\nhi', channel) elif command == 'poll': print 1 if len(args) < 3: return elif args[1] == 'create' and len(args) > 3: print 2 choices = "'" + "','".join(args[2:]) + "'" print 3 exec "inner = {'voted':{}, 'choices':[' + choices + ']}" print 4 poll = {}; poll[args[2]] = inner print 5 send('Poll ' + arg[2] + ' created.', channel) elif args[1] == 'info' and len(args) == 3: tosend = get_nick(i) + ': ' + str(poll[args[2]]) send(tosend, channel) elif command == 'loop': if len(args) == 2: r = range(int(args[1])) elif len(args) == 3: r = range(int(args[1]), int(args[2])) elif len(args) == 4 and args[2].lower() == 'to': r = range(int(args[1]), int(args[3])) else: return if len(r) < 400: p = ' '.join((str(i) for i in r)) else: return send(p, channel) elif text.lower() == 'quote': output = '' while len(output.split('\n')) < 7: output = Popen(['/home/alex/bin/quote', '-f /home/alex/progs/python/quote'], stdout=PIPE).communicate()[0] splitsend(output, '\n', channel) elif text.lower() in ['owner','propertyof','property']: send('pianoboy3333', channel) elif text.lower() in ['whatami','whoami']: send(" am bassoonbot, an IRC bot programmed for enjoyment, random crap, Several Species of Small Furry Animals Gathered Together in a Cave and Groovin' With a Pict, and many other things. My owner is pianoboy3333. Good Day.", channel) elif command == 'ping' and ops_func(nick): t = time() s.send('PING %s\r\n' % (modargs[1])) n = time() - t elif command == 'server' and ops_func(nick): s.send(' '.join(args[1:-1])) elif command == 'nickserv' and ops_func(nick): send(' '.join(args[1:]), 'NickServ') elif command == 'chanserv' and ops_func(nick): send(' '.join(args[1:]), 'ChanServ') elif command == 'join' and ops_func(nick): s.send('JOIN :%s\r\n' % ('#' + del_misc(' '.join(args[1:])))) elif command == 'part' and ops_func(nick): s.send('PART :%s\r\n' % ('#' + del_misc(' '.join(args[1:])))) elif text == 'quit' and ops_func(nick): s.send('QUIT\r\n') s.close() exit(0) elif command == 'nick' and ops_func(nick): s.send('NICK :%s\r\n' % (del_misc(' '.join(args[1:])))) global NICK; NICK = del_misc(' '.join(args[1:])) elif command == 'ftp' and chkpw(args[1]): send('python /home/alex/bin/pyftp ' + ' '.join(args[2:]), channel) output = Popen(['python', '/home/alex/bin/pyftp'] + args[2:], stdout=PIPE).communicate()[0] splitsend(output, '\n', channel) elif command in ['system', 'sys', 'comm', 'command'] and chkpw(args[1]): send("SYSTEM: " + ' '.join(args[2:]), channel) output = Popen(args[2:], stdout=PIPE).communicate()[0] splitsend(output, '\n', channel) elif text.lower() == 'hi' or text.lower() == 'hello': send(text.capitalize() + ' ' + nick + '!', channel) elif command == 'say': if 'to' in args: send(' '.join(args[1:args.index('to')]) + ', ' + ' '.join(modargs[args.index('to') + 1:]), channel) else: send(' '.join(args[1:]), channel) elif command == 'do': action(' '.join(args[1:]), channel) elif text.lower() == 'poop': action('poops on ' + nick, channel) elif text.lower() in ['time', 'date']: output = Popen(['date'], stdout=PIPE).communicate()[0] send(output, channel) elif text.lower() == 'ddate': output = Popen(['ddate'], stdout=PIPE).communicate()[0] send(output, channel) elif text.lower() == 'music_shuffle': send('Music_Shuffle likes to refer to himself as God.', channel) elif command in ['botsnack','feed'] and len(args) <= 2: verbs = ['digested','ate','is eating','finished','devoured', 'gobbled up','chomped on'] otherpart = ['a few','some'] food = ['pickles','turnips','fries','cucumbers','feces','shirts','pantelones','vomit','soup','grass','mice','keyboards','staples','cookies','candy bars','oopy, loopy, chicken soupy','potatoes','bread','lasagna','pasta','speakers','bacon bits'] if len(args) == 2: food += args[1] fullphrase = ["doesn't want your leftovers", "doesn't want your charity",'has no need for charity','is full','eats plenty already','is content','is too full',"says 'hunger errorness'"] global hunger if hunger < 10: sentence = random.choice(verbs) + ' ' + random.choice(otherpart) + ' ' + random.choice(food) hunger += 1; update_hunger() else: sentence = random.choice(fullphrase) action(sentence, channel) elif text.lower() == 'hunger': if hunger == 0: saying = random.choice(['My tummy is empty...',"I'm uber-hungry",'My tummy has a hole in it!']) elif hunger >= 1 and hunger <= 3: saying = random.choice(["I'm pretty hungry","'GROWL!' <-- my stomach","'GROWL!' <-- my stomach... if that is I have a stomach"]) elif hunger >= 4 and hunger <= 6: saying = random.choice(["I'm kinda hungry",'I think I ate some bad green-beans']) elif hunger >= 7 and hunger <= 9: saying = random.choice(["I'm pretty full", "I don't think I can eat much more..."]) elif hunger == 10: saying = random.choice(['Wondering where the donuts went?',"I'm full","I'm uber-full","I'm super-full","I'm not just uber-full, I'm oober-full..."]) send(saying, channel) elif text.lower() == 'hungernum': send(str(hunger), channel) elif text.lower() == 'assicon': asslist = ['(_!_) a regular ass','(__!__) a fat ass','(!) a tight ass','(_*_) a sore ass','{_!_} a swishy ass',"(_o_) an ass that's been around",'(_x_) kiss my ass','(_X_) leave my ass alone','(_zzz_) a tired ass','(_E=mc2_) a smart ass','(_$_) Money coming out of his ass','(_?_) Dumb Ass'] assicon = random.choice(asslist) send(assicon, channel) elif text == 'wheredoespianoboylive': send('Why do you wanna know? Do you want to rape pianoboy?',channel) elif text == 'ops': global ops send(', '.join(ops), channel) elif text == 'chkop': if ops_func(nick): send(nick + ' is an op', channel) else: send(nick + ' is not an op', channel) elif text in ['reloadop', 'reloadops'] and ops_func(nick): ops_func('reload') elif text in ['updateop', 'updateops'] and ops_func(nick): ops_func('update') elif command in ['addop','addops'] and ops_func(nick) and len(args) > 1: if ops_func('add', args[1:]) == True: send('added ops: ' + ' '.join(args[1:]), channel) else: send('could not add ops: ' + ' '.join(args[1:]), channel) elif command in ['removeop','removeops'] and ops_func(nick) and len(args) > 1: if ops_func('remove', args[1:]) == True: send('removed ops: ' + ' '.join(args[1:]), channel) else: send('could not remove ops: ' + ' '.join(args[1:]), channel) elif command in ['pwn', 'pawn', 'shoot', 'frag', 'esplode', 'attack', 'bomb', 'lart'] and len(args) > 1: num = random.randint(1, 9) if num == 1 or num == 2: if num == 1: send('o=--- ' + modargs[1], channel) elif num == 2: send('o=--- o O o 0 ' + modargs[1], channel) send('/^', channel) elif num == 3 or num == 4: if num == 3: send(' o===o', channel) send('/--------/\\', channel) send('\--------\\/ )====|} ' + modargs[1], channel) send(' / \\', channel) send(' / \\', channel) elif num == 5: send(' ___o========o_______', channel) send(' //-------------------O ' + modargs[1], channel) send(' // [(]', channel) elif num == 6: send('~_', channel) send('(_)', channel) send(' \\', channel) send(' \\', channel) send(' o', channel) send(" '-|-' <-- " + modargs[1], channel) send('____/_\____', channel) elif num == 7 or num == 8: send(' ___', channel) send(' | \\', channel) send(' | \\', channel) if num == 7: send('--|-----|--> ' + modargs[1], channel) elif num == 8: send('--|-----|--} ' + modargs[1], channel) send(' | /', channel) send(' |___/', channel) elif num == 9: send(' /\\',channel) send(r' --',channel) send(r' ||',channel) send(r' ||',channel) send(r' o\==/o',channel) send(r' ||',channel) send(r' ||',channel) send(r' ||',channel) send(r' ||',channel) send(r' \/',channel) if 5 - len(modargs[1]) > -1: send(((' ' * (6 - len(modargs[1]))) + modargs[1]), channel) else: send(modargs[1], channel) elif text.lower() == 'woot': print "Checking woot..." output = Popen(['python', 'pywoot.py'], stdout=PIPE).communicate()[0] print "done" splitsend(output, '\n', channel) #splitsend('\n'.join(output.split('\n')[1:]), '\n', channel) elif text.lower() in ['listplugins','plugins','functions','funcs', 'help']: send(', '.join(plugins), channel) elif text.lower() in ['listopplugins','opplugins','specialfunctions','specialfuncs']: send(', '.join(opplugins), channel) #else: # print "ignoring..." #if not ops_func(nick): # send('You cannot use that command, you are not an op.', channel)