Browse Source

Converted tildebot to pinhook framework. Moved other things around. Util-ified stuff

master
Russell 3 years ago
parent
commit
5f1bf146c3
  1. 2
      .config/systemd/user/banterbot.service
  2. 2
      .config/systemd/user/tildebot.service
  3. 2
      .config/systemd/user/topicbot.service
  4. 4
      .tracery/aphorism
  5. 99
      Code/irc/acronymFinder.py
  6. 64
      Code/irc/banterbot.py
  7. 440
      Code/irc/banterbot_legacy.py
  8. 7
      Code/irc/banterbot_plugins/template.py
  9. 17
      Code/irc/banterbot_plugins/units.py
  10. 4
      Code/irc/banterbot_plugins/xkcd.py
  11. 0
      Code/irc/data/badwords.txt
  12. 90
      Code/irc/data/banter_corpus.txt
  13. 0
      Code/irc/data/banterscores.txt
  14. 0
      Code/irc/data/numberwangscores.txt
  15. 3
      Code/irc/data/quotes.txt
  16. 0
      Code/irc/data/randomtopics.txt
  17. 1
      Code/irc/data/tildejackpot.txt
  18. 26
      Code/irc/data/tildescores.txt
  19. 0
      Code/irc/data/topics_#bot_test.txt
  20. 0
      Code/irc/data/topics_#bots.txt
  21. 0
      Code/irc/data/topics_#tildetown.txt
  22. 2
      Code/irc/data/topics_now.txt
  23. 0
      Code/irc/data/topicscores.txt
  24. 34
      Code/irc/defineWord.py
  25. 53
      Code/irc/dict_puzzle.py
  26. 198
      Code/irc/duckduckgo.py
  27. 9
      Code/irc/evil.py
  28. BIN
      Code/irc/formatter.pyc
  29. BIN
      Code/irc/get_users.pyc
  30. 3981
      Code/irc/inflect.py
  31. BIN
      Code/irc/inflect.pyc
  32. BIN
      Code/irc/mentions.pyc
  33. 55
      Code/irc/newBanter.py
  34. BIN
      Code/irc/pretty_date.pyc
  35. 185
      Code/irc/puzzle.py
  36. 27
      Code/irc/quote_puzzle.py
  37. 40
      Code/irc/rhymesWith.py
  38. 3
      Code/irc/run.sh
  39. 8
      Code/irc/run_banter.sh
  40. 8
      Code/irc/run_madlib.sh
  41. 7
      Code/irc/run_tilde.sh
  42. 6
      Code/irc/run_topic.sh
  43. 4
      Code/irc/run_wang.sh
  44. 394
      Code/irc/tildebot.py
  45. 215
      Code/irc/topicbot.py
  46. 50
      Code/irc/tumblr.py
  47. 282
      Code/irc/util.py
  48. 322
      Code/irc/wangbot.py
  49. 10
      Code/irc/welch.py
  50. 47
      Code/irc/whosaid.py
  51. 87
      Code/irc/wikiphilosophy.py
  52. 32
      Code/irc/xkcdApropos.py

2
.config/systemd/user/banterbot.service

@ -4,7 +4,7 @@ After=banterbot.service
[Service]
Type=simple
ExecStart=/home/krowbar/Code/irc/banterbot.py -s 127.0.0.1 -p 6667 -n banterbot -c #tildetown #bots
ExecStart=/home/krowbar/Code/irc/bot_launcher.py -s 127.0.0.1 -p 6667 -n banterbot -c #tildetown #bots
WorkingDirectory=/home/krowbar/Code/irc/
Restart=always
RestartSec=5

2
.config/systemd/user/tildebot.service

@ -4,7 +4,7 @@ After=tildebot.service
[Service]
Type=simple
ExecStart=/home/krowbar/Code/irc/tildebot.py -s 127.0.0.1:6667 -n tildebot -c #bots
ExecStart=/home/krowbar/Code/irc/bot_launcher.py -n tildebot -s 127.0.0.1 -p 6667 -c #bots
WorkingDirectory=/home/krowbar/Code/irc/
Restart=always
RestartSec=5

2
.config/systemd/user/topicbot.service

@ -4,7 +4,7 @@ After=topicbot.service
[Service]
Type=simple
ExecStart=/home/krowbar/Code/irc/topicbot.py -s 127.0.0.1:6667 -n topicbot -c #tildetown #bots
ExecStart=/home/krowbar/Code/irc/banterbot.py -s 127.0.0.1 -p 6667 -n topicbot -c #bot_test
WorkingDirectory=/home/krowbar/Code/irc/
Restart=always
RestartSec=5

4
.tracery/aphorism

@ -7,8 +7,8 @@
"#animal.a# in the #bodypart# is #preposition# #number# in the #plant#",
"#noun.a# is only as #adjective# as its #comparative# #noun#",
"#animal.a# is #person.a#'s #comparative# #relation#",
"#person.ae# and #pronoun_possessive# #money# are #adverb# #verb#ed",
"#adjective.a# #noun#is the of #comparative# #noun.s#",
"#person.a# and #pronoun_possessive# #money# are #adverb# #verb#ed",
"#adjective.a# #noun# is the #noun# of #comparative# #noun.s#",
"#person.a# in #verb# is #person.a# #adverb#",
"#comparative.a# #noun# makes #comparative.a# #noun#",
"#person.a# of #adjective# #noun.s# is #person# of #adjective#",

99
Code/irc/acronymFinder.py

@ -1,99 +0,0 @@
#!/usr/bin/python3
import urllib
from bs4 import BeautifulSoup
import random
import string
dict = "/usr/share/dict/american-english"
(userId, token) = open("/home/krowbar/.secret/s4token").readline().rstrip().split(",")
def get_acros(word, silly, short):
acros = []
url = "http://www.stands4.com/services/v2/abbr.php?uid={}&tokenid={}&term={}".format(
userId, token, word
)
soup = BeautifulSoup(urllib.request.urlopen(url).read(), "html5lib")
results = soup.find_all("result")
# there are lots of cases where the same definition is repeated multiple times under different categories. this is dumb so we should do a little more work
defs = []
for r in results:
rdef = r.find("definition").text
match = next((x for x in defs if x["definition"].lower() == rdef.lower()), None)
if match is not None:
# if we find a match, add the category to the existing categories and increase the score
match["categories"].append(
(
(r.find("parentcategoryname").text + "\\")
if r.find("parentcategoryname")
else ""
)
+ r.find("categoryname").text
)
match["score"] = str(float(match["score"]) + float(r.find("score").text))
else: # add a new item
defs.append(
{
"term": r.find("term").text,
"definition": r.find("definition").text,
"categories": [
(
(r.find("parentcategoryname").text + "\\")
if r.find("parentcategoryname")
else ""
)
+ r.find("categoryname").text
],
"score": r.find("score").text,
}
)
for d in sorted(defs, key=lambda x: float(x["score"]), reverse=True):
# print d;
if short is True:
acros.append('"%s"' % d["definition"])
else:
acros.append(
(
'{}: "{}" ({}, score: {})'.format(
d["term"],
d["definition"],
", ".join(d["categories"]),
d["score"],
)
)
)
if silly is True:
newDef = []
words = open(dict, "r").readlines()
try:
for idx, letter in enumerate(word):
newWord = random.choice(
list(filter(
lambda w: (idx is 0 or not w.strip().lower().endswith("'s"))
and w.lower().startswith(letter.lower()),
words,
))
).strip()
print(str(idx) + " -> " + newWord)
newDef.append(newWord)
newWord = string.capwords(" ".join(newDef))
if short is True:
acros.append('"%s"' % newWord)
else:
acros.append(
(
'{}: "{}" ({}, score: {})'.format(
word.upper(), newWord, "Tilde.town Original", "0"
)
)
)
except IndexError:
acros.append("Future hazy, try again later: Tilde.town Error")
if short is True:
shortList = acros[0:5]
if len(acros) > 5:
shortList.append(acros[-1])
return [word.upper() + ": " + ", ".join(shortList)]
else:
return acros

64
Code/irc/banterbot.py

@ -1,64 +0,0 @@
#!/usr/bin/python3
import argparse
from pinhook.bot import Bot
parser = argparse.ArgumentParser()
parser.add_argument(
"-s",
"--server",
dest="server",
default="127.0.0.1",
help="the server to connect to",
metavar="SERVER",
)
parser.add_argument(
"-p",
"--port",
dest="port",
type=int,
default=6667,
help="the port to connect to",
metavar="PORT",
)
parser.add_argument(
"-c",
"--channels",
dest="channels",
nargs="+",
default=["#bot_test"],
help="the channels to join",
metavar="CHANNELS",
)
parser.add_argument(
"-n",
"--nick",
dest="nick",
default="banterbot",
help="the nick to use",
metavar="NICK",
)
parser.add_argument(
"-o",
"--owner",
dest="owner",
default="krowbar",
help="the owner of this bot",
metavar="OWNER",
)
args = parser.parse_args()
print(args)
bot = Bot(
channels = args.channels,
nickname = args.nick,
ops = [ args.owner ],
plugin_dir = "{}_plugins".format(args.nick),
server = args.server,
port = args.port
)
if __name__ == "__main__":
bot.start()

440
Code/irc/banterbot_legacy.py

@ -1,440 +0,0 @@
#!/usr/bin/python3
# using python3 because of unicode and crap
# http://wiki.shellium.org/w/Writing_an_IRC_bot_in_Python
# Import some necessary libraries.
import argparse
import socket
import os
import sys
import fileinput
import random
import re
import subprocess
import textwrap
import time
import datetime
import inflect
from rhymesWith import getRhymes
from rhymesWith import rhymeZone
from defineWord import defWord
import welch
import evil
import tumblr
import xkcdApropos
import wikiphilosophy
import acronymFinder
import util
from whosaid import whoSaid
parser = argparse.ArgumentParser()
parser.add_argument(
"-s",
"--server",
dest="server",
default="127.0.0.1:6667",
help="the server to connect to",
metavar="SERVER",
)
parser.add_argument(
"-c",
"--channels",
dest="channels",
nargs="+",
default=["#bot_test"],
help="the channels to join",
metavar="CHANNELS",
)
parser.add_argument(
"-n",
"--nick",
dest="nick",
default="banterbot_legacy",
help="the nick to use",
metavar="NICK",
)
parser.add_argument(
"-o",
"--owner",
dest="owner",
default="krowbar",
help="the owner of this bot",
metavar="OWNER",
)
args = parser.parse_args()
p = inflect.engine()
def hello():
util.sendmsg(ircsoc, channel, "Hello!")
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("|")
if re.sub("[^a-z0-9]+", "", word.lower()) == bword[0]:
score += int(bword[1])
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
names = ["mate", "lad", "my best boy"]
compliment = [
"top-drawer",
"top-shelf",
"bangin'",
"legendary",
"smashing",
"incredible",
"impeccable",
"stunning",
]
msg = ""
if score > 100:
msg = "Truely {}, {}! That was some #banter! You earned a {} for that!".format(
random.choice(compliment).capitalize(), random.choice(names), score
)
elif score > 50:
msg = "{} #banter! You get a {} from me!".format(
random.choice(compliment).capitalize(), score
)
elif score > 10:
msg = "{} #banter. You get a {}".format(
random.choice(["acceptible", "reasonable", "passable"]).capitalize(), score
)
else:
msg = "That {} #banter, {}. I'll give you a {}. Maybe try again?".format(
random.choice(
["was hardly", "was barely", "wasn't", "won't pass for", "was awful"]
),
random.choice(["lad", "lah", "boy", ""]),
score,
)
util.sendmsg(ircsock, channel, msg)
def get_new_banter(channel, user):
with open("/usr/share/dict/words", "r") as dict:
words = list(filter(lambda word: re.search(r"^[^']*$", word), dict.readlines()))
if random.randint(0, 1): # look for *ant words
words = list(filter(lambda word: re.search(r"ant", word), words))
random.shuffle(words)
word = words[0].strip("\n")
start = word.find("ant")
if start == 0:
word = "b" + word
else:
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 = list(filter(lambda word: re.search(r"ban", word), words))
random.shuffle(words)
word = words[0].strip("\n")
end = word.find("ban") + 3
if end == len(word):
word = word + "t"
else:
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 :]
util.sendmsg(
ircsock, channel, "{} : Here, why don't you try '{}'?".format(user, word)
)
def get_rhymes(channel, user, text):
word = ""
if len(text.split(" ")) > 1:
word = text.split(" ")[1]
else:
with open("/home/nossidge/poems/words_poetic.txt", "r") as words:
word = random.choice(words.readlines()).strip("\n")
rhymes = rhymeZone(word)
if len(rhymes) == 0:
util.sendmsg(
ircsock,
channel,
"{}: Couldn't find anything that rhymes with '{}' :(".format(user, word),
)
else:
util.sendmsg(
ircsock,
channel,
"{}: Here, these words rhyme with '{}': {}".format(
user, word, ", ".join(rhymes)
),
)
def define_word(channel, user, text):
word = ""
defs = []
if len(text.split(" ")) > 1:
word = text.split(" ")[1]
defs = defWord(word)
if len(defs) == 0:
util.sendmsg(
ircsock,
channel,
"{}: Couldn't find the definition of '{}' :(".format(user, word),
)
elif isinstance(defs, list):
for entry in defs:
util.sendmsg(
ircsock, channel, "{} : Define '{}' {}".format(user, word, entry[0:400])
)
else:
util.sendmsg(
ircsock, channel, "{} : Define '{}' {}".format(user, word, defs[0:400])
)
def make_rainbow(channel, user, text):
rbword = util.makeRainbow(text[9:])
util.sendmsg(ircsock, channel, rbword)
def get_welch(channel):
util.sendmsg(ircsock, channel, welch.get_thing()[0:400])
def get_evil(channel):
evilThing = evil.get_thing()
for line in [evilThing[i : i + 400] for i in range(0, len(evilThing), 400)]:
util.sendmsg(ircsock, channel, line)
def get_tumble(url, channel):
tumble = tumblr.tumble(url)
for line in [tumble[i : i + 400] for i in range(0, len(tumble), 400)]:
util.sendmsg(ircsock, channel, line)
def get_xkcd(channel, text):
links = xkcdApropos.xkcd(text[6:])
joined_links = ", ".join(links)
for line in [joined_links[i : i + 400] for i in range(0, len(joined_links), 400)]:
util.sendmsg(ircsock, channel, line)
def get_wphilosophy(channel, text):
util.sendmsg(ircsock, channel, "Ok, give me a minute while I look up '{}'".format(text))
steps = wikiphilosophy.get_philosophy_lower(text)
if not steps:
util.sendmsg(
ircsock, channel, "Couldn't find a wikipedia entry for {}".format(text)
)
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)
]:
util.sendmsg(ircsock, channel, line)
def figlet(channel, text):
if not text:
util.sendmsg(ircsock, channel, "No text given. :(")
else:
lines = subprocess.Popen(
["figlet", "-w140"] + text.split(" "), shell=False, stdout=subprocess.PIPE
).stdout.read().decode("utf-8")
for line in lines.split("\n"):
util.sendmsg(ircsock, channel, line)
time.sleep(0.4) # to avoid channel throttle due to spamming
def toilet(channel, text):
if not text:
util.sendmsg(ircsock, channel, "No text given. :(")
else:
lines = subprocess.Popen(
["toilet", "-w140", "-F", "crop", "--irc"] + text.split(" "),
shell=False,
stdout=subprocess.PIPE,
).stdout.read().decode("utf-8")
for line in lines.split("\n"):
util.sendmsg(ircsock, channel, line)
time.sleep(0.4) # to avoid channel throttle due to spamming
def get_acronym(channel, text):
if not text:
util.sendmsg(ircsock, channel, "No text given :(")
else:
defs = acronymFinder.get_acros(text, True, True)
for d in defs[0:5]: # only the first five. they are already sorted by 'score'
util.sendmsg(ircsock, channel, d)
if len(defs) > 5:
util.sendmsg(ircsock, channel, defs[-1])
def get_whosaid(channel, text):
if not text:
util.sendmsg(ircsock, channel, " :No text given :(")
else:
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],
)
util.sendmsg(ircsock, channel, msg)
def get_notice(user, channel):
util.notice(ircsock, user, channel, "Notice me senpai!")
def get_water(user, channel, msg, botnick):
if msg.find(botnick) == 0:
util.sendmsg(ircsock, channel, "Fight me, {}!".format(user))
def mug_off(channel):
util.sendmsg(ircsock, channel, "u want some of this, m8?")
def rollcall(channel):
text = """
U wot m8? I score all the top drawer #banter and #bantz on this channel! / Find new top-shelf banter with !newbanter [mungeWord [dictionary]], !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 !evil !kjp and !help
"""
for line in textwrap.dedent(text).split("\n"):
if line == "":
continue
util.sendmsg(ircsock, channel, line)
def listen(botnick):
while 1: # loop forever
ircmsg = ircsock.recv(2048).decode('utf-8')
for msg in ircmsg.split("\n"):
msg = msg.strip("\n\r")
if msg[:4] == "PING":
util.ping(ircsock, msg)
continue
formatted = util.format_message(msg)
if "" == formatted:
time.sleep(1)
continue
# print(formatted)
_time, user, _command, channel, messageText = formatted.split("\t")
if messageText.find("#banter") != -1 or messageText.find("#bantz") != -1:
score_banter(channel, user, messageText)
if messageText.startswith("!newbanter"):
get_new_banter(channel, user, messageText)
if messageText.startswith("!rhymes"):
get_rhymes(channel, user, messageText)
if messageText.startswith("!define"):
define_word(channel, user, messageText)
if messageText.startswith("!rainbow"):
make_rainbow(channel, user, messageText)
if messageText.startswith("!welch"):
get_welch(channel)
if messageText.startswith("!evil"):
get_evil(channel)
if messageText.startswith("!kjp"):
get_tumble("http://kingjamesprogramming.tumblr.com", channel)
if messageText.startswith("!help"):
get_tumble("http://thedoomthatcametopuppet.tumblr.com", channel)
if messageText.startswith("!xkcd"):
get_xkcd(channel, messageText)
if messageText.startswith("!wiki-philosophy"):
get_wphilosophy(channel, messageText[17:])
if messageText.startswith("!figlet"):
figlet(channel, messageText[8:])
if messageText.startswith("!toilet"):
toilet(channel, messageText[8:])
if messageText.startswith("!acronym"):
get_acronym(channel, messageText[9:])
if messageText.startswith("!whosaid"):
get_whosaid(channel, messageText[9:])
if messageText.startswith("!notice"):
get_notice(user, channel)
if messageText.startswith("!water"):
get_water(user, channel, messageText[7:], botnick)
if messageText.startswith("!rollcall"):
rollcall(channel)
if messageText.startswith(botnick + ":"):
mug_off(channel)
if messageText.startswith("!join") and user == args.owner:
util.joinchan(ircsock, messageText[6:])
if messageText.startswith("!part") and user == args.owner:
util.part(ircsock, messageText[6:])
if messageText.startswith("!quit") and user == args.owner:
util.quit(ircsock, "Later chumps!")
return
sys.stdout.flush()
time.sleep(1)
if __name__ == "__main__":
# ROOT: i commented this out until it stops pegging the CPU.
# ~krowbar: this has the same logic loop as tildebot but for whatever reason
# it is banterbot that gets booted from IRC then rage-thrashes the machine
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
util.connect(ircsock, args)
listen(args.nick)
else:
# create a fake socket that we'll use to just write to the screen
import mock
ircsock = mock.Mock()
# print("!! ircsock was not initialized! most methods will not work !!")

7
Code/irc/banterbot_plugins/template.py

@ -1,7 +0,0 @@
#!/usr/bin/python3
import pinhook.plugin
@pinhook.plugin.register('!')
def _plugin(msg):
return pinhook.plugin.message()

17
Code/irc/banterbot_plugins/units.py

@ -0,0 +1,17 @@
#!/usr/bin/python3
import pinhook.plugin
import subprocess
UNITS_CMD = "/home/krowbar/Code/units/units-2.11/units"
UNITS_CFG = "/home/krowbar/Code/units/units-2.11/definitions.units"
@pinhook.plugin.register('!units')
def units_plugin(msg):
if not msg.arg:
return pinhook.plugin.message("No text given. :(")
else:
result = subprocess.Popen(
[UNITS_CMD, "-v1f", UNITS_CFG] + msg.arg.split(" "), shell=False, stdout=subprocess.PIPE
).stdout.read().decode("utf-8").strip()
return pinhook.plugin.message(result)

4
Code/irc/banterbot_plugins/xkcd.py

@ -1,8 +1,8 @@
#!/usr/bin/python3
import pinhook.plugin
from util import xkcdApropos
import util.xkcdApropos
@pinhook.plugin.register('!xkcd')
def xkcd_plugin(msg):
return pinhook.plugin.message(xkcdApropos.xkcd(msg.arg))
return pinhook.plugin.message(util.xkcdApropos.xkcd(msg.arg))

0
Code/irc/badwords.txt → Code/irc/data/badwords.txt

90
Code/irc/data/banter_corpus.txt

@ -0,0 +1,90 @@
1418511761 karlen no more banter in the irc now
1421140177 jumblesale karlen yeah mate me too nice one banter
1421140187 karlen i bantered you right off there
1421140203 karlen Archbishop of Banterbury over here
1421140221 jumblesale "Archbishop of Banterbury" amazing
1421140286 karlen I can provide the Bantidote, I am a Bantersaurus Rex
1421140530 jumblesale 2nd wave banterism
1421239834 jumblesale I still can't get over the bishop of banterbury
1421239946 jumblesale all their faces covered by "archbishop of banterbury" in a monospaced font
1421240905 jumblesale archbishop of banterbury is too great for irc
1421244850 jumblesale fruminous bantersnatch
1421322755 karlen tbf I dont think he has as much banter as Rowan http://i.dailymail.co.uk/i/pix/2008/04_05/006Archbishop_228x388.jpg
1421322856 karlen they should just make the archbishop and this point: I am always bantering people off
1421322914 jumblesale banter
1421323249 jumblesale a tilde for top drawer banter?
1421323301 karlen ive spent the last 15mins looking for nowertb with banter but only one came up and its not bantz
1421323368 jumblesale banter
1421323895 karlen ok there will be a nowertb with banter in it at somepoint but its not bantz
1421323963 jumblesale how can you have banter and it not be legendary bantz?
1421324052 karlen It's comforting to realize that no one will ever read this.I am a quiet person for the most part. I mean, I talk, but most of the time it's preprogrammed banter just to pass time and please the people around me.
1421324515 karlen banter all over the world
1421325936 karlen haha there is a podcast they ahve called the Bantams banter I have heard mention of before
1421326023 karlen heard lots of Bantam banter when they beat Arsenal a season or two back
1421326312 karlen haha course, they bantered me off but such is life for a top drawer banter merchant such as myself
1421326892 karlen so that guy is called Carl Jenkison and he plays for Arsenal and hes a right top lad and every other word he says is literally banter
1421326918 karlen of banterbury
1421327028 karlen he's just a banter lad
1421327036 jumblesale karlen nobody's THAT banter
1421327168 karlen me too, will get something banter for lunch
1421328693 jumblesale how banter was your lunch? top drawer or legendary?
1421329045 jumblesale just putting together a little faw for banter
1421329247 karlen 1) What is banter 2) How to banter 3) How to banter someone off 4) Top bantz 5) Banter phrases
1421329333 karlen 6) Lad banter 7) Am I banter? 8) Banter resources 9) Examples of banter 10) When to banter
1421329371 karlen i'll put a banter file in my ~ and try to address some of these issues
1421330214 jumblesale karlen your banter contribution is legendary, I'll combine the two
1421330680 karlen ill try and think of some more once my banter juices have recharged
1421331867 jumblesale my dream is to travel anywhere in the world and immediately be able to banter off the first #lad I see
1421332132 karlen love your top banter phrases jumblesale
1421332270 jumblesale I love everything about your banter file karlen
1421332374 karlen feels wrong typing in less banter
1421332494 jumblesale banter
1421332676 jumblesale I go home. it's dark. I find a pen and hastily scrawl a note. "~wife. sorry. I can't be with you any more. I need banter. #legend". charles barks. he does not recognise me. I am a different man to the one who left this morning. I put the note on the table, collect my passport and step out into the night. somewhere out there a lad needs to be bantered off. and I am the only one who can do it.
1421332760 jumblesale we were just enjoying some banter.
1421337186 jumblesale nah mate just kidding it was shit #banter
1421337361 karlen i got bantered right off there
1421345107 jumblesale now we can finally get some top drawer banter going on
1421346140 krowbar jumblesale: u wot m80? i swear on me mum that's the worst idea i ever dun hear and you should be banned from new ideas. banter!
1421351218 karlen saw the bantz, not sure I deserve to be a notable banterer though compared to those ledge's
1421353890 jumblesale haha harmless banter :)
1421402562 karlen the banter zone
1421402670 karlen im sure dan has banter, its probably a commonwealth export
1421402740 karlen banter has probably spread there like the cane toad
1421402762 karlen they are a banterous people by nature if Foster's adverts are to be believed
1421402804 jumblesale banter = comedy
1421402887 karlen you removed my top banter pun, it was the one bit of bantz in that file worth while
1421402953 karlen from "turn your banter from piss poor to top drawer"
1421402982 karlen or something like that, I had to delete the file from my ~. I had exceeded my banter allowance according the du -BANTS
1421403014 karlen or quota -u -BANTER rather
1421403230 jumblesale http://tilde.town/~banter/
1421403809 karlen wow, maybe they are the banter messiah?!
1421403998 jumblesale I saved your stuff to ~jumblesale/banter
1421404449 karlen just banter mate come on, didn't expect you to look. You've been bantered right off for caring
1421404474 jumblesale well I am going to add it back in put that in your banter pipe and bant it
1421404569 karlen ill be in banter space
1421404903 jumblesale I'm sorry karlen, the banter is fatal. It's spread to your brain.
1421424059 jumblesale karlen that's why they call you banter the magnificent
1421661838 karlen hey its jumblebanter!
1421661982 jumblesale spent all weekend getting bantered right off
1421661993 jumblesale now I'm seeing banter everywhere
1421662006 karlen mate you have taken the red banter pill
1421664295 jumblesale also where are you hanging around in the uk that has swastikas everywhere? are you that desparate for banter?
1421665117 karlen the dan and um zone is probably so banter
1421667558 karlen RogueLad: The banter chronicles
1421667703 jumblesale maybe when I quit here I'll have some time to put into RogueLad: The #banter Chronicles
1421667994 jumblesale Kragoth banters the kobold right off for 6 damage
1421668027 karlen KO: you have been bantered right off there. #DeadLad
1421678445 karlen haha we have to tone down the banter when we have company
1421678572 um You two can banter away as far as I'm concerned.
1421678645 jumblesale haha um you won't find it soothing when karlen banters you right off
1421678654 jumblesale just with his banter
1421678807 jumblesale mate I've been mugging off crustaceans since before you were born. think you can banter off a crab? fack off mate
1421678914 karlen Mate Crustaceans ain't shit. Wait till you banter off a Banatee
1421679040 jumblesale banatee might be a new low in banter punning
1421771342 karlen you are ascending the banter charts that is for sure
1421771528 karlen Mate, only in Ireland is that Banter
1421771917 karlen look what we did to this other guy! he didn't even get exposed! LabMateBanter http://cdn6.bigcommerce.com/s-vhn7zwb/products/452/images/411/eos_safe_showers_freeze__77418__05399.1405105554.1280.1280.jpg?c=2
1421773775 krowbar i'm thinking of writing a banterbot for scoring #banter
1421773807 krowbar but i'll first need a corpus of #banter
1421773838 karlen mensch -q banter
1421773857 karlen or mensch -q "#banter"

0
Code/irc/banterscores.txt → Code/irc/data/banterscores.txt

0
Code/irc/numberwangscores.txt → Code/irc/data/numberwangscores.txt

3
Code/irc/data/quotes.txt

@ -0,0 +1,3 @@
Bang a gong. Get it on. Bang a gong.
/T.Rex/
---

0
Code/irc/randomtopics.txt → Code/irc/data/randomtopics.txt

1
Code/irc/data/tildejackpot.txt

@ -0,0 +1 @@
35

26
Code/irc/tildescores.txt → Code/irc/data/tildescores.txt

@ -1,4 +1,4 @@
krowbar&^%2740&^%1548423098
krowbar&^%2745&^%1548770703.413761
karlen&^%498&^%1527613440
endorphant&^%809&^%1444775660
jumblesale&^%25&^%1426171214
@ -48,13 +48,13 @@ cinch&^%2&^%1480454755
caffbot&^%969&^%1532662872
evilbot&^%4&^%1480693919
tybaltcat&^%7&^%1481076625
Minerbot&^%316&^%1548341661
Minerbot&^%328&^%1548433782
mio&^%347&^%1529720473
tehfraga&^%673&^%1547260565
sushi&^%10&^%1493253212
troido&^%303&^%1548409580
gamebot&^%336&^%1548409599
nilaky&^%1757&^%1548386011
nilaky&^%1759&^%1548459568
bucket&^%103&^%1507931139
lolbot&^%1&^%1502568407
m455&^%12&^%1512076715
@ -67,7 +67,7 @@ pinhook&^%8&^%1509744722
emfor&^%3&^%1509671353
k2l8m11n2&^%11&^%1510932395
sacredpixel&^%3&^%1522082931
login&^%3249&^%1548423081
login&^%3276&^%1548698114
kelpiebot&^%3&^%1513101957
unreal&^%2&^%1534387108
kinsey&^%26&^%1520446672
@ -80,11 +80,11 @@ silver&^%9&^%1519333029
equa&^%53&^%1534373756
audiodude&^%2&^%1519453927
whimsy&^%47&^%1529678733
wangofett&^%285&^%1547499873
wangofett&^%286&^%1548446486
saturn&^%3&^%1521429369
lucidiot&^%28&^%1526201925
tracer&^%1&^%1521744878
jan6&^%1346&^%1548353997
jan6&^%1359&^%1548771222.440076
eeeeeta&^%55&^%1540361066
cmccabe&^%81&^%1529698164
carbon&^%9&^%1524135505
@ -96,7 +96,7 @@ ralph&^%4&^%1526980620
von&^%490&^%1548233084
ensis&^%1750&^%1546853217
simon&^%26&^%1527937489
benharri&^%3241&^%1548427827
benharri&^%3276&^%1548695613
cpb&^%3&^%1528930564
calmbit&^%160&^%1541625694
wisebot&^%5652&^%1539612163
@ -106,10 +106,10 @@ x4464&^%1&^%1532028546
pounce&^%19&^%1532133325
livix&^%7&^%1533603142
ben&^%3&^%1533767627
npa&^%319&^%1548385964
npa&^%326&^%1548659103
ezo&^%6&^%1533883842
aliasless&^%36&^%1541001821
kirch&^%487&^%1548427938
kirch&^%492&^%1548773313.169501
root&^%2&^%1535558514
byte&^%5&^%1536416308
qbe&^%7&^%1537850181
@ -118,16 +118,16 @@ h00fi&^%1&^%1537050053
fantoro&^%57&^%1542125611
tildethief&^%7421&^%1542132794
benjaminwil&^%581&^%1548377274
deltawitch&^%3451&^%1548192292
deltawitch&^%3453&^%1548462217
archangelic&^%484&^%1541101297
diodelass&^%3&^%1539382302
minerobber&^%420&^%1548341654
minerobber&^%420&^%1548433750
brendantcc&^%3&^%1539908223
dozens&^%21&^%1541090333
bowlercaptain&^%6&^%1540926135
nicole&^%6&^%1541276844
littlebigly&^%49&^%1541283119
ahriman&^%624&^%1548397580
ahriman&^%636&^%1548663037
tunas&^%114&^%1545848648
netscape_navigator&^%5&^%1545846867
roan&^%5&^%1545846612
@ -136,6 +136,6 @@ ben&^%3&^%1545800958
l0010o0001l&^%3&^%154529473
rgdrake&^%1&^%1546086404
handyc&^%5&^%1546456002
fosslinux&^%8&^%1548296029
fosslinux&^%10&^%1548661962
banterbot&^%3&^%1547588758
testgamebot&^%4&^%1547722176

0
Code/irc/topics_#bot_test.txt → Code/irc/data/topics_#bot_test.txt

0
Code/irc/topics_#bots.txt → Code/irc/data/topics_#bots.txt

0
Code/irc/topics_#tildetown.txt → Code/irc/data/topics_#tildetown.txt

2
Code/irc/data/topics_now.txt

@ -0,0 +1,2 @@
1516797459&^%login&^%
1516797472&^%login&^%

0
Code/irc/topicscores.txt → Code/irc/data/topicscores.txt

34
Code/irc/defineWord.py

@ -1,34 +0,0 @@
#!/usr/bin/python3
import urllib
from bs4 import BeautifulSoup
import random
def define(word):
defs = []
url = "http://www.merriam-webster.com/dictionary/{}".format(word)
soup = BeautifulSoup(urllib.request.urlopen(url).read(), "html.parser")
head = soup.find("div", id="headword")
if head:
for p in head.find_all("p"):
defs.append(p.text)
return defs
key = open("/home/krowbar/.secret/key").readline().rstrip()
def defWord(word, short=True):
defs = []
url = "http://www.dictionaryapi.com/api/v1/references/collegiate/xml/{}?key={}".format(
word, key
)
soup = BeautifulSoup(urllib.request.urlopen(url).read(), "html5lib")
entry = soup.find("entry")
if entry:
for d in entry.find_all("dt"):
defs.append(d.text)
if short:
return " ".join(defs)
else:
return defs

53
Code/irc/dict_puzzle.py

@ -1,53 +0,0 @@
#!/usr/bin/python
import random
import inflect
p = inflect.engine()
dictionary = "/usr/share/dict/american-english-small"
BAD_WORDS_FILE = "badwords.txt"
def gen_wordlist():
# I feel weird calling this "get_wordlist" when it's a generator without calling out that I do in fact realise it's weird - ~deltawitch
# how about gen_wordlist
with open(BAD_WORDS_FILE, "r") as fp:
bad_words = set(fp)
for word in open(dictionary).readlines():
if "'" not in word and word not in bad_words:
yield word.rstrip()
def get_puzzle():
dict_words = list(gen_wordlist())
words = random.sample(dict_words, 3)
key = random.randrange(0, 3) # get values 1-3
puzzle = "When alphebetized, what is the {} in {}?".format(
p.ordinal(p.number_to_words(key + 1)), ", ".join(words)
)
words.sort()
answer = words[key]
return [answer, puzzle]
def get_anagram(maxlen=6):
dict_words = [
word for word in gen_wordlist() if len(word) > 2 and len(word) < maxlen + 1
]
word = random.choice(dict_words)
anagram = list(word)
random.shuffle(anagram)
anagram = "".join(anagram)
# Anagrams can have multiple answers, so we provide a check function that accepts all possibilities
def answer_checker(guess):
# Check for exact match
if guess == word:
return True
# Bail out early if they didn't even use all the same letters
if sorted(guess) != sorted(word):
return False
# Ok, gotta actually check if it's a word now
return any(guess == item for item in gen_wordlist())
return [answer_checker, "Unscramble the following word: '{}'".format(anagram)]

198
Code/irc/duckduckgo.py

@ -1,198 +0,0 @@
import requests
import urllib
import json as j
import sys
__version__ = 0.242
def query(
query,
useragent="python-duckduckgo " + str(__version__),
safesearch=True,
html=False,
meanings=True,
**kwargs
):
"""
Query DuckDuckGo, returning a Results object.
Here's a query that's unlikely to change:
>>> result = query('1 + 1')
>>> result.type
'nothing'
>>> result.answer.text
'1 + 1 = 2'
>>> result.answer.type
'calc'
Keword arguments:
useragent: UserAgent to use while querying. Default: "python-duckduckgo %d" (str)
safesearch: True for on, False for off. Default: True (bool)
html: True to allow HTML in output. Default: False (bool)
meanings: True to include disambiguations in results (bool)
Any other keyword arguments are passed directly to DuckDuckGo as URL params.
""" % __version__
safesearch = "1" if safesearch else "-1"
html = "0" if html else "1"
meanings = "0" if meanings else "1"
params = {
"q": query,
"o": "json",
"kp": safesearch,
"no_redirect": "1",
"no_html": html,
"d": meanings,
}
params.update(kwargs)
encparams = urllib.parse.urlencode(params)
url = "http://api.duckduckgo.com/?" + encparams
request = requests.get(url, headers={"User-Agent": useragent})
return Results(request.json())
class Results(object):
def __init__(self, json):
self.type = {
"A": "answer",
"D": "disambiguation",
"C": "category",
"N": "name",
"E": "exclusive",
"": "nothing",
}.get(json.get("Type", ""), "")
self.json = json
self.api_version = None # compat
self.heading = json.get("Heading", "")
self.results = [Result(elem) for elem in json.get("Results", [])]
self.related = [Result(elem) for elem in json.get("RelatedTopics", [])]
self.abstract = Abstract(json)
self.redirect = Redirect(json)
self.definition = Definition(json)
self.answer = Answer(json)
self.image = Image({"Result": json.get("Image", "")})
class Abstract(object):
def __init__(self, json):
self.html = json.get("Abstract", "")
self.text = json.get("AbstractText", "")
self.url = json.get("AbstractURL", "")
self.source = json.get("AbstractSource")
class Redirect(object):
def __init__(self, json):
self.url = json.get("Redirect", "")
class Result(object):
def __init__(self, json):
self.topics = json.get("Topics", [])
if self.topics:
self.topics = [Result(t) for t in self.topics]
return
self.html = json.get("Result")
self.text = json.get("Text")
self.url = json.get("FirstURL")
icon_json = json.get("Icon")
if icon_json is not None:
self.icon = Image(icon_json)
else:
self.icon = None
class Image(object):
def __init__(self, json):
self.url = json.get("Result")
self.height = json.get("Height", None)
self.width = json.get("Width", None)
class Answer(object):
def __init__(self, json):
self.text = json.get("Answer")
self.type = json.get("AnswerType", "")
class Definition(object):
def __init__(self, json):
self.text = json.get("Definition", "")
self.url = json.get("DefinitionURL")
self.source = json.get("DefinitionSource")
def get_zci(
q,
web_fallback=True,
priority=["answer", "abstract", "related.0", "definition"],
urls=True,
**kwargs
):
"""A helper method to get a single (and hopefully the best) ZCI result.
priority=list can be used to set the order in which fields will be checked for answers.
Use web_fallback=True to fall back to grabbing the first web result.
passed to query. This method will fall back to 'Sorry, no results.'
if it cannot find anything."""
ddg = query("\\" + q, **kwargs)
response = ""
for p in priority:
ps = p.split(".")
type = ps[0]
index = int(ps[1]) if len(ps) > 1 else None
result = getattr(ddg, type)
if index is not None:
if not hasattr(result, "__getitem__"):
raise TypeError("%s field is not indexable" % type)
result = result[index] if len(result) > index else None
if not result:
continue
if result.text:
response = result.text
if result.text and hasattr(result, "url") and urls:
if result.url:
response += " (%s)" % result.url
if response:
break
# if there still isn't anything, try to get the first web result
if not response and web_fallback:
if ddg.redirect.url:
response = ddg.redirect.url
# final fallback
if not response:
response = "Sorry, no results."
return response
def main():
if len(sys.argv) > 1:
q = query(" ".join(sys.argv[1:]))
keys = q.json.keys()
keys.sort()
for key in keys:
sys.stdout.write(key)
if type(q.json[key]) in [str, unicode]:
print(":", q.json[key])
else:
sys.stdout.write("\n")
for i in q.json[key]:
print("\t", i)
else:
print("Usage: %s [query]" % sys.argv[0])

9
Code/irc/evil.py

@ -1,9 +0,0 @@
import random
def get_thing():
file = "/home/krowbar/logs/evildata.txt"
thing = ""
return (
"If I Ever Become an Evil Overlord: " + random.choice(list(open(file))).rstrip()
)

BIN
Code/irc/formatter.pyc

Binary file not shown.

BIN
Code/irc/get_users.pyc

Binary file not shown.

3981
Code/irc/inflect.py

File diff suppressed because it is too large

BIN
Code/irc/inflect.pyc

Binary file not shown.

BIN
Code/irc/mentions.pyc

Binary file not shown.

55
Code/irc/newBanter.py

@ -1,55 +0,0 @@
#!/usr/bin/python3
import random
import re
dictDir = "/usr/share/dict/"
def getBanter(morphWord="bant", dictName="words"):
with open(dictDir + dictName, "r") as dict:
# get rid of all the words with apostrophes
words = list(filter(lambda word: re.search(r"^[^']*$", word), dict.readlines()))
head = getBanterHead(words, morphWord)
tail = getBanterTail(words, morphWord)
if head == "" and tail == "":
return "" # dang, we just failed
else:
# pick randomly between non-empty strings
return random.choice([w for w in [head, tail] if w != ""])
def getBanterHead(words, morphWord):
morphHead = morphWord[0:-1]
morphLast = morphWord[-1]
filtered = list(filter(lambda word: re.search(morphHead, word), words))
if len(filtered) == 0:
return "" # nothing applicable found
word = random.choice(filtered).strip("\n")
end = word.find(morphHead) + len(morphHead)
if end == len(word):
return word + morphLast
else:
if "aeiou".find(word[end]) > -1: # just append 't'
return word[:end] + morphLast + word[end:]
else: # replace the letter with 'b'
return word[:end] + morphLast + word[end + 1 :]
def getBanterTail(words, morphWord):
morphTail = morphWord[1:]
morphFirst = morphWord[0]
filtered = list(filter(lambda word: re.search(morphTail, word), words))
if len(filtered) == 0:
return "" # nothing applicable found
word = random.choice(filtered).strip("\n")
start = word.find(morphTail)
if start == 0:
return morphFirst + word
else:
if "aeiou".find(word[start]) > -1: # just append a 'b'
return word[:start] + morphFirst + word[start:]
else: # replace the letter with 'b'
return word[: start - 1] + morphFirst + word[start:]

BIN
Code/irc/pretty_date.pyc

Binary file not shown.

185
Code/irc/puzzle.py

@ -1,185 +0,0 @@
#!/usr/bin/python
import random
import hashlib
import inflect
import quote_puzzle
import dict_puzzle
import textcaptcha
p = inflect.engine()
primes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
fuzz_amount = 3
def make_puzzle(obfuscate=True, roll=None):
answer = 0
bonus = 0
puzzle = random.choice(
[
"Prove you're not a robot: ",
"Are you a robot?: ",
"Anti-bot check: ",
"Counter-cnd0rphant measures: ",
"Cosn0k countermeasures: ",
"Anti-tilde7hief precautions: ",
"Pro-l0gin challenge: ",
"Riddle me this: ",
"Would you like to play a game? ",
"How about this? "
]
)
puzzle += random.choice(
[
"What is",
"What do you get from",
"What do you get with",
"What is the value of",
"Can you answer",
"Can you tell me",
"Ask wiz3bot what is",
"Does anybody know",
"Who knows",
"Guess what",
"Calculate",
"Find out"
]
)
puzzle += " "
roll = roll or random.randrange(0, 21)
var1 = random.randrange(1, 10)
var2 = random.randrange(1, 10)
var3 = random.randrange(1, 20)
var4 = random.randrange(1, 20)
let1_ord = random.randrange(ord("a"), ord("z") + 1)
if roll == 0:
answer = var1 + var2
puzzle += "{} {} {}".format(
p.number_to_words(var1),
random.choice(["and", "plus", "sum", "add"]),
p.number_to_words(var2),
)
elif roll == 1:
answer = var1 * var2
puzzle += "{} {} {}".format(
p.number_to_words(var1),
random.choice(["times", "multiply", "multiplied by", "product"]),
p.number_to_words(var2),
)
elif roll == 2:
if var2 > var1:
var1, var2 = var2, var1
answer = var1 - var2
puzzle += "{} {} {}".format(
p.number_to_words(var1),
random.choice(["minus", "subtract", "take away", "less"]),
p.number_to_words(var2),
)
elif roll == 3:
if var2 > var1:
var1, var2 = var2, var1
answer = var1 * 2 / var2
puzzle += "{} {} {} (no remainder)".format(
p.number_to_words(var1 * 2),
random.choice(["divided by", "over"]),
p.number_to_words(var2),
)
elif roll == 4:
answer = var1 ** var2
puzzle += "{} to the {} power".format(
p.number_to_words(var1), p.ordinal(p.number_to_words(var2))
)
elif roll == 5:
p1 = random.choice(primes)
p2 = random.choice(primes)
def answer(guess):
# Check the the numbers entered are correct, regardless of order
# or surrounding whitespace.
attempt = sorted(word.strip() for word in guess.split(","))
correct = sorted([str(p1), str(p2)])
return attempt == correct
bonus = 1
puzzle += "{} when factored into its two primes (answer in the form of the two primes with a comma between)".format(
p.number_to_words(p1 * p2)
)
elif roll == 6:
prime = random.choice(primes)
answer = prime % var1
puzzle += p.number_to_words(prime) + " modulus " + p.number_to_words(var1)
elif roll == 7:
if let1_ord + var1 > ord("z"):
let1_ord -= var1
answer = chr(let1_ord + var1)
puzzle += "letter comes {} letters after '{}'".format(
p.number_to_words(var1), chr(let1_ord)
)
obfuscate = False
elif roll == 8:
if let1_ord - var1 < ord("a"):
let1_ord += var1
answer = chr(let1_ord - var1)
puzzle += "letter comes {} letters before '{}'".format(
p.number_to_words(var1), chr(let1_ord)
)
obfuscate = False
elif roll == 9:
answer, puzzle = quote_puzzle.get_quote()
obfuscate = False
elif roll == 10:
answer = str(min(var1, var2, var3, var4))
puzzle += "the {} of {}, {}, {}, and {}".format(
random.choice(["smallest", "lowest"]),
p.number_to_words(var1),
p.number_to_words(var2),
p.number_to_words(var3),
p.number_to_words(var4),
)
elif roll == 11:
answer = str(max(var1, var2, var3, var4))
puzzle += "the {} of {}, {}, {}, and {}".format(
random.choice(["biggest", "largest"]),
p.number_to_words(var1),
p.number_to_words(var2),
p.number_to_words(var3),
p.number_to_words(var4),
)
elif roll <= 14: # 12-14
answer, puzzle = dict_puzzle.get_puzzle()
obfuscate = False
elif roll <= 17: # 15-17
answer, puzzle = dict_puzzle.get_anagram()
obfuscate = False
elif roll == 18:
answer, puzzle = quote_puzzle.get_chuck()
obfuscate = False
elif roll <= 20: #19-20
captcha = textcaptcha.get_captcha()
puzzle = captcha['q'] # the question part of the captcha
print(captcha)
answer = lambda a : hashlib.md5(a.encode()).hexdigest() in captcha['a'] # check if the answer is correct
obfuscate = False
bonus = 1
# Add a question mark on the end of the question
if puzzle[-1] != "?":
puzzle += "?"
if obfuscate == True:
for _ in range(fuzz_amount):
idx = random.randrange(len(puzzle) - 2) # get between 0 and string length (except the ? mark)