Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import socket
- import string
- import urllib2
- import json
- import threading
- import time
- import random
- import select
- import re
- import quotelib
- import os
- import linecache
- from datetime import datetime, timedelta
- RAW_CHATTERS = 'http://tmi.twitch.tv/group/user/%s/chatters'
- STREAM_API = 'https://api.twitch.tv/kraken/channels/abahbob'
- WORLD_RECORDS_API = 'http://www.speedrun.com/api_records.php?game='
- HOST="irc.twitch.tv"
- PORT=6667
- OWNER="Abahbob"
- NICK="Abahbot"
- PASS="***"
- BOTMODS=["Abahbob", "stuff"]
- channelfile="channels.txt"
- userlists={}
- readbuffer=""
- listcount=0
- CHANNELS={}
- spamlimit=[0]
- RUN=[1]
- PING = [0]
- chan_rights = ""
- bot_rights = ""
- log = open("log.txt", "a+")
- threshold = 60
- is_alive = [0]
- t = ""
- stream_info = ""
- FAQs = ""
- FAQs = json.load(open('FAQs.json', 'r'))
- quotes = quotelib.quotelib("quotes.json")
- msg_count = 0
- msg_threshold = 0
- last_notif = 0
- notif_number = 0
- os.system ("echo '\e[0;32;40m'")
- class start_new_thread(threading.Thread):
- def __init__(self, callback, *args, **kwargs):
- threading.Thread.__init__(self)
- self.callback = lambda: callback(*args, **kwargs)
- self.start()
- def run(self):
- self.callback()
- def send_data(command):
- try:
- print "+ "+command
- s.send(command + "\r\n")
- except (socket.error, socket.timeout):
- print "- INFO - \"%s\" wasn't sent"
- def receive_data(command):
- print "- "+command
- def send_msg(chan, msg):
- send_data("PRIVMSG %s :%s" % (chan, msg))
- print "%s[%s] %s: %s" % (t, chan, NICK, msg)
- log.write("%s[%s] %s: %s\n" % (t, chan, NICK, msg))
- def parsemsg(s):
- prefix = ''
- trailing = []
- if s[0] == ':':
- prefix, s = s[1:].split(' ', 1)
- if s.find(' :') != -1:
- s, trailing = s.split(' :', 1)
- args = s.split()
- args.append(trailing)
- else:
- args = s.split()
- command = args.pop(0)
- return prefix, command, args
- def get_list(chan):
- while (chan in CHANNELS):
- try:
- data = urllib2.urlopen(RAW_CHATTERS % chan[1:])
- except:
- time.sleep(5)
- continue
- userlist = json.load(data)['chatters']
- userlists[hash(chan)] = userlist
- time.sleep(10)
- print "XXXX userlist update thread for %s is dead XXXX\n" % chan
- def update_chans(chans):
- f = open(channelfile, "w")
- for line in chans:
- f.write(line+"\n")
- f.close()
- def is_chatmod(chan, nick):
- if(nick in userlists[hash(chan)]["moderators"]):
- return 1
- return 0
- def is_mod(chan, nick):
- if(nick in userlists[hash(chan)]["moderators"]):
- return 1
- return is_botmod(nick)
- def is_viewer(chan, nick):
- if(nick in userlists[hash(chan)]["viewers"]):
- return 1
- return 0
- def is_botmod(nick):
- if(nick in BOTMODS):
- return 1
- return 0
- def is_owner(nick):
- if(nick.lower()==OWNER.lower()):
- return 1
- return 0
- def is_me(nick):
- if(nick.lower()==NICK.lower()):
- return 1
- return 0
- def make_chan(word):
- return word if (word[0] == "#") else "#" + word
- def make_not_chan(word):
- return word if (word[0] != "#") else word[1:]
- def bot(chan, nick, line):
- global stream_info, msg_count, last_notif, notif_number
- line = line.lower()
- msg = string.split(line, " ")
- msg_count+=1
- chan = chan.lower()
- nick = nick.lower()
- if(msg[0]=="!color" and is_botmod(nick) and len(msg) > 1):
- send_msg(chan, "/color %s" % msg[1])
- spamlimit[0] += 1
- elif(msg[0]=="!title"):
- send_msg(chan, stream_info["status"])
- spamlimit[0] += 1
- elif(msg[0]=="!game"):
- send_msg(chan, stream_info["game"])
- spamlimit[0] += 1
- elif(msg[0]=="!wr"):
- if(len(msg) <= 1):
- send_msg(chan, getWR(stream_info["game"], "Any%"))
- if(len(msg) == 2):
- send_msg(chan, getWR(stream_info["game"], msg[1]))
- if(len(msg) >= 3):
- count = 0
- game = ""
- for word in msg:
- if(count > 0 and count < len(msg) - 1):
- game += msg[count] + " "
- count += 1
- send_msg(chan, getWR(game, msg[-1]))
- elif(msg[0]=="!faq"):
- try:
- FAQ = FAQs[stream_info["game"]]
- send_msg(chan, stream_info["game"] + " FAQ: " + FAQ)
- except:
- title = str.lower(str(stream_info["status"]))
- if("%" in title or "speedrun" in title):
- send_msg(chan, "Speedrunning FAQ: " + FAQs["Speedrun"])
- elif(("glitch" in title) or ("break" in title)):
- send_msg(chan, "Glitch Hunting FAQ: " + FAQs["GlitchHunt"])
- spamlimit[0] += 1
- elif(msg[0]=="!pat"):
- nick = nick.rstrip("0123456789")
- if(is_owner(nick)):
- send_msg(chan, "%s-senpai <3" % OWNER)
- spamlimit[0] += 1
- elif(msg[0]=="!ask"):
- rng = random.randint(0,899)
- rng /= 100
- if(rng>=5):
- rng-=4
- if(rng == 1):
- send_msg(chan, "I suppose yes... but it's not like I agree or anything! Baka...")
- if(rng == 2):
- send_msg(chan, "Yes... I just happened to know the answer, it has nothing to do with you, o-okay!")
- if(rng == 3):
- send_msg(chan, "Yes. Consider yourself lucky that I answered you!")
- if(rng == 4):
- send_msg(chan, "Yes... probably... Not that I wanted to tell you b-baka!")
- elif(rng>=1):
- if(rng == 1):
- send_msg(chan, "No, now go die you freak")
- if(rng == 2):
- send_msg(chan, "N-No... okay!?")
- if(rng == 3):
- send_msg(chan, "No, not that I care or anything...")
- if(rng == 4):
- send_msg(chan, "It is no and it is obvious! Are you stupid %s?" % nick)
- else:
- send_msg(chan, "Why are you asking me, does it turn you on to ask a girl things like that? P-pervert!")
- spamlimit[0] += 1
- elif(msg[0]=="!shoot" and is_mod(chan, nick) and len(msg) >= 2):
- send_msg(chan, "/me fires a bullet at %s." % msg[1])
- send_msg(chan, "/timeout %s 1" % msg[1])
- spamlimit[0] += 1
- elif(msg[0]=="!shootrand" and is_mod(chan, nick)):
- if (len(userlists[hash(chan)]["viewers"]) > 0):
- rand = random.randint(0, len(userlists[hash(chan)]["viewers"]))
- if (rand == len(userlists[hash(chan)]["viewers"])):
- send_msg(chan, "/me fires a bullet randomly but fortunately nobody receives damage")
- else:
- user = userlists[hash(chan)]["viewers"][rand]
- send_msg(chan, "/me fires a bullet randomly and %s gets shot" % user)
- send_msg(chan, "/timeout %s 1" % user)
- spamlimit[0] += 1
- else:
- send_msg(chan, "There's nobody to shoot!")
- spamlimit[0] += 1
- elif(msg[0]=="!quote"):
- if len(msg) >= 3 and re.match("^\d*$",msg[2]):
- send_msg(chan, quotes.quote(msg[1], int(msg[2])))
- elif len(msg) >= 2:
- send_msg(chan, quotes.quote(msg[1]))
- else:
- send_msg(chan, quotes.quote())
- if(msg_count >= msg_threshold + random.randint(5, 10) and time.time() - last_notif > 1200):
- time.sleep(1)
- msg_count = 0
- last_notif = time.time()
- if(notif_number == 0):
- try:
- FAQ = FAQs[stream_info["game"]]
- send_msg(chan, stream_info["game"] + " FAQ: " + FAQ)
- except:
- title = str.lower(str(stream_info["status"]))
- if("%" in title or "speedrun" in title):
- send_msg(chan, "Speedrunning FAQ: " + FAQs["Speedrun"])
- elif(("glitch" in title) or ("break" in title)):
- send_msg(chan, "Glitch Hunting FAQ: " + FAQs["GlitchHunt"])
- notif_number += 1
- elif(notif_number == 1):
- send_msg(chan, "Like the stream? Be sure to follow!")
- notif_number = 0
- def getWR(game, category):
- try:
- url = (WORLD_RECORDS_API + game).replace(' ',"%20")
- result = json.load(urllib2.urlopen(url))
- times = result[result.keys()[0]]
- time = -1
- for key in times.keys():
- if(str.lower(category) in str.lower(str(key))):
- if(time == -1 or time > times[key]["time"]):
- important_time = times[key]
- cate = key
- time = int(times[key]["time"])
- return cate + " in " + str(timedelta(seconds=time)) + " by " + important_time["player"]
- except:
- return "Record not found"
- def cmd(chan, nick, line):
- line = line.lower()
- msg = string.split(line, " ")
- chan = chan.lower()
- nick = nick.lower()
- if(msg[0]=="!join" and is_botmod(nick) and len(msg) > 1):
- chan2 = make_chan(msg[1])
- if(not chan2 in CHANNELS):
- send_data("JOIN %s" % chan2)
- CHANNELS.append(chan2)
- update_chans(CHANNELS)
- start_new_thread(get_list,chan2)
- elif(msg[0]=="!quit" and is_botmod(nick) and ((chan!="#"+OWNER.lower() and chan!="#"+NICK.lower()) or len(msg)!=1)):
- if(len(msg) == 1):
- if(chan in CHANNELS):
- send_data("PART %s" % chan)
- CHANNELS.remove(chan)
- update_chans(CHANNELS)
- else:
- chan2 = make_chan(msg[1])
- if(chan2 in CHANNELS and chan2!="#"+OWNER.lower() and chan2!="#"+NICK.lower()):
- send_data("PART %s" % chan2)
- CHANNELS.remove(chan2)
- update_chans(CHANNELS)
- elif(msg[0]=="!list" and is_owner(nick)):
- if(len(msg) > 1):
- chan = make_chan(msg[1])
- if (chan in CHANNELS):
- print "staff:"
- print userlists[hash(chan)]["staff"]
- print "admins:"
- print userlists[hash(chan)]["admins"]
- print "moderators:"
- print userlists[hash(chan)]["moderators"]
- print "viewers:"
- print userlists[hash(chan)]["viewers"]
- elif(msg[0]=="!exit" and is_owner(nick)):
- for chan in CHANNELS:
- send_data("PART %s" % chan)
- while(len(CHANNELS) > 0):
- CHANNELS.pop()
- RUN[0] = 0
- log.close()
- send_data("QUIT leavin'~")
- sys.exit()
- elif(msg[0]=="!chans" and is_owner(nick)):
- print "channels:"
- for chans in CHANNELS:
- print " "+chans
- elif(msg[0]=="!test" and is_owner(nick)):
- send_data("WHO %s" % chan)
- def spam_block():
- while(RUN[0]):
- time.sleep(5)
- if(spamlimit[0] > 0):
- spamlimit[0] -= 1
- print "XXXX Spam block is dead XXXX\n"
- def update_info():
- global stream_info
- while 1:
- try:
- result = urllib2.urlopen(STREAM_API)
- stream_info = json.load(result)
- except urllib2.URLError, e:
- print("Error loading stream info")
- time.sleep(2)
- def check_connection ():
- while is_alive[0] == 0:
- continue
- connected = 1
- while (connected and is_alive[0]):
- time.sleep(60)
- ping_time = time.time()
- print "atashi no pingu~"
- try:
- s.send("PING tsundere\r\n")
- except (socket.error, socket.timeout):
- print "ping failed"
- break
- while (time.time() - ping_time < threshold and is_alive[0]):
- connected = 0
- if PING[0]:
- pong_time= time.time() - ping_time
- print "response time %fs" % pong_time
- PING[0] = 0
- connected = 1
- break
- connected = 0
- is_alive[0] = 0
- start_new_thread(check_connection)
- start_new_thread(spam_block)
- start_new_thread(update_info)
- with open(channelfile) as f:
- CHANNELS = f.read().splitlines()
- f.close()
- while is_alive[0] == 0:
- s=socket.socket()
- try:
- s.connect((HOST, PORT))
- send_data("PASS %s" % PASS)
- send_data("NICK %s" % NICK)
- send_data("USER %s 0 * :%s" % (NICK, OWNER))
- for chan in CHANNELS:
- send_data("JOIN %s" % chan)
- is_alive[0] = 1
- except (socket.error, socket.timeout):
- s.close()
- os.system ("echo '\e[0;37;44m'")
- print "++++++++++++++ connection failed, retrying in 5s"
- time.sleep(5)
- continue
- for chan in CHANNELS:
- start_new_thread(get_list, chan)
- os.system ("echo '\e[0;32;40m'")
- print "-------------- connected"
- t = datetime.now().strftime("%H:%M:%S on %B %d, %Y")
- print "session start at %s" % (t)
- #start_new_thread(check_connection)
- while 1:
- try:
- readbuffer=readbuffer+s.recv(1024)
- #if is_alive[0] == 0:
- #raise socket.timeout("missing pong")
- except (socket.error, socket.timeout):
- os.system ("echo '\e[0;37;44m'")
- readbuffer=""
- print "\n++++++++++++++ disconnected"
- s.close()
- print "-------------- reconnection"
- s=socket.socket()
- try:
- s.connect((HOST, PORT))
- send_data("PASS %s" % PASS)
- send_data("NICK %s" % NICK)
- send_data("USER %s 0 * :%s" % (NICK, OWNER))
- for chan in CHANNELS:
- send_data("JOIN %s" % chan)
- print "-------------- reconnected\n"
- #is_alive[0] = 1
- os.system ("echo '\e[0;32;40m'")
- except (socket.error, socket.timeout):
- print "++++++++++++++ reconnection failed retrying in 5s"
- time.sleep(5)
- continue
- continue
- except Exception, e:
- print e
- time.sleep(5)
- continue
- temp=string.split(readbuffer, "\r\n")
- readbuffer=temp.pop()
- t = datetime.now().strftime("[%H:%M:%S]")
- for line in temp:
- prefix, command, params = parsemsg(line)
- nick = string.split(prefix,"!")
- if(command=="PING"):
- print t
- print "anata no pingu~"
- data = params.pop(0)
- print "atashi no pongu~"
- try:
- s.send("PONG :%s\r\n" % data)
- except socket.error, socket.timeout:
- print "- INFO - \"atashi no pongu~\" wasn't sent"
- elif(command=="PONG"):
- print "anata no pongu~"
- #PING[0] = 1
- elif(command=="PRIVMSG"):
- chan = params.pop(0)
- msg = params.pop(0)
- msg = msg.rstrip()
- if (nick[0]!="jtv"):
- chan_rights = "@" if is_chatmod(chan, nick[0]) else ""
- bot_rights = "$" if is_botmod(nick[0]) else ""
- print "%s[%s] %s%s%s: %s" % (t, chan, bot_rights, chan_rights, nick[0], msg)
- log.write("%s[%s] %s%s%s: %s\n" % (t, chan, bot_rights, chan_rights, nick[0], msg))
- if(spamlimit[0] < 10):
- bot(chan, nick[0], msg)
- cmd(chan, nick[0], msg)
- elif(command=="JOIN"):
- chan = params.pop(0)
- print "%s joined [%s]" % (nick[0], chan)
- elif(command=="PART"):
- chan = params.pop(0)
- print "%s left [%s]" % (nick[0], chan)
- elif(command=="MODE"):
- chan = params.pop(0)
- nick = params.pop(1)
- mode = params.pop(0)
- print "[%s] gives %s to %s" % (chan, mode, nick)
- elif(command=="001"):
- print "welcome: %s" % params[1]
- elif(command=="002"):
- print "host: %s" % params[1]
- elif(command=="003"):
- print "creation date: %s" % params[1]
- elif(command=="004"):
- print "my info: %s" % params[1]
- elif(command=="375"):
- print "______________________________"
- print params[1]
- elif(command=="376"):
- print params[1]
- print "______________________________"
- elif(command=="372"):
- print "%s" % params[1]
- elif(command=="315"):
- print "end of /WHO for [%s]" % params[1]
- elif(command=="353"):
- print "receiving /NAMES for [%s]: %s" % (params[2],params[3])
- elif(command=="366"):
- print "end of /NAMES for [%s]" % params[1]
- elif(command=="421"):
- print "unknown command: %s" % params[1]
- else:
- receive_data(line)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement