Files
tilde-projects/Code/irc/banterbot.py
T

429 lines
12 KiB
Python
Raw Normal View History

#!/usr/bin/python
# http://wiki.shellium.org/w/Writing_an_IRC_bot_in_Python
# Import some necessary libraries.
import socket
import os
import sys
from optparse import OptionParser
import fileinput
import random
import re
import subprocess
2016-09-07 15:58:36 +00:00
import time
import datetime
import inflect
2015-11-24 12:56:18 -05:00
from rhymesWith import getRhymes
2016-01-06 14:08:25 -05:00
from rhymesWith import rhymeZone
from defineWord import defWord
from rainbow import makeRainbow
import welch
import evil
import tumblr
import xkcdApropos
import wikiphilosophy
import acronymFinder
2018-10-09 02:50:06 -04:00
import util
2016-09-07 15:58:36 +00:00
from whosaid import whoSaid
parser = OptionParser()
2018-10-05 16:02:38 -04:00
parser.add_option(
"-s",
"--server",
dest="server",
2018-10-08 17:19:07 -04:00
default="127.0.0.1:6667",
2018-10-05 16:02:38 -04:00
help="the server to connect to",
metavar="SERVER",
)
parser.add_option(
"-c",
"--channel",
dest="channel",
default="#bot_test",
help="the channel to join",
metavar="CHANNEL",
)
parser.add_option(
"-n",
"--nick",
dest="nick",
default="tildebot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args()
p = inflect.engine()
def joinchan(chan):
2018-10-08 17:19:07 -04:00
ircsock.send("JOIN " + chan + "\r\n")
2018-10-05 16:02:38 -04:00
def hello():
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsoc, channel, "Hello!")
2018-10-05 16:02:38 -04:00
def score_banter(channel, user, messageText):
score = 5
with open("banterscores.txt", "r") as banterfile:
bantz = banterfile.readlines()
words = messageText.strip("\n").split(" ")
for word in words:
for bant in bantz:
bword = bant.strip("\n").split("|")
2018-10-05 16:02:38 -04:00
if re.sub("[^a-z0-9]+", "", word.lower()) == bword[0]:
score += int(bword[1])
2018-10-05 16:02:38 -04:00
score += messageText.count("!") * 2 # hype is banter
score -= messageText.count("!!!") * 6 # too much hype is not banter
score += messageText.count("#") * 3 # hashs are mad bantz
score -= messageText.count("##") * 6 # but too many is garbage
2018-10-05 16:02:38 -04:00
names = ["mate", "lad", "my best boy"]
compliment = [
"top-drawer",
"top-shelf",
"bangin'",
"legendary",
"smashing",
"incredible",
"impeccable",
"stunning",
]
msg = ""
if score > 100:
2018-10-08 17:19:07 -04:00
msg = "Truely {}, {}! That was some #banter! You earned a {} for that!".format(
random.choice(compliment).capitalize(), random.choice(names), score
2018-10-05 16:02:38 -04:00
)
elif score > 50:
2018-10-08 17:19:07 -04:00
msg = "{} #banter! You get a {} from me!".format(
random.choice(compliment).capitalize(), score
2018-10-05 16:02:38 -04:00
)
elif score > 10:
2018-10-08 17:19:07 -04:00
msg = "{} #banter. You get a {}".format(
random.choice(["acceptible", "reasonable", "passable"]).capitalize(), score
2018-10-05 16:02:38 -04:00
)
else:
2018-10-08 17:19:07 -04:00
msg = "That {} #banter, {}. I'll give you a {}. Maybe try again?".format(
random.choice(
2018-10-05 16:02:38 -04:00
["was hardly", "was barely", "wasn't", "won't pass for", "was awful"]
2018-10-08 17:19:07 -04:00
),
random.choice(["lad", "lah", "boy", ""]),
score,
2018-10-05 16:02:38 -04:00
)
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, msg)
2018-10-05 16:02:38 -04:00
2015-01-23 17:42:11 +00:00
def get_new_banter(channel, user):
with open("/usr/share/dict/words", "r") as dict:
2018-10-05 16:02:38 -04:00
words = filter(lambda word: re.search(r"^[^']*$", word), dict.readlines())
if random.randint(0, 1): # look for *ant words
words = filter(lambda word: re.search(r"ant", word), words)
2015-01-23 18:07:24 +00:00
random.shuffle(words)
word = words[0].strip("\n")
2018-10-05 16:02:38 -04:00
start = word.find("ant")
if start == 0:
word = "b" + word
2015-01-23 18:07:24 +00:00
else:
2018-10-05 16:02:38 -04:00
if "aeiou".find(word[start]) > -1: # just append a 'b'
word = word[:start] + "b" + word[start:]
else: # replace the letter with 'b'
word = word[: start - 1] + "b" + word[start:]
else: # look for ban* words
words = filter(lambda word: re.search(r"ban", word), words)
2015-01-23 18:07:24 +00:00
random.shuffle(words)
word = words[0].strip("\n")
2018-10-05 16:02:38 -04:00
end = word.find("ban") + 3
if end == len(word):
word = word + "t"
2015-01-23 18:07:24 +00:00
else:
2018-10-05 16:02:38 -04:00
if "aeiou".find(word[end]) > -1: # just append 't'
word = word[:end] + "t" + word[end:]
else: # replace the letter with 'b'
word = word[:end] + "t" + word[end + 1 :]
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock, channel, "{} : Here, why don't you try '{}'?".format(user, word)
2018-10-05 16:02:38 -04:00
)
2015-01-23 17:42:11 +00:00
2015-11-24 12:56:18 -05:00
def get_rhymes(channel, user, text):
word = ""
2018-10-05 16:02:38 -04:00
if len(text.split(" ")) > 1:
word = text.split(" ")[1]
2015-11-24 12:56:18 -05:00
else:
with open("/home/nossidge/poems/words_poetic.txt", "r") as words:
word = random.choice(words.readlines()).strip("\n")
2016-01-06 14:08:25 -05:00
rhymes = rhymeZone(word)
2018-10-05 16:02:38 -04:00
if len(rhymes) == 0:
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock,
channel,
"{}: Couldn't find anything that rhymes with '{}' :(".format(user, word),
2018-10-05 16:02:38 -04:00
)
2015-11-24 12:56:18 -05:00
else:
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock,
channel,
"{}: Here, these words rhyme with '{}': {}".format(
user, word, ", ".join(rhymes)
),
2018-10-05 16:02:38 -04:00
)
2015-11-24 12:56:18 -05:00
def define_word(channel, user, text):
word = ""
defs = []
2018-10-05 16:02:38 -04:00
if len(text.split(" ")) > 1:
word = text.split(" ")[1]
2016-01-06 14:08:25 -05:00
defs = defWord(word)
2018-10-05 16:02:38 -04:00
if len(defs) == 0:
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock,
channel,
"{}: Couldn't find the definition of '{}' :(".format(user, word),
2018-10-05 16:02:38 -04:00
)
elif isinstance(defs, list):
2016-01-13 11:17:57 -05:00
for entry in defs:
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock, channel, "{} : Define '{}' {}".format(user, word, entry[0:400])
2018-10-05 16:02:38 -04:00
)
2018-01-24 20:51:54 +00:00
else:
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock, channel, "{} : Define '{}' {}".format(user, word, defs[0:400])
2018-10-05 16:02:38 -04:00
)
2015-11-24 12:56:18 -05:00
2016-01-06 14:08:25 -05:00
def make_rainbow(channel, user, text):
rbword = makeRainbow(text[9:])
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, rbword)
2015-11-24 12:56:18 -05:00
2018-10-05 16:02:38 -04:00
def get_welch(channel):
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, welch.get_thing()[0:400])
2018-10-05 16:02:38 -04:00
def get_evil(channel):
evilThing = evil.get_thing()
2018-10-05 16:02:38 -04:00
for line in [evilThing[i : i + 400] for i in range(0, len(evilThing), 400)]:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, line)
2018-10-05 16:02:38 -04:00
def get_tumble(url, channel):
tumble = tumblr.tumble(url)
2018-10-05 16:02:38 -04:00
for line in [tumble[i : i + 400] for i in range(0, len(tumble), 400)]:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, line)
2018-10-05 16:02:38 -04:00
def get_xkcd(channel, text):
2016-09-07 15:58:36 +00:00
links = xkcdApropos.xkcd(text[6:])
2018-10-05 16:02:38 -04:00
joined_links = ", ".join(links)
for line in [joined_links[i : i + 400] for i in range(0, len(joined_links), 400)]:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, line)
2018-10-05 16:02:38 -04:00
# res = xkcdApropos.xkcd(text[6:])
# ircsock.send("PRIVMSG " + channel + " :" + res + "\n")
def get_wphilosophy(channel, text):
2018-10-05 16:02:38 -04:00
steps = wikiphilosophy.get_philosophy_lower(text[17:])
if not steps:
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock, channel, "Couldn't find a wikipedia entry for {}".format(text)
2018-10-05 16:02:38 -04:00
)
else:
joined_steps = " > ".join(steps)
if steps[-1] == "Philosophy":
joined_steps += "!!!"
for line in [
joined_steps[i : i + 400] for i in range(0, len(joined_steps), 400)
]:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, line)
2018-10-05 16:02:38 -04:00
def figlet(channel, text):
if not text:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, "No text given. :(")
else:
2018-10-05 16:02:38 -04:00
lines = subprocess.Popen(
["figlet", "-w140"] + text.split(" "), shell=False, stdout=subprocess.PIPE
).stdout.read()
for line in lines.split("\n"):
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, line)
2018-10-05 16:02:38 -04:00
time.sleep(0.4) # to avoid channel throttle due to spamming
2016-09-07 15:58:36 +00:00
def toilet(channel, text):
if not text:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, "No text given. :(")
2016-09-07 15:58:36 +00:00
else:
2018-10-05 16:02:38 -04:00
lines = subprocess.Popen(
["toilet", "-w140", "--irc"] + text.split(" "),
shell=False,
stdout=subprocess.PIPE,
).stdout.read()
for line in lines.split("\n"):
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, line)
2018-10-05 16:02:38 -04:00
time.sleep(0.4) # to avoid channel throttle due to spamming
2016-09-07 15:58:36 +00:00
def get_acronym(channel, text):
2018-10-05 16:02:38 -04:00
if not text:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, "No text given :(")
2018-10-05 16:02:38 -04:00
else:
defs = acronymFinder.get_acros(text, True, True)
for d in defs[0:5]: # only the first five. they are already sorted by 'score'
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, d.encode("utf-8"))
2018-10-05 16:02:38 -04:00
if len(defs) > 5:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, defs[-1])
2018-10-05 16:02:38 -04:00
2016-09-07 15:58:36 +00:00
def get_whosaid(channel, text):
2018-10-05 16:02:38 -04:00
if not text:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, " :No text given :(")
2016-09-07 15:58:36 +00:00
else:
2018-10-05 16:02:38 -04:00
result = whoSaid(text)
date = datetime.date.fromtimestamp(result["timecutoff"])
dateStr = date.strftime("%B %d")
if not result["data"]:
msg = "Nobody said '%s' since %s" % (text, dateStr)
else:
msg = "Since %s, %s said '%s' %d times" % (
dateStr,
result["data"][0][0],
text,
result["data"][0][1],
)
if len(result["data"]) > 1:
msg += " and %s said it %d times" % (
result["data"][1][0],
result["data"][1][1],
)
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, msg)
2018-10-05 16:02:38 -04:00
2018-09-19 17:04:38 +00:00
def get_notice(user, channel):
2018-10-08 17:19:07 -04:00
ircsock.send("CNOTICE " + user + " " + channel + " :Notice me senpai!\r\n")
2018-09-19 17:04:38 +00:00
2018-10-05 16:02:38 -04:00
2018-09-19 17:04:38 +00:00
def get_water(user, channel, msg, botnick):
if msg.find(botnick) == 0:
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, "Fight me, {}!".format(user))
2018-09-19 17:04:38 +00:00
2018-10-05 16:02:38 -04:00
2018-02-28 21:08:22 +00:00
def mug_off(channel):
2018-10-08 17:19:07 -04:00
util.sendmsg(ircsock, channel, "u want some of this, m8?")
2018-02-28 21:08:22 +00:00
2018-10-05 16:02:38 -04:00
def rollcall(channel):
2018-10-08 17:19:07 -04:00
util.sendmsg(
ircsock,
channel,
"""
U wot m8? I score all the top drawer #banter and #bantz on this channel!
Find new top-shelf banter with !newbanter, !rhymes, and !define.
Look up things with !acronym and !whosaid.
Make your chatter #legend with !rainbow, !toilet, and !figlet.
Find interesting things with !xkcd and !wiki-philosophy.
Get jokes with !welch and !evil
""",
2018-10-05 16:02:38 -04:00
)
def get_user_from_message(msg):
2018-10-05 16:02:38 -04:00
try:
i1 = msg.index(":") + 1
i2 = msg.index("!")
return msg[i1:i2]
except ValueError:
return ""
def listen(botnick):
2018-10-05 16:02:38 -04:00
while 1:
2018-10-05 16:02:38 -04:00
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip("\n\r")
2018-10-05 16:02:38 -04:00
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
2018-10-05 16:02:38 -04:00
formatted = util.format_message(ircmsg)
2018-10-05 16:02:38 -04:00
if "" == formatted:
continue
2018-10-05 16:02:38 -04:00
# print formatted
2018-10-08 17:19:07 -04:00
time, user, command, channel, messageText = formatted.split("\t")
2018-10-05 16:02:38 -04:00
if ircmsg.find("#banter") != -1 or ircmsg.find("#bantz") != -1:
score_banter(channel, user, messageText)
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!newbanter") != -1:
get_new_banter(channel, user)
2015-01-23 17:42:11 +00:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!rhymes") != -1:
get_rhymes(channel, user, messageText)
2015-11-24 12:56:18 -05:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!define") != -1:
define_word(channel, user, messageText)
2015-11-24 12:56:18 -05:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!rainbow") != -1:
make_rainbow(channel, user, messageText)
2016-01-06 14:08:25 -05:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!welch") != -1:
get_welch(channel)
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!evil") != -1:
get_evil(channel)
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!kjp") != -1:
get_tumble("http://kingjamesprogramming.tumblr.com", channel)
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!help") != -1:
get_tumble("http://thedoomthatcametopuppet.tumblr.com", channel)
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!xkcd") != -1:
get_xkcd(channel, messageText)
if ircmsg.find(":!wiki-philosophy") != -1:
get_wphilosophy(channel, messageText)
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!figlet") != -1:
figlet(channel, messageText[8:])
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!toilet") != -1:
toilet(channel, messageText[8:])
2016-09-07 15:58:36 +00:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!acronym") != -1:
get_acronym(channel, messageText[9:])
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!whosaid") != -1:
get_whosaid(channel, messageText[9:])
2016-09-07 15:58:36 +00:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!notice") != -1:
get_notice(user, channel)
2018-09-19 17:04:38 +00:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!water") != -1:
get_water(user, channel, messageText[7:], botnick)
2018-09-19 17:04:38 +00:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
2018-09-19 17:04:38 +00:00
2018-10-05 16:02:38 -04:00
if ircmsg.find(":" + botnick + ":") != -1:
mug_off(channel)
2018-10-05 16:02:38 -04:00
if ircmsg[:4] == "PING":
2018-10-08 17:19:07 -04:00
util.ping(ircsock, msg)
2018-02-28 21:08:22 +00:00
2018-10-05 16:02:38 -04:00
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2018-10-08 17:19:07 -04:00
util.connect(ircsock, options)
listen(options.nick)