mixster

mixster

Jul 6th, 2010
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.26 KB | None | 0 0
  1. #!/usr/bin/python
  2. import sys, socket, time, threading, random, MySQLdb
  3.  
  4. class ERR:
  5.     NOCON = -1
  6.     NODAT = -2
  7.     NOHAN = -3
  8.  
  9. class IRCCon:
  10.     data = []
  11.     connected = False
  12.  
  13. class Message:
  14.     nick = ''
  15.     real = ''
  16.     host = ''
  17.     param = []
  18.     trail = []
  19.  
  20.     def __init__(self, data):
  21.         print "<<" + data
  22.  
  23.         if data[0] == ":":
  24.             data = data[1:]
  25.             t = data.find(" ")
  26.             prefix = data[:t]
  27.             data = data[t+1:]
  28.             temp = prefix.partition("@")
  29.             self.host = temp[2]
  30.             temp = temp[0].partition("!")
  31.             self.nick, self.real = temp[0], temp[2]
  32.         else:
  33.             self.nick, self.real, self.host = "", "", ""
  34.  
  35.         pe = data.find(" :")
  36.         if pe != -1:
  37.             self.trail = data[pe + 2:].split(" ")
  38.             self.param = data[:pe].split(" ")
  39.         else:
  40.             self.trail = []
  41.             self.param = data.split(" ")
  42.  
  43.  
  44. class IRCReader(threading.Thread):
  45.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  46.     con = IRCCon()
  47.  
  48.     def __init__(self, server, nick, port=6667, real=None, passw=None, auth="ABC123"):
  49.         self.sock.connect((server, port))
  50.         self.con.connected = True
  51.         self.nick = nick
  52.         self.auth = auth
  53.  
  54.         if passw != None:
  55.             self.send("PASS " + passw)
  56.         if real == None:
  57.             real = nick
  58.  
  59.         self.send("NICK " + nick)
  60.         self.send("USER " + nick + " 0 0 :" + real)
  61.  
  62.         self.act = {
  63.         "CTCP" : lambda x: self.send("PRIVMSG " + x.nick + " :" + chr(1) + " ".join(x.trail[1:]) + chr(1)),
  64.         "QUIT": lambda x: self.send("QUIT :" + " ".join(x.trail[1:])),
  65.         "RAW": lambda x: self.send(" ".join(x.trail[1:]))
  66.         }
  67.  
  68.         self.ntc = {}
  69.  
  70.         self.ctcp = {
  71.         "PING": lambda x: self.send("NOTICE " + x.nick + " :" + chr(1) + "PING " + " ".join(x.trail[1:]) + chr(1)),
  72.         "VERSION": lambda x: self.send("NOTICE " + x.nick + " :" + chr(1) + "VERSION Python Markov Chain Chatbot v3.0" + chr(1)),
  73.         "TIME": lambda x: self.send("NOTICE " + x.nick + " :" + chr(1) + "TIME " + time.strftime("%a %b %d %H:%M:%S %Y") + chr(1))
  74.         }
  75.  
  76.         self.cmd = {
  77.         "PING": lambda x: self.send("PONG " + x.trail[0]),
  78.         "NOTICE": lambda x: self.ntc.get(x.trail[0].upper(), lambda x: ERR.NOHAN)(x),
  79.         "PRIVMSG": self.checkPrivmsg,
  80.         "ERROR": lambda x: self.setClosed()
  81.         }
  82.  
  83.         threading.Thread.__init__(self)
  84.  
  85.     def run(self):
  86.         while self.con.connected:
  87.             data = self.sock.recv(512)
  88.             while data[-2:] != "\r\n":
  89.                 data += self.sock.recv(64)
  90.             data = data.split("\r\n")
  91.  
  92.             for line in data:
  93.                 tmp = self.parse(line)
  94.                 if tmp == ERR.NODAT:
  95.                     continue
  96.                 res = self.handle(tmp)
  97.                 if res == ERR.NOHAN:
  98.                     self.con.data.append(tmp)
  99.  
  100.         self.sock.close()
  101.  
  102.     def setClosed(self):
  103.         self.con.connected = False
  104.  
  105.     def parse(self, data):
  106.         if len(data) == 0:
  107.             return ERR.NODAT
  108.      
  109.         tmp = Message(data)
  110.  
  111.         print "(" + ",".join([tmp.nick, tmp.real, tmp.host]) + ")::" + "|".join(tmp.param) + "[" + str(len(tmp.param)) + "]::" + " ".join(tmp.trail)
  112.  
  113.         return tmp
  114.  
  115.  
  116.     def checkPrivmsg(self, data):
  117.         if len(data.trail) == 0:
  118.             return ERR.NOHAN
  119.  
  120.         elif data.param[1] == self.nick:
  121.             if data.trail[0].startswith(chr(1)) and data.trail[-1].endswith(chr(1)):
  122.                 data.trail[0] = data.trail[0].lstrip(chr(1))
  123.                 data.trail[-1] = data.trail[-1].rstrip(chr(1))
  124.                 return self.ctcp.get(data.trail[0].upper(), lambda x: ERR.NOHAN)(data)
  125.             elif ((len(data.trail) > 1) and (data.trail[0] == self.auth)):
  126.                 del data.trail[0]
  127.                 return self.act.get(data.trail[0].upper(), lambda x: ERR.NOHAN)(data)
  128.             else:
  129.                 return ERR.NOHAN
  130.         else:
  131.             return ERR.NOHAN
  132.  
  133.  
  134.     def handle(self, data):
  135.         return self.cmd.get(data.param[0].upper(), lambda x: ERR.NOHAN)(data)
  136.  
  137.     def send(self, data):
  138.         if not self.con.connected:
  139.             return ERR.NOCON
  140.  
  141.         print ">>" + data
  142.         sent = self.sock.send(data + "\n")
  143.         data = data[sent:]
  144.         while (len(data) != 0) and (self.con.connected):
  145.             sent = self.sock.send(data + "\n")
  146.             data = data[sent:]
  147.  
  148.         return 0
  149.  
  150.     def formatPriv(self, data, text):
  151.         if self.nick == data.param[1]:
  152.             return "PRIVMSG " + data.nick + " :" + text
  153.         else:
  154.             return "PRIVMSG " + data.param[1] + " :" + text
  155.  
  156.  
  157. class IRCProcessor:
  158.     def __init__(self, server, nick, port=6667, real=None, passw=None, auth="ABC123"):
  159.         self.reader = IRCReader(server, nick, port, real, passw, auth)
  160.         self.con = self.reader.con
  161.         self.send = self.reader.send
  162.         self.formatPriv = self.reader.formatPriv
  163.         self.reader.start()
  164.  
  165.         self.ntc = {}
  166.  
  167.         self.act = {
  168.         "REPLY": lambda x: self.send(self.formatPriv(x, generateReply(x.trail[1:]))),
  169.         "PING" : lambda x: self.send(self.formatPriv(x, "pong!"))
  170.         }
  171.  
  172.         self.cmd = {
  173.         "NOTICE": lambda x: self.ntc.get(x.trail[0].upper(), lambda x: ERR.NOHAN)(x),
  174.         "PRIVMSG": self.checkPrivmsg
  175.         }
  176.  
  177.     def read(self):
  178.         if len(self.con.data) == 0:
  179.             return ERR.NODAT
  180.         return self.con.data.pop(0)
  181.  
  182.     def handle(self, data):
  183.         return self.cmd.get(data.param[0].upper(), lambda x: ERR.NOHAN)(data)
  184.  
  185.     def checkPrivmsg(self, data):
  186.         if len(data.trail) == 0:
  187.             return ERR.NOHAN
  188.  
  189.         if data.trail[0].startswith(self.reader.nick):
  190.             if len(data.trail[0]) != len(self.reader.nick):
  191.                 if data.trail[0][len(self.reader.nick)+1:].isalnum():
  192.                     return ERR.NOHAN
  193.  
  194.             del data.trail[0]
  195.         elif data.param[1] == self.reader.nick:
  196.             pass
  197.         else:
  198.             return ERR.NOHAN
  199.  
  200.        
  201.         return self.act.get(data.trail[0].upper(), lambda x: ERR.NOHAN)(data)
  202.  
  203.  
  204. def generateReply(seed):
  205.     t = time.clock()
  206.  
  207.     db = MySQLdb.connect("localhost", "user", "pass", "wordsdb")
  208.     c = db.cursor()
  209.  
  210.     if type(seed) == type(list()):
  211.         if len(seed) == 0:
  212.             c.execute("SELECT wid FROM sentences WHERE sentences.pid=0 ORDER BY rand() LIMIT 1")
  213.             inp = c.fetchone()
  214.             c.execute("SELECT word FROM words WHERE id=%s", (inp[0],))
  215.             inp = c.fetchone()
  216.             seed = inp[0]
  217.         else:
  218.             seed = random.choice(seed)
  219.  
  220.     inp = seed.lower()
  221.     sentence = [inp]
  222.  
  223.     c.execute("SELECT id FROM words WHERE word=%s", (inp, ))
  224.     inp = c.fetchone()
  225.  
  226.     if inp != None:
  227.         pid = [inp[0]]
  228.  
  229.         c.execute("SELECT curw.word, curw.id FROM words curw, sentences curs, sentences pres WHERE pres.wid=%s AND curs.pid=pres.id AND curw.id=curs.wid ORDER BY rand() LIMIT 1", (pid[0], ))
  230.         inp = c.fetchone()
  231.  
  232.         if inp != None:
  233.             sentence.append(inp[0])
  234.             pid.append(inp[1])
  235.  
  236.     while inp != None:
  237.         c.execute("SELECT curw.word, curw.id FROM words curw, sentences curs, sentences pres, sentences pres2 WHERE pres.wid=%s AND pres2.wid=%s AND curs.pid=pres.id AND pres.pid=pres2.id AND curw.id=curs.wid ORDER BY RAND() LIMIT 1", (pid[-1], pid[-2], ))
  238.  
  239.         inp = c.fetchone()
  240.         if inp != None:
  241.             sentence.append(inp[0])
  242.             pid.append(inp[1])
  243.  
  244.     t = time.clock() - t
  245.     if t > 0:
  246.         print "generateReply() took " + str(t) + " seconds to produce a sentence of " + str(len(sentence)) + " words (" + str((len(sentence) - 1) / t) + " wps)"
  247.     else:
  248.         print "generateReply() took " + str(t) + " seconds to produce a sentence of " + str(len(sentence)) + " words"
  249.  
  250.     return " ".join(sentence)
  251.  
  252.  
  253. random.seed()
  254. irccon = IRCProcessor("irc.rizon.net", "sillybot", auth="ABC123")
  255. irccon.send("JOIN #mixster")
  256. while irccon.con.connected:
  257.     inp = irccon.read()
  258.     if inp != ERR.NODAT:
  259.         irccon.handle(inp)
  260.     else:
  261.         time.sleep(0.025)
  262. print "Terminating!"
Add Comment
Please, Sign In to add comment