IssacX

[Python] IRC Bot

May 4th, 2015
348
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.71 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import socket, string, ssl, time, os, random, hashlib, base64, urllib2, threading, re
  5.  
  6. wait = []
  7. wait2 = []
  8. kicks = []
  9. sock_lock = threading.Lock()
  10.  
  11. # Some functions
  12.  
  13. # Ping
  14. def ping():
  15.     s.send("PONG %s\n" % buffer.split(" ")[1])
  16.     print "<< PONG %s" % buffer.split(" ")[1]
  17.  
  18. # Split message
  19. def make():
  20.     try:
  21.         msg = buffer.split(":")
  22.         m_nick = msg[1].split(" ")[0].split("!")[0]
  23.         m_chan = msg[1].split(" ")[2]
  24.        
  25.         msg = ":".join(map(str,msg[2:]))
  26.         return (msg,m_nick,m_chan)
  27.     except:
  28.         none = False
  29.         return ("","","")
  30.  
  31. # Send message
  32. def say(c,m):
  33.     for n in range(len(notnice)):
  34.         m = m.replace(notnice[n],nice[n])
  35.     s.send("PRIVMSG %s :%s\n" % (c,m))
  36.     print "<< PRIVMSG %s :%s" % (c,m)
  37. # Send notice
  38. def notice(n,m):
  39.     s.send("NOTICE %s :%s\n" % (n,m))
  40.     print "<< NOTICE %s :%s" % (n,m)
  41.  
  42. # Wait system
  43. def add(u,c):
  44.     wait.append((u,c,time.time()))
  45.  
  46. def add2(u,c):
  47.     wait2.append((u,c,time.time()))
  48.    
  49. def check(u,c, SAY = True):
  50.     count = 0
  51.     count2 = 0
  52.     for i in wait:
  53.         if i[0] == u and time.time() - i[2] < 30 and i[1] == c and u not in adminlist:
  54.             count += 1
  55.         if i[0] == u and time.time() - i[2] < 180 and i[1] == c and u not in adminlist:
  56.             count2 += 1
  57.     if count == 3 or count2 == 10:
  58.         if u in ignorelist:
  59.             return False
  60.         if SAY:
  61.             say(c,"%s, Please wait a while" % u)
  62.         add(u,c)
  63.         return False
  64.     elif count > 3 or count2 > 10:
  65.         return False
  66.     else:
  67.         if u in ignorelist:
  68.             return False
  69.         else:
  70.             return True
  71.  
  72. def check2(u,c):
  73.     count = 0
  74.     count2 = 0
  75.     for i in wait2:
  76.         if i[0] == u and time.time() - i[2] < 7 and i[1] == c and u not in adminlist:
  77.             count += 1
  78.         if i[0] == u and time.time() - i[2] < 5 and i[1] == c and u not in adminlist:
  79.             count2 += 1
  80.     if count >= 10:
  81.         s.send("KICK %s %s :Anti spamming\n" % (c,u))
  82.         print "<< KICK %s %s :Anti spamming" % (c,u)
  83.     if count >= 6:
  84.         s.send("KICK %s %s :Anti spamming\n" % (c,u))
  85.         print "<< KICK %s %s :Anti spamming" % (c,u)
  86.  
  87. # Rejoin
  88. def rejoin(m):
  89.     try:
  90.         mkick = m.split(":")
  91.         k_nick = mkick[1].split(" ")[0].split("!")[0]
  92.         k_chan = mkick[1].split(" ")[2]
  93.         if mkick[1].split(" ")[1] == "KICK" and mkick[1].split(" ")[3] == "Qbot":
  94.             ret = True
  95.             for k in kicks:
  96.                 if k[0] == k_chan and time.time() - k[1] < 45:
  97.                     ret = False
  98.             if k_nick == "rChanBot":
  99.                 time.sleep(5)
  100.                 s.send("JOIN %s\n" % k_chan)
  101.                 print "<< JOIN %s" % k_chan
  102.             elif ret:
  103.                 time.sleep(5)
  104.                 s.send("JOIN %s\n" % k_chan)
  105.                 print "<< JOIN %s" % k_chan
  106.                 kicks.append([k_chan,time.time()])
  107.                 say(k_chan, k_nick + ", I'm just a bot with autorejoin. Please don't ban me. If you kick me again in 30 seconds, I won't bother you anymore")
  108.     except:
  109.         print "Hasn't been kicked"
  110.     print 8
  111.     return
  112.  
  113. def rejoin60(c):
  114.     time.sleep(60)
  115.     s.send("JOIN %s\n" % c)
  116.     print "<< JOIN %s" % c
  117.     return
  118.  
  119. # Clear requests & channel
  120. def clear_req():
  121.     while 1:
  122.         if len(wait) > 0:
  123.             for i in wait:
  124.                 if time.time() - i[2] > 240:
  125.                     del wait[wait.index(i)]
  126.         time.sleep(20)
  127.    
  128. def clear_chan():
  129.     while 1:
  130.         if len(wait2) > 0:
  131.             for i in wait2:
  132.                 if time.time() - i[2] > 15:
  133.                     del wait2[wait2.index(i)]
  134.         time.sleep(5)
  135.  
  136. # Update ignore list
  137. def update_ignore():
  138.     f = open("ignorelist.dat","w")
  139.     for i in ignorelist:
  140.         if i != "":
  141.             if i != ignorelist[-1]:
  142.                 f.write(i + "\n")
  143.             else:
  144.                 f.write(i)
  145.     f.close()
  146.  
  147. # Get link title
  148. def link_title(link,c):
  149.     try:
  150.         req = urllib2.Request(link)
  151.         req.add_header("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)")
  152.         page = urllib2.urlopen(req).read().replace("\n","").replace("\r","").replace("\t","")
  153.         #r = re.findall("<title>[\W]*(.+)[\W]*</title>",page,re.I)
  154.         page = re.sub("<title (.+)>","<title>",page,re.I)
  155.         page = page[(page.find("<title>") + 7):(page.find("</title>"))]
  156.         r = re.sub("[ ]{2,}"," ",page).strip(" ")
  157.         if len(r) > 0:
  158.             if len(r) <= 30:
  159.                 say(c, link + " -> " + r)
  160.             else:
  161.                 r2 = r.split(" ")
  162.                 r3 = ""
  163.                 for i in range(len(r2)):
  164.                     if len(r3 + " " + r2[i]) < 30:
  165.                         r3 += " " + r2[i]
  166.                     else:
  167.                         break
  168.                 if r3 == "":
  169.                     r = r[:30]
  170.                 else:
  171.                     r = r3
  172.                 r += "..."
  173.                 say(c, link + " -> " + r)
  174.         else:
  175.             say(c, "Error while getting title, maybe 404")
  176.     except:
  177.         say(c, "Error while getting page, maybe wrong server?")
  178.     return
  179.  
  180. if __name__ == "__main__":
  181.    
  182.     # Variable Definitions
  183.     host = "irc.land.yt"
  184.     port = 6667
  185.     nick = "IssacBot"
  186.     username = "IssacBot"
  187.     realname = "IssacBotBot"
  188.     channels = "#lizardlounge"
  189.     buffer = ""
  190.     msg = ""
  191.     m_nick = ""
  192.     m_chan = ""
  193.     conn = False
  194.     help = "$say, $help, $credits, $joke, $hash, $b64en, $b64de, $urlen, $urlde, [$search|$s], [$link|$l]"
  195.     admin_help = "$join, $leave, $restart, $welcome, $ignore, $chansay"
  196.     antispamchans = ["#sd","#linux"]
  197.     notnice = ["retard","gay","הומו","כוסעמק","גיי ","בן זונה","מוצצת","כוסאמא","זונה","סעמק","זין","אידיוט","מפגר","מטומטם","motherfucker","בןזונה","בנזונה","fag","fuck","retart","faggot","bitch","nigger","bastard","g a y","b i t c h","f u c k","r e t a r d","b a s t a r d","n i g g e r","כוס עמק","ינעל","STFU","גייז ","זונות"]
  198.     nice = ["r*tard","g*y","ה*מו","כ*סעמק","ג*י ","בן ז*נה","מו**ת","כ*סאמא","ז*נה","ס*מק","ז*ן","אחד*ןו","מפ*ר","מטומ*ם","motherf*cker","בןז*נה","בנז*נה","f*g","f*ck","rest*rt","f*ggot","b*tch","n*gger","b*stard", "g * y","b * t c h","f * c k","r * t a r d","b * s t a r d","n * g g e r","כ*ס עמק","ינ*ל","ST*U","גי*ז ","ז*נות"]
  199.     logchans = ["#security"]
  200.     adminlist = ("Qazjap11","Q11","Q[BRB]")
  201.    
  202.     #f = open("ignorelist.dat","r")
  203.     #ignorelist = f.readlines()
  204.     #f.close()
  205.     #for i in ignorelist:
  206.         #if i == "":
  207.             #del ignorelist[ignorelist.index(i)]
  208.         #if i[-1] == '\n':
  209.             #ignorelist[ignorelist.index(i)] = i[:-1]
  210.    
  211.     # Load Jokes
  212.    
  213.     #randj = random.randint(1,130)
  214.     #f = open("jokes/jokes-" + str(randj) + ".dat")
  215.     #jokes = f.readlines()
  216.     #f.close()
  217.    
  218.     #print "Jokes #%d loaded!" % randj
  219.    
  220.     # Connecting
  221.     while not conn:
  222.         try:
  223.             print "Connecting %s:%d..." % (host,port)
  224.             sa = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  225.             sa.connect((host,port))
  226.             s = ssl.wrap_socket(sa)
  227.             conn = True
  228.         except:
  229.             try:
  230.                 s.close()
  231.                 sa.close()
  232.             except:
  233.                 print "No connection..."
  234.             print "Connection errors"
  235.             conn = False
  236.             time.sleep(3)
  237.     print "Connected %s:%d!" % (host,port)
  238.            
  239.     # Join
  240.     s.send("USER %s %s bla :%s\n" % (username,host,realname))
  241.     print "<< USER %s %s bla :%s" % (username,host,realname)
  242.     s.send("NICK %s\n" % nick)
  243.     print "<< NICK %s" % nick
  244.     buffer = s.recv(4096)
  245.     if buffer.find("PING :") != -1:
  246.         print ">> " + buffer
  247.         ping()
  248.     else:
  249.         print "Didn't recieve ping"
  250.     s.send("PRIVMSG NICKSERV :IDENTIFY **********\n")
  251.     print "<< PRIVMSG NICKSERV :IDENTIFY **********"
  252.    
  253.     time.sleep(2)
  254.     s.send("JOIN %s\n" % channels)
  255.     print "<< JOIN %s" % channels
  256.    
  257.     t = threading.Thread(target=clear_req)
  258.     t.start()
  259.     t = threading.Thread(target=clear_chan)
  260.     t.start()
  261.    
  262.     # Gratz
  263.     #s.send("PRIVMSG %s :%s\n" % (channels, "Hi! I'm Q11's bot! Type $help to see my commands"))
  264.     #print "<< PRIVMSG %s :%s" % (channels, "Hi! I'm Q11's bot! Type $help to see my commands")
  265.    
  266.     # Listen
  267.     while 1:
  268.         try:
  269.             buffer = s.recv(4096)
  270.             buffer = buffer.strip('\n\r')
  271.             (msg,m_nick,m_chan) = make()
  272.             smsg = msg.split(" ")
  273.             if buffer != "":
  274.                 print ">> " + buffer
  275.         except KeyboardInterrupt:
  276.             s.send("QUIT :Qbot\n")
  277.             print "<< QUIT :Qbot"
  278.             exit()
  279.        
  280.         # Reply pings
  281.            
  282.         if buffer.find("PING :") != -1:
  283.             ping()
  284.            
  285.         # Anti spamming mode
  286.        
  287.         if m_chan in antispamchans:
  288.             add2(m_nick,m_chan)
  289.             check2(m_nick,m_chan)
  290.        
  291.         # Commands
  292.        
  293.         if msg == "$say":
  294.             if check(m_nick, m_chan):
  295.                 say(m_chan, "Hi! I'm Q11's bot! Type $help to see my commands")
  296.                 add(m_nick, m_chan)
  297.        
  298.         if msg == "$credits":
  299.             if check(m_nick, m_chan):
  300.                 notice(m_nick, "Bot by Qazjap11!")
  301.                 add(m_nick, m_chan)
  302.        
  303.         if msg == "$help" and m_nick not in adminlist:
  304.             if check(m_nick, m_chan):
  305.                 notice(m_nick, help)
  306.                 add(m_nick, m_chan)
  307.        
  308.         if msg == "$help" and m_nick in adminlist:
  309.             notice(m_nick, help + ", " + admin_help)
  310.        
  311.         if smsg[0] == "$say" and len(smsg) > 1 and smsg[1] != "":
  312.             tmp = smsg[1:]
  313.             if check(m_nick, m_chan):
  314.                 say(m_chan, " ".join(map(str,tmp)))
  315.                 add(m_nick, m_chan)
  316.         if smsg[0] == "$chansay" and len(smsg) > 2 and smsg[1] != "" and smsg[2] != "" and m_nick in adminlist:
  317.             tmp = smsg[2:]
  318.             say(smsg[1], " ".join(map(str,tmp)))
  319.         if smsg[0] == "$b64en" and len(smsg) > 1 and smsg[1] != "":
  320.             tmp = smsg[1:]
  321.             tmp = " ".join(map(str,tmp))
  322.             if check(m_nick, m_chan):
  323.                 say(m_chan, "base64_encode('" + tmp + "') = " + base64.b64encode(tmp))
  324.                 add(m_nick, m_chan)
  325.         if smsg[0] == "$b64de" and len(smsg) == 2 and smsg[1] != "":
  326.             if check(m_nick, m_chan):
  327.                 try:
  328.                     say(m_chan, "base64_decode('" + smsg[1] + "') = " + base64.b64decode(smsg[1]))
  329.                 except:
  330.                     say(m_chan, "Invalid message")
  331.                 add(m_nick, m_chan)
  332.         if smsg[0] == "$urlen" and len(smsg) > 1 and smsg[1] != "":
  333.             tmp = smsg[1:]
  334.             tmp = " ".join(map(str,tmp))
  335.             if check(m_nick, m_chan):
  336.                 say(m_chan, urllib2.quote(tmp))
  337.                 add(m_nick, m_chan)
  338.         if smsg[0] == "$urlde" and len(smsg) == 2 and smsg[1] != "":
  339.             if check(m_nick, m_chan):
  340.                 say(m_chan, urllib2.unquote(smsg[1]))
  341.                 add(m_nick, m_chan)
  342.         if (smsg[0] == "$link" or smsg[0] == "$l") and len(smsg) >= 2 and smsg[1] != "" and re.search("^(http|https)://(www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,4}(\.[a-zA-Z]{2,4})?(:[\d]{1,5})?(.*)$",smsg[1]):
  343.             if check(m_nick, m_chan):
  344.                 t = threading.Thread(target=link_title,args=(smsg[1],m_chan))  
  345.                 t.start()
  346.                 add(m_nick, m_chan)
  347.         if (smsg[0] == "$link" or smsg[0] == "$l") and (len(smsg) < 2 or not re.search("^(http|https)://(www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,4}(\.[a-zA-Z]{2,4})?(:[\d]{1,5})?(.*)$",smsg[1])):
  348.             if check(m_nick, m_chan):
  349.                 say(m_chan, "Usage: [$l|$link] URL")
  350.                 add(m_nick, m_chan)
  351.         if smsg[0] == "$join" and len (smsg) == 2 and m_nick in adminlist:
  352.             s.send("JOIN %s\n" % smsg[1])
  353.             print "<< JOIN %s" % smsg[1]
  354.         if msg == "$leave" and m_nick in adminlist:
  355.             s.send("PART %s\n" % m_chan)
  356.             print "<< PART %s" % m_chan
  357.         if smsg[0] == "$leave" and len (smsg) == 2 and m_nick in adminlist:
  358.             s.send("PART %s\n" % smsg[1])
  359.             print "<< PART %s" % smsg[1]
  360.         if smsg[0] == "$welcome" and len (smsg) >= 2 and m_nick in adminlist:
  361.             notice(smsg[1], "Hi " + smsg[1] + "! I'm Q11's bot! Type $help to see my commands")
  362.         if msg == "$restart" and m_nick in adminlist:
  363.             s.send("QUIT :Restarting\n")
  364.             print "<< QUIT :Restarting"
  365.             os.system("killall -9 python && ./irc.py")
  366.             exit()
  367.         if smsg[0] == "$ignore" and len (smsg) > 1 and m_nick in adminlist:
  368.             if smsg[1] == "add":
  369.                 if smsg[2] in ignorelist:
  370.                     notice(m_nick, smsg[2] + " is already in ignore list")
  371.                 else:
  372.                     ignorelist.append(smsg[2])
  373.                     update_ignore()
  374.                     notice(m_nick, smsg[2] + " added to ignore list")
  375.             elif smsg[1] == "remove":
  376.                 if smsg[2] not in ignorelist:
  377.                     notice(m_nick, smsg[2] + " is not in ignore list")
  378.                 else:
  379.                     del ignorelist[ignorelist.index(smsg[2])]
  380.                     update_ignore()
  381.                     notice(m_nick, smsg[2] + " removed from ignore list")
  382.             elif smsg[1] == "list":
  383.                 for i in ignorelist:
  384.                     if i != ignorelist[0]:
  385.                         ms += ", " + i
  386.                     else:
  387.                         ms = i
  388.                 notice(m_nick, "Ignore list: " + ms)
  389.             else:
  390.                 notice(m_nick, "Usage: $ignore [add|remove|list] [nick]")  
  391.         if smsg[0] == "$ignore" and len (smsg) == 1 and m_nick in adminlist:
  392.             notice(m_nick, "Usage: $ignore [add|remove|list] [nick]")
  393.         if msg == "$joke":
  394.             if check(m_nick, m_chan):
  395.                 joke = random.choice(jokes)
  396.                 if len(joke) < 450:
  397.                     say(m_chan, joke)
  398.                 else:
  399.                     joke2 = joke.split(" ")
  400.                     joke = ""
  401.                     for i in range(len(joke2)):
  402.                         if len(joke + " " + joke2[i]) < 450:
  403.                             joke += " " + joke2[i]
  404.                         else:
  405.                             break
  406.                    
  407.                     say(m_chan, joke)
  408.                     say(m_chan, " ".join(map(str,joke2[i:])))
  409.                 add(m_nick, m_chan)
  410.         if smsg[0] == "$hash":
  411.             if check(m_nick, m_chan):
  412.                 if len(smsg) > 2:
  413.                     tmp = smsg[2:]
  414.                     tmp = " ".join(map(str,tmp))
  415.                     if len(tmp) > 32:
  416.                         say(m_chan,"Message must be below 32 char long")
  417.                     else:
  418.                         if smsg[1] == "md5":
  419.                             m = hashlib.md5()
  420.                             m.update(tmp)
  421.                             say(m_chan, "md5('" + tmp + "') = " + m.hexdigest())
  422.                         elif smsg[1] == "sha1":
  423.                             m = hashlib.sha1()
  424.                             m.update(tmp)
  425.                             say(m_chan, "sha1('" + tmp + "') = " + m.hexdigest())
  426.                         elif smsg[1] == "sha224":
  427.                             m = hashlib.sha224()
  428.                             m.update(tmp)
  429.                             say(m_chan, "sha224('" + tmp + "') = " + m.hexdigest())
  430.                         elif smsg[1] == "sha384":
  431.                             m = hashlib.sha384()
  432.                             m.update(tmp)
  433.                             say(m_chan, "sha384('" + tmp + "') = " + m.hexdigest())
  434.                         elif smsg[1] == "sha512":
  435.                             m = hashlib.sha512()
  436.                             m.update(tmp)
  437.                             say(m_chan, "sha512('" + tmp + "') = " + m.hexdigest())
  438.                         else:
  439.                             say(m_chan, "Usage: $hash [md5|sha1|sha224|sha384|sha512] message")
  440.                 else:
  441.                     say(m_chan, "Usage: $hash [md5|sha1|sha224|sha384|sha512] message")
  442.                 add(m_nick, m_chan)
  443.        
  444.         if (smsg[0] == "$search" or smsg[0] == "$s") and len(smsg) > 1:
  445.             if check(m_nick, m_chan):
  446.                 if m_chan in logchans:
  447.                     tmp = smsg[1:]
  448.                     tmp = " ".join(map(str,tmp))
  449.                     logs = os.popen("tail -n 200 ~/.xchat2/xchatlogs/Nix-" + m_chan + ".log | grep \\<.*\\>").read()
  450.                     logs = logs.split("\n")
  451.                     logs_fin = []
  452.                     for log in logs:
  453.                         if log.find(tmp) != -1:
  454.                             logs_fin.append(log)
  455.                     if len(logs_fin) > 4:
  456.                         logs_fin = logs_fin[-4:-1]
  457.                     else:
  458.                         logs_fin = logs_fin[:-1]
  459.                     if len(logs_fin) > 0:
  460.                         for log in logs_fin:
  461.                             say(m_chan, log)
  462.                     else:
  463.                         say(m_chan, "%s, No matches found in last 200 lines" % m_nick)
  464.                    
  465.                 else:
  466.                     say(m_chan, "Log search isn't available in this channel");
  467.                 add(m_nick, m_chan)
  468.        
  469.         #for m in notnice:
  470.         #   if msg.lower().find(m.lower()) != -1:
  471.         #       if check(m_nick, m_chan, False):
  472.         #           say(m_chan, "%s, לא יפה לקלל" % m_nick);
  473.         #           add(m_nick, m_chan)
  474.         #           break
  475.        
  476.         if buffer.find("KICK") != -1:
  477.             t = threading.Thread(target=rejoin,args=(buffer,)) 
  478.             t.start()
  479.         if buffer.find("500") != -1:
  480.             try:
  481.                 m_rejoin = buffer.split(":")
  482.                 if m_rejoin[1].split(" ")[0] == "maia.nix.co.il" and m_rejoin[1].split(" ")[1] == "500" and m_rejoin[1].split(" ")[2] == "Qbot":
  483.                     t = threading.Thread(target=rejoin60,args=(m_rejoin[1].split(" ")[3],))
  484.                     t.start()
  485.             except:
  486.                 print "No rejoin"
Add Comment
Please, Sign In to add comment