import socket import re from random import randint, choice import sys, os import time import subprocess import tracery from tracery.modifiers import base_english import json import random DB = {} def grammar(rules): try: res = tracery.Grammar(rules) res.add_modifiers(base_english) return res except Exception as e: print(e) def load_rules(path): try: with open(path) as f: return json.loads(f.read()) except Exception as e: print(e) def populate(): global DB DB = {} for subdir in os.listdir("/home"): d = "/home/"+subdir+"/.tracery" if os.path.isdir(d): for p in os.listdir(d): rule = d+"/"+p name = p.replace(".json", "") #print(p, rule, name) if p in DB: DB[name].append(grammar(load_rules(rule))) else: DB[name] = [grammar(load_rules(rule))] populate() #print(DB) def generate(rule): populate() if rule in DB: g = random.choice(DB[rule]) return g.flatten("#origin#") def listify(col): if type(col) == type([]): return col else: return [col] def shuffle(col): a = random.choice(col.keys()) b = random.choice(col.keys()) if 'origin' in [a,b]: print("origin discard") return col temp = col[a] col[a] = col[b] col[b] = temp return col def fuse(argv): populate() raw = {} for gk in argv: if gk in DB: g = random.choice(DB[gk]).raw for k in g: if k in raw: raw[k] = listify(raw[k])+listify(g[k]) else: raw[k] = g[k] for i in range(20): raw = shuffle(raw) return grammar(raw).flatten("#origin#") server = "127.0.0.1" channels = [] if len(sys.argv) > 1: for c in sys.argv[1:]: channels.append("#"+c) botnick = "tracer" def ping(): ircsock.send("PONG :Pong\n") def joinchan(chan): ircsock.send("JOIN "+ chan +"\n") def sendmsg(chan , msg): # This is the send message function, it simply sends messages to the channel. ircsock.send("PRIVMSG "+ chan +" :"+ msg.encode("utf8") +"\n") def wexec(msg): ircsock.send("EXEC -msg "+channel+" "+msg) if __name__ == "__main__": ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock.connect((server, 6667)) # Here we connect to the server using port 6667 ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :tracery bot.\n") # user authentication ircsock.send("NICK "+ botnick +"\n") # here we actually assign the nick to the bot for c in channels: joinchan(c) def send(channel, s): sendmsg("#"+channel, s) def think(chan, nick, msg): words = re.split('[ \t\s]+', msg) if len(words) > 0 and nick != "tracer": if words[0] == "!!list": res = "" for k in DB: res += k+" " send(chan, res.encode("utf8")[:475]) elif words[0] == "!!fuse": if "|" in words: res = fuse(words[1:words.index("|")]) if res: send(chan, " ".join(words[words.index("|")+1:])+" "+res) else: res = fuse(words[1:]) if res: send(chan,res[0:475]) elif words[0][0:2] == "!!": print(words) res = generate(words[0][2:]) if res: if len(words) >= 3: if words[1] == "|": send(chan, " ".join(words[2:]) + " " + res) else: send(chan, res) else: send(chan, res) if __name__ == "__main__": while 1: ircmsg = ircsock.recv(2048) ircmsg = ircmsg.strip('\n\r') if ircmsg.find("PING") != -1: ping() m = re.match(':(?P[^ ]+)!.*PRIVMSG #(?P\w+) :(?P.*)', ircmsg) if m and m.groupdict(): m = m.groupdict() try: think(m["chan"], m["nick"], m["msg"]) except Exception as e: print "ERROR" + str(m) print(e)