#!/bin/env python
import socket
from sys import argv, stderr, exit
import os
from time import sleep
lastmsg = 0
sok = None
isok = None
osok = None
argv0 = "bot.py"
def usage():
global argv0
print(f"usage: {argv0} HOST PORT", file=stderr)
print(file=stderr)
print("'advanced' 'AI' for nanochat", file=stderr)
exit(-1)
### "AI" ###
def split_list(words, pwords):
terms = []
acc = []
for i in range(len(words)):
if len(acc) == 0 and pwords[i] in ('and', 'or'):
continue
if words[i][-1] == ',':
acc.append(words[i].rstrip(','))
terms.append(acc)
acc = []
else:
acc.append(words[i])
if len(acc) != 0:
terms.append(acc)
return terms
def strip_direct_address(name, special, words, pwords):
if name not in pwords:
return False
# ignore an initial greeting
if pwords[0] in ['hey', 'oh', 'yo', 'ok', 'okay']:
idx = 1
else:
idx = 0
# "bot, hi"
if pwords[idx] == name and words[idx][-1] in ',:':
# strip direct address and greeting
for _ in range(idx+1):
words.pop(0)
pwords.pop(0)
return True
# lol
if len(words) < 2:
words.pop()
pwords.pop()
return True
if len(words) == True and words[-2] in special:
words.pop()
pwords.pop()
return True
# trailing address
if pwords[-1] == name and words[-2][-1] == ',':
words.pop()
pwords.pop()
words[-1] = words[-1].lstrip(',') # strip comma
return True
return False
def handle_line(line, name, msgfn, actfn):
# we assume nobody's nick is longer than 20 chars, to
# hopefully avoid picking up actions that include colons.
# this may need tweaking!
try:
colon_pos = line.index(':', 0, 20)
except:
colon_pos = len(line)
if colon_pos+1 >= len(line):
words, pwords = parse_words(line)
if len(words) > 0:
actfn(line, words, pwords)
else:
nick, line = line.split(':', 1)
if line.startswith('/') or nick.endswith('http') or nick.endswith('https'):
return # picked up a URL by accident
if nick == name:
return
words, pwords = parse_words(line)
if len(words) >= 2:
msgfn(nick, line, words, pwords)
def parse_words(line):
words = [*filter(lambda x: x, line.split(' '))]
pwords = [word.rstrip(',!.:~?') for word in words] # [n]ormalized words
return words, pwords
### NETCODE ###
def readln():
global isok
return isok.readline().decode('latin-1', errors='replace').strip()
def readk():
return int(readln())
def writeln(line):
global osok
osok.write(f"{line}\n")
osok.flush()
def send(msg):
writeln(f"SEND {msg}")
return readk()
def readmany():
global lastmsg
ret = []
k = readk()
for i in range(k):
ret.append(readln())
lastmsg = readk()
return ret
### BOOT ###
def parse_args():
global sok, isok, osok, argv, argv0, lastmsg
if len(argv) < 1:
usage()
argv0 = argv[0]
argv = argv[1:]
if len(argv) != 2:
usage()
sok = socket.create_connection((argv[0], int(argv[1])))
isok = sok.makefile('rb')
osok = sok.makefile('w')
writeln("LAST 0")
readln()
lastmsg = readk()