about summary refs log blame commit diff
path: root/tracer.py
blob: 8b34a9e668c1a84b165fe2132b6f5ff850cfc6b5 (plain) (tree)
1
2

                      































                                          
                                      










                                                              
         









































                                                          
                    




                              


                                       

                   
                           
 


                                                                                 
 

                                               

                     
                             







                                           
                                 





















                                                                            







                                                                                   

                                   

                                              

                                     




                                             






                                                                                      
                                       
                        
 
#!/usr/bin/env python3

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 = f"/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 = ["#bots"]
if len(sys.argv) > 1:
    for c in sys.argv[1:]:
        channels.append("#"+c)
botnick = "tracer"

def rawsend(msg):
    print(msg)
    ircsock.send(f"{msg}\r\n".encode())

def joinchan(chan):
    rawsend(f"JOIN {chan}")

def sendmsg(chan, msg): 
    # This is the send message function, it simply sends messages to the channel.
    rawsend(f"PRIVMSG {chan} :{msg}")

# def wexec(msg):
#    ircsock.send("EXEC -msg "+channel+" "+msg)

def send(channel, s):
    sendmsg(f"#{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[: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__":
    ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ircsock.connect((server, 6667)) # Here we connect to the server using port 6667
    rawsend(f"NICK {botnick}") # here we actually assign the nick to the bot
    rawsend(f"USER {botnick} 0 * :tracery bot") # user authentication

    for c in channels:
        joinchan(c)

    while 1:
        ircmsg = ircsock.recv(2048)
        ircmsg = ircmsg.decode().strip('\n\r')
        print(ircmsg)

        if ircmsg.find("PING") != -1:
            rawsend(ircmsg.replace("I", "O"))

        if ircmsg.find("001") != -1:
            for c in channels:
                joinchan(c)

        m = re.match(':(?P<nick>[^ ]+)!.*PRIVMSG #(?P<chan>\w+) :(?P<msg>.*)', 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)