Converted tildebot to pinhook framework. Moved other things around. Util-ified stuff
This commit is contained in:
parent
bc102890b2
commit
5f1bf146c3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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#",
|
||||
|
|
|
@ -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
|
|
@ -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()
|
|
@ -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 !!")
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import pinhook.plugin
|
||||
|
||||
@pinhook.plugin.register('!')
|
||||
def _plugin(msg):
|
||||
return pinhook.plugin.message()
|
|
@ -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)
|
|
@ -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,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,0 +1,3 @@
|
|||
Bang a gong. Get it on. Bang a gong.
|
||||
/T.Rex/
|
||||
---
|
|
@ -0,0 +1 @@
|
|||
35
|
|
@ -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,0 +1,2 @@
|
|||
1516797459&^%login&^%
|
||||
1516797472&^%login&^%
|
|
@ -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
|
|
@ -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)]
|
|
@ -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])
|
|
@ -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()
|
||||
)
|
Binary file not shown.
Binary file not shown.
3981
Code/irc/inflect.py
3981
Code/irc/inflect.py
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
|
@ -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:]
|
Binary file not shown.
|
@ -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)
|
||||
puzzle = "".join(
|
||||
[puzzle[0:idx], chr(random.randint(33, 126)), puzzle[idx + 1 :]]
|
||||
)
|
||||
return [puzzle, answer, bonus]
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import json
|
||||
import urllib
|
||||
import random
|
||||
import re
|
||||
|
||||
quotefile = "/home/karlen/irc/quotes.txt"
|
||||
chuckfile = "chuck.txt"
|
||||
chuckApi = "https://api.icndb.com/jokes/random"
|
||||
|
||||
def get_quote():
|
||||
quotes = open(quotefile, "r").read().split("---")
|
||||
quote, attr = random.choice(quotes).strip().splitlines()
|
||||
quote = quote[:200] # get only the first 200 chars
|
||||
word = random.choice([q for q in quote.split(" ") if len(q) > 1])
|
||||
quote = quote.replace(word, re.sub(r"[a-zA-Z]", "_", word))
|
||||
return [word, 'Fill in the blank: "' + quote + '" ' + attr]
|
||||
|
||||
def get_chuck():
|
||||
#chucks = open(chuckfile, "r").readlines()
|
||||
#chuck = random.choice(chucks).rstrip()[:200] # get only the first 200 chars
|
||||
# ha ha! let's see if we can confus login
|
||||
chuck = json.loads(urllib.urlopen(chuckApi).read().decode())['value']['joke'][:200]
|
||||
word = random.choice([w for w in chuck.split(" ") if len(w) > 1 and w.lower() != "chuck" and w.lower() != "norris"])
|
||||
chuck = chuck.replace(word, re.sub(r"[a-zA-Z]", "_", word)).replace(""", "\"")
|
||||
return [word, 'Fill in the blank: "{}"'.format(chuck)]
|
|
@ -1,40 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
import urllib
|
||||
|
||||
# from lxml.html import fromstring
|
||||
from bs4 import BeautifulSoup
|
||||
import random
|
||||
|
||||
|
||||
def getRhymes(word):
|
||||
words = []
|
||||
url = "http://www.rhymer.com/RhymingDictionaryLast/%s.html" % word
|
||||
soup = BeautifulSoup(urllib.request.urlopen(url).read(), "html.parser")
|
||||
|
||||
for t in soup.find_all("table", "table"):
|
||||
words.append(
|
||||
random.choice(
|
||||
[
|
||||
w
|
||||
for w in t.text.split("\n")
|
||||
if w not in [u"", u"\xa0"] and "-" not in w
|
||||
]
|
||||
)
|
||||
)
|
||||
return words
|
||||
|
||||
|
||||
def rhymeZone(word):
|
||||
words = []
|
||||
url = (
|
||||
"http://rhymezone.com/r/rhyme.cgi?Word=%s&typeofrhyme=perfect&org1=syl&org2=l&org3=y"
|
||||
% word
|
||||
)
|
||||
soup = BeautifulSoup(urllib.request.urlopen(url).read(), "html.parser")
|
||||
|
||||
for t in soup.find_all("a", "d"):
|
||||
w = t.text.rstrip()
|
||||
if w not in [u"", u"\xa0"] and "?" not in t:
|
||||
words.append(w)
|
||||
random.shuffle(words)
|
||||
return words[0:5]
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
nohup ./tilde_bot.py -s 127.0.0.1 -n tilde_bot -c \#bot_test >> log 2>> log &
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ ! `pidof -sx banterbot.py` ]]; then
|
||||
#nohup ./banterbot.py -s 127.0.0.1:6667 -n banterbot -c \#tildetown \#bots >> banterlog 2>> banterlog &
|
||||
# check if the bot is already running
|
||||
if [[ ! `pidof -sx bot_launcher.py` || ! `ps -p $(pidof -sx bot_launcher.py) -o args | grep "\-n banterbot"` ]]; then
|
||||
echo "Starting banterbot"
|
||||
nohup ./banterbot.py -s 127.0.0.1:6667 -n banterbot -c \#tildetown \#bots >> banterlog 2>> banterlog &
|
||||
/home/krowbar/Code/irc/bot_launcher.py -n banterbot -s 127.0.0.1 -p 6667 -c \#tildetown \#bots
|
||||
# nohup /home/krowbar/Code/irc/bot_launcher.py -n banterbot -s 127.0.0.1:6667 -c \#bot_test
|
||||
else
|
||||
echo "Banterbot has already been started"
|
||||
fi
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ ! `pidof -sx madlibbot.py` ]]; then
|
||||
nohup ./madlibbot/madlibbot.py -s 127.0.0.1:6667 -n madlibbot -c \#bots \#madlibs >> madliblog 2>> madliblog &
|
||||
echo "Starting madlibbot"
|
||||
else
|
||||
echo "madlibbot has already been started"
|
||||
fi
|
|
@ -1,8 +1,9 @@
|
|||
#!/bin/bash
|
||||
if [[ ! `pidof -sx tildebot.py` ]]; then
|
||||
# check if the bot is already running
|
||||
if [[ ! `pidof -sx bot_launcher.py` || ! `ps -p $(pidof -sx bot_launcher.py) -o args | grep "\-n tildebot"` ]]; then
|
||||
echo "Starting tildebot"
|
||||
nohup ./tildebot.py -s 127.0.0.1:6667 -n tildebot -c \#tildetown \#bots >> tildelog 2>> tildelog &
|
||||
#nohup ./tildebot.py -s 127.0.0.1:6667 -n tildebot -c \#bots >> tildelog 2>> tildelog &
|
||||
/home/krowbar/Code/irc/bot_launcher.py -n tildebot -s 127.0.0.1 -p 6667 -c \#bots
|
||||
# nohup /home/krowbar/Code/irc/bot_launcher.py -n tildebot -s 127.0.0.1:6667 -c \#bot_test
|
||||
else
|
||||
echo "Tildebot has already been started"
|
||||
fi
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
if [[ ! `pidof -sx topicbot.py` ]]; then
|
||||
nohup ./topicbot.py -s 127.0.0.1:6667 -n topicbot -c \#tildetown \#bots >> topiclog 2>> topiclog &
|
||||
fi
|
||||
#nohup ./topicbot.py -s 127.0.0.1:6667 -n topicbot -c \#bot_test \#bots >> topiclog 2>> topiclog &
|
||||
#./topic_bot.py -s 127.0.0.1 -n topic_bot -c \#bot_test
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
nohup ./wangbot.py -n numberwang_bot -c \#bots >> wanglog 2>> wanglog &
|
||||
#nohup ./wangbot.py -s 127.0.0.1 -n numberwang_bot -c \#bot_test >> wanglog 2>> wanglog &
|
|
@ -1,394 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# http://wiki.shellium.org/w/Writing_an_IRC_bot_in_Python
|
||||
|
||||
# Import some necessary libraries.
|
||||
import socket
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import argparse
|
||||
import fileinput
|
||||
import random
|
||||
|
||||
import inflect
|
||||
import puzzle
|
||||
import util
|
||||
|
||||
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="tildebot",
|
||||
help="the nick to use",
|
||||
metavar="NICK",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
p = inflect.engine()
|
||||
challenges = {}
|
||||
SCORE_FILE = "tildescores.txt"
|
||||
JACKPOT_FILE = "tildejackpot.txt"
|
||||
JACKPOT_MIN = 3
|
||||
DEBUG = False
|
||||
|
||||
|
||||
def too_recent(time1, time2):
|
||||
return int(time1) - int(time2) < 60 * 60
|
||||
|
||||
|
||||
def get_positive():
|
||||
return random.choice(
|
||||
[
|
||||
"Yes",
|
||||
"Yep",
|
||||
"Yeppers",
|
||||
"Correct",
|
||||
"You got it",
|
||||
"Yeah",
|
||||
"Right on",
|
||||
"Uh-huh",
|
||||
"Positive",
|
||||
"Totally right",
|
||||
"Close enough",
|
||||
"That's it",
|
||||
"Winner, winner",
|
||||
"Bingo",
|
||||
"Affirmative",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def get_negative():
|
||||
return random.choice(
|
||||
[
|
||||
"No",
|
||||
"Nope",
|
||||
"Sorry",
|
||||
"Wrong",
|
||||
"Nuh-uh",
|
||||
"Negatory",
|
||||
"Incorrect",
|
||||
"Not today",
|
||||
"Try again",
|
||||
"Maybe later",
|
||||
"Maybe next time",
|
||||
"Probably not",
|
||||
"Answer hazy",
|
||||
"Not quite",
|
||||
"Not even close",
|
||||
"Not for you",
|
||||
"I think not"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def get_superlative(score):
|
||||
if score > 4:
|
||||
return random.choice(
|
||||
[
|
||||
"super cool",
|
||||
"totally rad",
|
||||
"extraordinary",
|
||||
"dynomite",
|
||||
"#topdrawer",
|
||||
"a #TopLad",
|
||||
"the cat's meow",
|
||||
"a tilde town hero",
|
||||
"my favorite person",
|
||||
"incredibly lucky",
|
||||
"unbelievable",
|
||||
"a tilde town hunk",
|
||||
"could bring all the boys to the yard",
|
||||
"worth twice their weight in gold",
|
||||
"the hero we need",
|
||||
"no ordinary townie",
|
||||
]
|
||||
)
|
||||
elif score > 2:
|
||||
return random.choice(
|
||||
[
|
||||
"really cool",
|
||||
"pretty neat",
|
||||
"rather nice",
|
||||
"a dynamic doggo",
|
||||
"radical",
|
||||
"intense",
|
||||
"pretty lucky",
|
||||
"knows the territory",
|
||||
"has what it takes",
|
||||
"has mad skillz",
|
||||
"going the distance",
|
||||
"a hard worker",
|
||||
"my sunshine",
|
||||
"ready to rumble",
|
||||
]
|
||||
)
|
||||
else:
|
||||
return random.choice(
|
||||
[
|
||||
"cool",
|
||||
"nice",
|
||||
"acceptible",
|
||||
"good enough",
|
||||
"a promising pupper",
|
||||
"better than a horse",
|
||||
"swell",
|
||||
"a little lucky",
|
||||
"just credible",
|
||||
"my friend",
|
||||
"probably not a robot",
|
||||
"valuable to the team",
|
||||
"now trending",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def get_bad_thing():
|
||||
return random.choice(
|
||||
[
|
||||
"is a meanie",
|
||||
"mugs me right off",
|
||||
"miffed me off",
|
||||
"is worse than a horse",
|
||||
"smells like a ghost",
|
||||
"probably didn't bathe today",
|
||||
"probably shakes babies",
|
||||
"didn't guess hard enough",
|
||||
"isn't lucky",
|
||||
"smells of elderberries",
|
||||
"should reconsider their life choices",
|
||||
"did't believe in the heart of the tilde",
|
||||
"came to the wrong side of town",
|
||||
"should have stopped while they were ahead",
|
||||
"requires annotations from an authoratative source",
|
||||
"could have been a contender",
|
||||
"spreads vicious rumors",
|
||||
"drank my milkshake",
|
||||
"is probably cheating",
|
||||
"is trying too hard",
|
||||
"didn't really try",
|
||||
"should try harder",
|
||||
"caught me in a bad mood",
|
||||
"should have gone with their first choice",
|
||||
"did not receive IFR clearance from tower",
|
||||
"was tardy for class",
|
||||
"is on double secret probation",
|
||||
"forgot their keys",
|
||||
"forgot to bribe me",
|
||||
"forgot to close the door",
|
||||
"waited too long",
|
||||
"doesn't call me on my cellphone",
|
||||
"isn't wearing a seatbelt",
|
||||
"didn't courtesy flush",
|
||||
"asked a bot for answers",
|
||||
"was right but I didn't feel like it",
|
||||
"is right on opposite day",
|
||||
"actually answered the last question",
|
||||
"has their pants on backwards",
|
||||
"forgot their own name",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def get_prize(name, isHuman, bonus=0):
|
||||
prizes = [1] * 8 + [2] * 4 + [3] * 2 + [5] * isHuman # no 5pt prize for non-humans
|
||||
prize = random.choice(prizes) + bonus
|
||||
if (
|
||||
random.randint(1, 10) > 6 - 4 * isHuman
|
||||
): # 80% of the time it's a normal prize (40% for not humans)
|
||||
return [
|
||||
prize,
|
||||
"{}: {}! You are {} and get {} tildes!".format(
|
||||
name,
|
||||
(get_positive() if isHuman else get_negative()),
|
||||
get_superlative(prize),
|
||||
p.number_to_words(prize),
|
||||
),
|
||||
]
|
||||
else: # 20% of the time its a jackpot situation
|
||||
with open(JACKPOT_FILE, "r+") as jackpotfile:
|
||||
jackpot = int(jackpotfile.readline().strip("\n"))
|
||||
jackpotfile.seek(0)
|
||||
jackpotfile.truncate()
|
||||
if (
|
||||
random.randint(1, 10) > 1 or not isHuman
|
||||
): # 90% of the time it's a non-prize. non-humans never win jackpot
|
||||
new_jackpot = jackpot + max(1, prize)
|
||||
jackpotfile.write(
|
||||
str(new_jackpot)
|
||||
) # increase the jackpot by the prize size
|
||||
return [
|
||||
0,
|
||||
"{} {} and gets no tildes! (Jackpot is now {} tildes)".format(
|
||||
name, get_bad_thing(), new_jackpot
|
||||
),
|
||||
]
|
||||
else: # hit jackpot!
|
||||
jackpotfile.write(str(JACKPOT_MIN))
|
||||
return [
|
||||
jackpot,
|
||||
"{} hit the jackpot and won **{}** tildes!".format(
|
||||
name, p.number_to_words(jackpot)
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def show_jackpot(channel):
|
||||
with open(JACKPOT_FILE, "r") as jackpotfile:
|
||||
jackpot = int(jackpotfile.readline().strip("\n"))
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"The jackpot is currently {} tildes!".format(p.number_to_words(jackpot)),
|
||||
)
|
||||
|
||||
|
||||
def give_tilde(channel, user, name, time, human, bonus=0):
|
||||
found = False
|
||||
with open(SCORE_FILE, "r+") as scorefile:
|
||||
scores = scorefile.readlines()
|
||||
scorefile.seek(0)
|
||||
scorefile.truncate()
|
||||
for score in scores:
|
||||
name, score_on_file, timestamp = score.strip("\n").split("&^%")
|
||||
if name == user:
|
||||
found = True
|
||||
if too_recent(time, timestamp) and not DEBUG:
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{} asked for a tilde too recently and {}. Try again later.".format(
|
||||
name, get_bad_thing()
|
||||
),
|
||||
)
|
||||
else:
|
||||
prizevalue, prizetext = get_prize(name, human, bonus)
|
||||
score = "{}&^%{}&^%{}\n".format(
|
||||
name, str(int(score_on_file) + prizevalue), time
|
||||
)
|
||||
util.sendmsg(ircsock, channel, prizetext)
|
||||
scorefile.write(score)
|
||||
if not found:
|
||||
prizevalue, prizetext = get_prize(name, True, bonus)
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"Welcome to the tilde game! Here's {} free tildes to start you off.".format(
|
||||
p.number_to_words(prizevalue + 1)
|
||||
),
|
||||
)
|
||||
scorefile.write("{}&^%{}&^%{}\n".format(user, str(prizevalue + 1), time))
|
||||
|
||||
|
||||
def show_tildescore(channel, user, name):
|
||||
with open(SCORE_FILE, "r") as scorefile:
|
||||
for _idx, score in enumerate(scorefile):
|
||||
person = score.strip("\n").split("&^%")
|
||||
if person[0] == user:
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{} has {} tildes!".format(name, p.number_to_words(person[1])),
|
||||
)
|
||||
return
|
||||
# person has not played yet
|
||||
util.sendmsg(ircsock, channel, "{} has no tildes yet!".format(name))
|
||||
|
||||
|
||||
def challenge(channel, user, name, time):
|
||||
if channel != "#bots" and not DEBUG:
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{} is a meanie and gets no tildes. **Tildebot now only gives out tildes in the #bots channel.**".format(
|
||||
name
|
||||
),
|
||||
)
|
||||
return
|
||||
global challenges
|
||||
challenge = puzzle.make_puzzle()
|
||||
challenges[user] = challenge[1:]
|
||||
util.sendmsg(ircsock, channel, "{}: {}".format(name, challenge[0]))
|
||||
|
||||
|
||||
def challenge_response(channel, user, name, time, msg):
|
||||
global challenges
|
||||
print(msg)
|
||||
if user in challenges:
|
||||
answer, bonus = challenges[user]
|
||||
if (callable(answer) and answer(msg.lower())) or (
|
||||
msg.lower() == str(answer).lower() or msg == p.number_to_words(answer)
|
||||
):
|
||||
give_tilde(channel, user, name, time, True, bonus)
|
||||
else:
|
||||
give_tilde(channel, user, name, time, False, 0)
|
||||
del challenges[user]
|
||||
# delete the user from challenges either way
|
||||
|
||||
|
||||
def rollcall(channel):
|
||||
util.sendmsg(
|
||||
ircsock, channel, "tildebot reporting! I respond to !tilde !tildescore"
|
||||
)
|
||||
|
||||
|
||||
def listen():
|
||||
while 1:
|
||||
|
||||
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)
|
||||
# print(formatted)
|
||||
|
||||
if "" == formatted:
|
||||
continue
|
||||
|
||||
iTime, user, _command, channel, messageText = formatted.split("\t")
|
||||
name = util.get_name(user)
|
||||
|
||||
if msg.find(":!tildescore") != -1:
|
||||
show_tildescore(channel, user, name)
|
||||
elif msg.find(":!tilde") != -1 and user not in challenges:
|
||||
challenge(channel, user, name, iTime)
|
||||
elif user in challenges and (channel == "#bots" or DEBUG):
|
||||
challenge_response(channel, user, name, iTime, messageText)
|
||||
|
||||
if msg.find(":!jackpot") != -1:
|
||||
show_jackpot(channel)
|
||||
|
||||
if msg.find(":!rollcall") != -1:
|
||||
rollcall(channel)
|
||||
|
||||
sys.stdout.flush()
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
util.connect(ircsock, args)
|
||||
listen()
|
|
@ -1,215 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# http://wiki.shellium.org/w/Writing_an_IRC_bot_in_Python
|
||||
|
||||
# Import some necessary libraries.
|
||||
import socket
|
||||
import os
|
||||
import sys
|
||||
import fileinput
|
||||
import random
|
||||
import time
|
||||
import argparse
|
||||
|
||||
import inflect
|
||||
import util
|
||||
|
||||
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="topicbot",
|
||||
help="the nick to use",
|
||||
metavar="NICK",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
p = inflect.engine()
|
||||
|
||||
|
||||
def get_topic(channel, user, time):
|
||||
# topic scores are saved as <USER>&^%<GETS SCORE>&^%<SETS SCORE>
|
||||
with open("topicscores.txt", "r") as scorefile:
|
||||
scores = scorefile.readlines()
|
||||
userscore = 1
|
||||
found = False
|
||||
with open("topicscores.txt", "w") as scorefile:
|
||||
for idx, score in enumerate(scores):
|
||||
data = score.strip("\n").split("&^%")
|
||||
if data[0] == user:
|
||||
found = True
|
||||
userscore = int(data[1]) + 1
|
||||
scores[idx] = data[0] + "&^%" + str(userscore) + "&^%" + data[2] + "\n"
|
||||
scorefile.writelines(scores)
|
||||
if not found:
|
||||
scorefile.write(user + "&^%1&^%0\n")
|
||||
|
||||
with open("topics_" + channel + ".txt", "r") as topics:
|
||||
topic = topics.readlines()[-1].strip("\n").split("&^%", 3)
|
||||
byuser = util.get_name(topic[1])
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"I've told you {} times! It's \"{}\" (set by {} {})".format(
|
||||
p.number_to_words(userscore),
|
||||
topic[2],
|
||||
byuser,
|
||||
util.pretty_date(int(topic[0])),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def count_topic(channel, user, time, msg):
|
||||
with open("topics_" + channel + ".txt", "a") as topics:
|
||||
topics.write(time + "&^%" + user + "&^%" + msg + "\n")
|
||||
with open("topicscores.txt", "r") as scorefile:
|
||||
scores = scorefile.readlines()
|
||||
userscore = 1
|
||||
found = False
|
||||
with open("topicscores.txt", "w") as scorefile:
|
||||
for idx, score in enumerate(scores):
|
||||
data = score.strip("\n").split("&^%")
|
||||
if data[0] == user:
|
||||
found = True
|
||||
userscore = int(data[2]) + 1
|
||||
scores[idx] = data[0] + "&^%" + data[1] + "&^%" + str(userscore) + "\n"
|
||||
scorefile.writelines(scores)
|
||||
if not found:
|
||||
scorefile.write(user + "&^%0&^%1")
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{} has changed the topic {} times!".format(user, p.number_to_words(userscore)),
|
||||
)
|
||||
|
||||
|
||||
def set_topic(channel, user, time, msg):
|
||||
ircsock.send("TOPIC " + channel + " :" + msg + "\n")
|
||||
count_topic(channel, user, time, msg)
|
||||
|
||||
|
||||
def random_topic(channel, user, time, setTopic=False):
|
||||
with open("randomtopics.txt") as rtopics:
|
||||
msg = random.choice(rtopics.readlines()).strip("\n")
|
||||
if setTopic:
|
||||
set_topic(channel, user, time, msg)
|
||||
else:
|
||||
util.sendmsg(ircsock, channel, "Suggested Topic: {}".format(msg))
|
||||
|
||||
|
||||
def rollcall(channel):
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"topicbot reporting! I respond to !topic !settopic !suggesttopic !thistory",
|
||||
)
|
||||
|
||||
|
||||
def topic_score(channel):
|
||||
util.sendmsg(ircsock, channel, "Not implemented yet")
|
||||
|
||||
|
||||
def topic_scores(channel):
|
||||
util.sendmsg(ircsock, channel, "Not implemented yet")
|
||||
|
||||
|
||||
def topic_history(channel, user, count):
|
||||
try:
|
||||
iCount = int(count.split()[1])
|
||||
except (ValueError, IndexError):
|
||||
iCount = 3
|
||||
if iCount > 10:
|
||||
iCount = 10
|
||||
if iCount < 1:
|
||||
iCount = 3
|
||||
with open("topics_" + channel + ".txt", "r") as topicsfile:
|
||||
# topics = topicsfile.readlines()[-iCount:].reverse()
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"Ok, here are the last {} topics".format(p.number_to_words(iCount)),
|
||||
)
|
||||
for idx, topic in enumerate(reversed(topicsfile.readlines()[-iCount:])):
|
||||
topic = topic.strip("\n").split("&^%", 3)
|
||||
byuser = util.get_name(topic[1])
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{}: {} (set by {} {})".format(
|
||||
str(idx + 1), topic[2], byuser, util.pretty_date(int(topic[0]))
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def listen():
|
||||
while 1:
|
||||
|
||||
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
|
||||
|
||||
msgtime, user, command, channel, messageText = formatted.split("\t")
|
||||
|
||||
if command == "TOPIC" and user != args.nick:
|
||||
count_topic(channel, user, msgtime, messageText)
|
||||
|
||||
if msg.find(":!topic") != -1:
|
||||
get_topic(channel, user, msgtime)
|
||||
|
||||
if msg.find(":!settopic") != -1:
|
||||
set_topic(channel, user, msgtime, messageText[10:])
|
||||
|
||||
if msg.find(":!tscores") != -1:
|
||||
topic_scores(channel)
|
||||
elif msg.find(":!tscores") != -1:
|
||||
topic_score(channel)
|
||||
|
||||
if msg.find(":!randomtopic") != -1:
|
||||
random_topic(channel, user, msgtime, True)
|
||||
if msg.find(":!suggesttopic") != -1:
|
||||
random_topic(channel, user, msgtime, False)
|
||||
|
||||
if msg.find(":!thistory") != -1:
|
||||
topic_history(channel, user, messageText)
|
||||
|
||||
if msg.find(":!rollcall") != -1:
|
||||
rollcall(channel)
|
||||
|
||||
sys.stdout.flush()
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
util.connect(ircsock, args)
|
||||
listen()
|
|
@ -1,50 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
import urllib
|
||||
from bs4 import BeautifulSoup
|
||||
import random
|
||||
import re
|
||||
|
||||
|
||||
def tumble(url):
|
||||
# Find the max pages
|
||||
soup = BeautifulSoup(urllib.request.urlopen(url).read(), "html.parser")
|
||||
pages = soup.findAll("span", "page-numbers")[0].text.split("/")[
|
||||
1
|
||||
] # this could totally fail several ways
|
||||
tries = 3
|
||||
while True:
|
||||
try:
|
||||
page = random.randrange(1, int(pages) + 1)
|
||||
|
||||
# Parse a page
|
||||
soup = BeautifulSoup(
|
||||
urllib.request.urlopen(url + "/page/" + str(page)).read(), "html.parser"
|
||||
)
|
||||
article = random.choice(soup.findAll("article"))
|
||||
quote = article.find("blockquote").text.replace("\n", "")
|
||||
if len(article.find("footer").findAll("ul")) > 1:
|
||||
quote += re.sub(
|
||||
"\n+", " ", article.find("footer").findAll("ul")[0].text
|
||||
)
|
||||
# the hash tags
|
||||
quote += (
|
||||
"("
|
||||
+ re.sub("\n+", " ", article.find("footer").findAll("ul")[1].text)
|
||||
+ ")"
|
||||
)
|
||||
# and the date and notes
|
||||
else:
|
||||
quote += (
|
||||
"("
|
||||
+ re.sub("\n+", " ", article.find("footer").findAll("ul")[0].text)
|
||||
+ ")"
|
||||
)
|
||||
# just the date and notes
|
||||
|
||||
return quote
|
||||
except: # sometimes we fail. let's retry a few times
|
||||
if tries == 0:
|
||||
return ""
|
||||
else:
|
||||
tries -= 1
|
||||
break
|
282
Code/irc/util.py
282
Code/irc/util.py
|
@ -1,282 +0,0 @@
|
|||
import json
|
||||
import time
|
||||
import random
|
||||
import re
|
||||
|
||||
MAX_LINE = 400
|
||||
|
||||
|
||||
def ping(ircsock, msg):
|
||||
# print("{} => PONG {}".format(msg, msg.split(" ")[1]))
|
||||
ircsock.send("PONG {}\n".format(msg.split(" ")[1]).encode())
|
||||
|
||||
|
||||
def sendmsg(ircsock, chan, msg):
|
||||
print("sending {} to {}".format(msg, chan)[0:MAX_LINE])
|
||||
ircsock.send("PRIVMSG {} :{}\r\n".format(chan, msg).encode()[0:MAX_LINE])
|
||||
|
||||
def notice(ircsock, user, chan, msg):
|
||||
print("sending notice {} to {} in {}".format(msg, user, chan)[0:MAX_LINE])
|
||||
ircsock.send("CNOTICE {} {} :{}\r\n".format(user, chan, msg).encode()[0:MAX_LINE])
|
||||
|
||||
def part(ircsock, chan, msg="Bye!"):
|
||||
print("leaving channel {}".format(chan))
|
||||
ircsock.send("PART {} {}\r\n".format(chan, msg).encode())
|
||||
|
||||
def quit(ircsock, msg="Quitting!"):
|
||||
print("!! quitting !!")
|
||||
ircsock.send("QUIT {}".format(msg).encode())
|
||||
|
||||
def joinchan(ircsock, chan):
|
||||
print("joining {}".format(chan))
|
||||
ircsock.send("JOIN {}\r\n".format(chan).encode())
|
||||
|
||||
|
||||
def get_user_from_message(msg):
|
||||
try:
|
||||
i1 = msg.index(":") + 1
|
||||
i2 = msg.index("!")
|
||||
return msg[i1:i2]
|
||||
except ValueError:
|
||||
return ""
|
||||
|
||||
|
||||
def connect(ircsock, options):
|
||||
print(options)
|
||||
server, port = options.server.split(":")
|
||||
ircsock.connect((server, int(port)))
|
||||
print(ircsock)
|
||||
nick = "NICK {}\r\n".format(options.nick).encode()
|
||||
print(nick)
|
||||
ircsock.send(nick)
|
||||
login = "USER {0} {0} {0} {0}".format(options.nick).encode()
|
||||
print(login)
|
||||
ircsock.send(login)
|
||||
mode = "MODE +B {}\r\n".format(options.nick).encode()
|
||||
print(mode)
|
||||
ircsock.send(mode)
|
||||
if 'channels' in options:
|
||||
for channel in options.channels:
|
||||
joinchan(ircsock, channel)
|
||||
else:
|
||||
joinchan(ircsock, options.channel)
|
||||
|
||||
|
||||
# integer number to english word conversion
|
||||
# can be used for numbers as large as 999 vigintillion
|
||||
# (vigintillion --> 10 to the power 60)
|
||||
# tested with Python24 vegaseat 07dec2006
|
||||
def int2word(n):
|
||||
"""
|
||||
convert an integer number n into a string of english words
|
||||
"""
|
||||
# break the number into groups of 3 digits using slicing
|
||||
# each group representing hundred, thousand, million, billion, ...
|
||||
n3 = []
|
||||
r1 = ""
|
||||
# create numeric string
|
||||
ns = str(n)
|
||||
for k in range(3, 33, 3):
|
||||
r = ns[-k:]
|
||||
q = len(ns) - k
|
||||
# break if end of ns has been reached
|
||||
if q < -2:
|
||||
break
|
||||
else:
|
||||
if q >= 0:
|
||||
n3.append(int(r[:3]))
|
||||
elif q >= -1:
|
||||
n3.append(int(r[:2]))
|
||||
elif q >= -2:
|
||||
n3.append(int(r[:1]))
|
||||
r1 = r
|
||||
|
||||
# print n3 # test
|
||||
|
||||
# break each group of 3 digits into
|
||||
# ones, tens/twenties, hundreds
|
||||
# and form a string
|
||||
nw = ""
|
||||
for i, x in enumerate(n3):
|
||||
b1 = x % 10
|
||||
b2 = (x % 100) // 10
|
||||
b3 = (x % 1000) // 100
|
||||
# print b1, b2, b3 # test
|
||||
if x == 0:
|
||||
continue # skip
|
||||
else:
|
||||
t = thousands[i]
|
||||
if b2 == 0:
|
||||
nw = ones[b1] + t + nw
|
||||
elif b2 == 1:
|
||||
nw = tens[b1] + t + nw
|
||||
elif b2 > 1:
|
||||
nw = twenties[b2] + ones[b1] + t + nw
|
||||
if b3 > 0:
|
||||
nw = ones[b3] + "hundred " + nw
|
||||
return nw
|
||||
|
||||
|
||||
############# globals ################
|
||||
ones = [
|
||||
"",
|
||||
"one ",
|
||||
"two ",
|
||||
"three ",
|
||||
"four ",
|
||||
"five ",
|
||||
"six ",
|
||||
"seven ",
|
||||
"eight ",
|
||||
"nine ",
|
||||
]
|
||||
tens = [
|
||||
"ten ",
|
||||
"eleven ",
|
||||
"twelve ",
|
||||
"thirteen ",
|
||||
"fourteen ",
|
||||
"fifteen ",
|
||||
"sixteen ",
|
||||
"seventeen ",
|
||||
"eighteen ",
|
||||
"nineteen ",
|
||||
]
|
||||
twenties = [
|
||||
"",
|
||||
"",
|
||||
"twenty ",
|
||||
"thirty ",
|
||||
"forty ",
|
||||
"fifty ",
|
||||
"sixty ",
|
||||
"seventy ",
|
||||
"eighty ",
|
||||
"ninety ",
|
||||
]
|
||||
thousands = [
|
||||
"",
|
||||
"thousand ",
|
||||
"million ",
|
||||
"billion ",
|
||||
"trillion ",
|
||||
"quadrillion ",
|
||||
"quintillion ",
|
||||
"sextillion ",
|
||||
"septillion ",
|
||||
"octillion ",
|
||||
"nonillion ",
|
||||
"decillion ",
|
||||
"undecillion ",
|
||||
"duodecillion ",
|
||||
"tredecillion ",
|
||||
"quattuordecillion ",
|
||||
"sexdecillion ",
|
||||
"septendecillion ",
|
||||
"octodecillion ",
|
||||
"novemdecillion ",
|
||||
"vigintillion ",
|
||||
]
|
||||
|
||||
|
||||
def format_message(message):
|
||||
pattern = r"^:.*\!~(.*)@.* (.*) (.*) :(.*)"
|
||||
now = int(time.time())
|
||||
matches = re.match(pattern, message)
|
||||
if not matches:
|
||||
return ""
|
||||
|
||||
nick = matches.group(1).strip()
|
||||
command = matches.group(2).strip()
|
||||
channel = matches.group(3).strip()
|
||||
message = matches.group(4).strip()
|
||||
|
||||
return "%s\t%s\t%s\t%s\t%s" % (now, nick, command, channel, message)
|
||||
|
||||
|
||||
def get_users():
|
||||
# thanks, ~dan!
|
||||
users = []
|
||||
with open("/etc/passwd", "r") as f:
|
||||
for line in f:
|
||||
if "/bin/bash" in line:
|
||||
u = line.split(":")[0] # Grab all text before first ':'
|
||||
users.append(u)
|
||||
|
||||
return users
|
||||
|
||||
|
||||
def get_name(name):
|
||||
names_file = "/home/jumblesale/Code/canonical_names/canonical_names.json"
|
||||
try:
|
||||
with open(names_file) as names_data:
|
||||
names = json.load(names_data)
|
||||
try:
|
||||
return names[name]["userName"]
|
||||
except KeyError:
|
||||
return name
|
||||
except IOError:
|
||||
return name # if we didn't already
|
||||
|
||||
|
||||
def pretty_date(time=False):
|
||||
"""
|
||||
Get a datetime object or a int() Epoch timestamp and return a
|
||||
pretty string like 'an hour ago', 'Yesterday', '3 months ago',
|
||||
'just now', etc
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
now = datetime.now()
|
||||
if type(time) is int:
|
||||
diff = now - datetime.fromtimestamp(time)
|
||||
elif isinstance(time, datetime):
|
||||
diff = now - time
|
||||
elif not time:
|
||||
diff = now - now
|
||||
second_diff = diff.seconds
|
||||
day_diff = diff.days
|
||||
|
||||
if day_diff < 0:
|
||||
return ""
|
||||
|
||||
if day_diff == 0:
|
||||
if second_diff < 10:
|
||||
return "just now"
|
||||
if second_diff < 60:
|
||||
return str(second_diff) + " seconds ago"
|
||||
if second_diff < 120:
|
||||
return "a minute ago"
|
||||
if second_diff < 3600:
|
||||
return str(second_diff / 60) + " minutes ago"
|
||||
if second_diff < 7200:
|
||||
return "an hour ago"
|
||||
if second_diff < 86400:
|
||||
return str(second_diff / 3600) + " hours ago"
|
||||
if day_diff == 1:
|
||||
return "Yesterday"
|
||||
if day_diff < 7:
|
||||
return str(day_diff) + " days ago"
|
||||
if day_diff < 31:
|
||||
return str(day_diff / 7) + " weeks ago"
|
||||
if day_diff < 365:
|
||||
return str(day_diff / 30) + " months ago"
|
||||
return str(day_diff / 365) + " years ago"
|
||||
|
||||
|
||||
def makeRainbow(word):
|
||||
|
||||
word = word or "RAINBOW"
|
||||
output = ""
|
||||
rb = ["5", "7", "8", "3", "12", "13", "6"]
|
||||
bg = "01"
|
||||
idx = random.randrange(0, len(rb))
|
||||
|
||||
for l in word:
|
||||
if l == " ":
|
||||
output += " "
|
||||
else:
|
||||
output += "\x03" + rb[idx % len(rb)] + "," + bg + l
|
||||
idx += 1
|
||||
|
||||
return output
|
|
@ -1,322 +0,0 @@
|
|||
#!/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 time
|
||||
import re
|
||||
import operator
|
||||
|
||||
import inflect
|
||||
import util
|
||||
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option(
|
||||
"-s",
|
||||
"--server",
|
||||
dest="server",
|
||||
default="127.0.0.1:6667",
|
||||
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="wangbot",
|
||||
help="the nick to use",
|
||||
metavar="NICK",
|
||||
)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
p = inflect.engine()
|
||||
LIMIT_GUESSING = True
|
||||
MIN_ROUNDS = 5
|
||||
MAX_ROUNDS = 12
|
||||
SCORE_FILE = "numberwangscores.txt"
|
||||
SHOW_TOP_NUM = 5
|
||||
GOOD_CHAN = "#bots"
|
||||
|
||||
roundsLeft = 0
|
||||
bonusRound = 0
|
||||
guesses = 0
|
||||
lastGuesser = ""
|
||||
currentScores = {}
|
||||
|
||||
|
||||
def resetGlobals():
|
||||
global roundsLeft
|
||||
global bonusRound
|
||||
global guesses
|
||||
global lastGuesser
|
||||
global currentScores
|
||||
roundsLeft = 0
|
||||
bonusRound = 0
|
||||
guesses = 0
|
||||
lastGuesser = ""
|
||||
currentScores.clear()
|
||||
|
||||
|
||||
def start_numberwang(channel, user):
|
||||
if channel != "#bots":
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"Numberwang has been disabled in {} due to spamminess. Please join {} to start a game.".format(
|
||||
channel, GOOD_CHAN
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
print(user + " started a game")
|
||||
resetGlobals()
|
||||
util.sendmsg(ircsock, channel, "It's time for Numberwang!")
|
||||
time.sleep(1)
|
||||
util.sendmsg(ircsock, channel, "Here's how to play:")
|
||||
|
||||
util.sendmsg(ircsock, channel, "1. There are 10 rounds")
|
||||
util.sendmsg(
|
||||
ircsock, channel, "2. Each round lasts 10 seconds. You're up against the clock!"
|
||||
)
|
||||
util.sendmsg(
|
||||
ircsock, channel, "3. Play your numbers, as long as they're between 0 and 99."
|
||||
)
|
||||
util.sendmsg(ircsock, channel, "4. That's Numberwang!")
|
||||
time.sleep(2)
|
||||
util.sendmsg(ircsock, channel, "Let's get started!")
|
||||
global roundsLeft
|
||||
global bonusRound
|
||||
roundsLeft = random.randint(MIN_ROUNDS, MAX_ROUNDS)
|
||||
bonusRound = random.randint(2, roundsLeft - 1)
|
||||
print(
|
||||
"There will be {} rounds with the bonus on round {}".format(
|
||||
str(roundsLeft), str(roundsLeft - bonusRound + 1)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def print_scores(channel):
|
||||
scoreStrs = []
|
||||
first = True
|
||||
for name in currentScores:
|
||||
scoreStrs.append(
|
||||
"{} is {} on {}".format(
|
||||
name,
|
||||
("also " if not first and random.randint(1, 3) == 3 else ""),
|
||||
currentScores[name],
|
||||
)
|
||||
)
|
||||
first = False
|
||||
util.sendmsg(ircsock, channel, p.join(scoreStrs))
|
||||
|
||||
|
||||
def guess_numberwang(channel, user, messageText):
|
||||
global guesses
|
||||
global lastGuesser
|
||||
global currentScores
|
||||
global roundsLeft
|
||||
print(user + " guessed '" + messageText + "'")
|
||||
guess = re.sub(
|
||||
"[^0-9]", "", messageText.split()[0]
|
||||
) # must have a number in the first 'word'
|
||||
if guess:
|
||||
if LIMIT_GUESSING and user == lastGuesser:
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{}, you just guessed! Give another player a try!".format(user),
|
||||
)
|
||||
else:
|
||||
guesses += 1
|
||||
lastGuesser = user
|
||||
###CORRECT GUESS###
|
||||
if (
|
||||
random.randint(0, 10) > 10 - guesses
|
||||
): # the more guesses, the higher the probability
|
||||
guesses = 0
|
||||
lastGuesser = ""
|
||||
util.sendmsg(ircsock, channel, "{}: THAT'S NUMBERWANG!".format(user))
|
||||
points = random.randint(2, 10) * (
|
||||
random.randint(2, 4) if roundsLeft == bonusRound else 1
|
||||
)
|
||||
if user in currentScores.keys():
|
||||
currentScores[user] += points
|
||||
else:
|
||||
currentScores[user] = points
|
||||
roundsLeft -= 1
|
||||
time.sleep(2)
|
||||
if roundsLeft == 0:
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"Numberwang is now over. Thank you for playing!",
|
||||
)
|
||||
util.sendmsg(ircsock, channel, "Final scores:")
|
||||
print_scores(channel)
|
||||
save_scores()
|
||||
else:
|
||||
print_scores(channel)
|
||||
newRoundStr = ""
|
||||
if roundsLeft == 1:
|
||||
newRoundStr += "The last round is Wangernumb!"
|
||||
elif roundsLeft == bonusRound:
|
||||
newRoundStr += "**Bonus Round!**"
|
||||
else:
|
||||
newRoundStr += "New Round!"
|
||||
if random.randint(1, 10) > 8:
|
||||
newRoundStr += " Let's rotate the board!"
|
||||
util.sendmsg(
|
||||
ircsock, channel, "{} Start guessing!".format(newRoundStr)
|
||||
)
|
||||
|
||||
###INCORRECT GUESS###
|
||||
else:
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{}, {}, {} Numberwang!".format(
|
||||
random.choice(["Sorry", "I'm sorry", "No", "Nope"]),
|
||||
user,
|
||||
random.choice(
|
||||
[
|
||||
"that's not",
|
||||
"that is not",
|
||||
"that isn't",
|
||||
"that is not",
|
||||
"that won't make",
|
||||
"that will not make",
|
||||
]
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def stop_numberwang(channel, user):
|
||||
print(user + " stopped a game")
|
||||
resetGlobals()
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"Numberwang has been stopped. No points have been awarded. {} is such a party pooper!".format(
|
||||
user
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def save_scores():
|
||||
with open(SCORE_FILE, "r+") as scorefile:
|
||||
scores = scorefile.readlines()
|
||||
scorefile.seek(0)
|
||||
scorefile.truncate()
|
||||
for line in scores:
|
||||
for name in currentScores:
|
||||
score = line.strip("\n").split("&^%")
|
||||
if score[0] == name:
|
||||
line = "{}&^%{}\n".format(
|
||||
score[0], int(score[1]) + currentScores[name]
|
||||
)
|
||||
del currentScores[name]
|
||||
break
|
||||
scorefile.write(line)
|
||||
|
||||
for name in currentScores: # new wangers
|
||||
scorefile.write("{}&^%{}\n".format(name, currentScores[name]))
|
||||
|
||||
|
||||
def show_highscores(channel):
|
||||
with open(SCORE_FILE, "r") as scorefile:
|
||||
scores = []
|
||||
for line in scorefile.readlines():
|
||||
sline = line.strip("\n").split("&^%")
|
||||
scores.append((int(sline[1]), sline[0]))
|
||||
scores = sorted(scores, reverse=True)[:SHOW_TOP_NUM]
|
||||
|
||||
util.sendmsg(ircsock, channel, "====TOP WANGERS====")
|
||||
for score in scores:
|
||||
util.sendmsg(
|
||||
ircsock, channel, " :== ~{} ({} points!) ==".format(score[1], score[0])
|
||||
)
|
||||
|
||||
|
||||
def show_user_score(channel, user):
|
||||
with open(SCORE_FILE, "r") as scorefile:
|
||||
for line in scorefile.readlines():
|
||||
score = line.strip("\n").split("&^%")
|
||||
if user == score[0]:
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"{}: Your global numberwang score is {}!".format(user, score[1]),
|
||||
)
|
||||
return
|
||||
# if we don't find a score line
|
||||
util.sendmsg(
|
||||
ircsock, channel, "{} You haven't scored any points yet!".format(user)
|
||||
)
|
||||
|
||||
|
||||
def rollcall(channel):
|
||||
util.sendmsg(
|
||||
ircsock,
|
||||
channel,
|
||||
"Is it time for Numberwang? It might be! Start a new game with !numberwang or stop a current game with !wangernumb Get your score with !myscore and the list of top wangers with !topwangers",
|
||||
)
|
||||
|
||||
|
||||
def listen():
|
||||
while 1:
|
||||
|
||||
ircmsg = ircsock.recv(2048).decode("utf-8")
|
||||
ircmsg = ircmsg.strip("\n\r")
|
||||
|
||||
if ircmsg[:4] == "PING":
|
||||
util.ping(ircsock, ircmsg)
|
||||
|
||||
formatted = util.format_message(ircmsg)
|
||||
|
||||
if "" == formatted:
|
||||
continue
|
||||
|
||||
# print formatted
|
||||
|
||||
_time, user, _command, channel, messageText = formatted.split("\t")
|
||||
|
||||
if ircmsg.find(":!numberwang") != -1 and roundsLeft == 0:
|
||||
start_numberwang(channel, user)
|
||||
|
||||
if channel == GOOD_CHAN:
|
||||
if ircmsg.find(":!wangernumb") != -1 and roundsLeft > 0:
|
||||
stop_numberwang(channel, user)
|
||||
if roundsLeft > 0:
|
||||
guess_numberwang(channel, user, messageText)
|
||||
|
||||
if ircmsg.find(":!topwangers") != -1:
|
||||
show_highscores(channel)
|
||||
if ircmsg.find(":!myscore") != -1:
|
||||
show_user_score(channel, user)
|
||||
|
||||
if ircmsg.find(":!rollcall") != -1:
|
||||
rollcall(channel)
|
||||
|
||||
sys.stdout.flush()
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
util.connect(ircsock, options)
|
||||
listen()
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
|
||||
def get_thing():
|
||||
file = "/home/krowbar/logs/welchdata.txt"
|
||||
thing = ""
|
||||
return (
|
||||
"Thing Mr. Welch can no longer do in a RPG #"
|
||||
+ random.choice(list(open(file))).rstrip()
|
||||
)
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
import fileinput
|
||||
import time
|
||||
import calendar
|
||||
import re
|
||||
import operator
|
||||
|
||||
MAX_NODES = 5
|
||||
|
||||
logfile = "/home/archangelic/irc/log"
|
||||
timeCutoff = calendar.timegm(time.gmtime()) - (3 * 7 * 24 * 60 * 60) # 3 weeks
|
||||
|
||||
nameFix = {
|
||||
"jumblesal": "jumblesale",
|
||||
"hardmath1": "kc",
|
||||
"hardmath123": "kc",
|
||||
"bendorphan": "endorphant",
|
||||
"endorphan": "endorphant",
|
||||
"synergian": "synergiance",
|
||||
}
|
||||
|
||||
|
||||
def whoSaid(word):
|
||||
word = word.lower()
|
||||
userData = (
|
||||
{}
|
||||
) # hash keyed by "user" that contains a hash of mentioned other users with count
|
||||
# Get a list of all user names by checking the logs for people who have said things
|
||||
with open(logfile, "r") as log:
|
||||
for line in log:
|
||||
try:
|
||||
time, user, message = line.split("\t", 3)
|
||||
time = int(time)
|
||||
if user in nameFix:
|
||||
user = nameFix[user]
|
||||
else:
|
||||
user = user.lower()
|
||||
except ValueError:
|
||||
continue # There are some bad lines in the log file that we'll ignore if we can't parse
|
||||
|
||||
if time > timeCutoff and message[0] is not "!" and word in message.lower():
|
||||
if user in userData:
|
||||
userData[user] += 1
|
||||
else:
|
||||
userData[user] = 1
|
||||
userData = sorted(userData.items(), key=operator.itemgetter(1), reverse=True)
|
||||
return {"timecutoff": timeCutoff, "data": userData}
|
|
@ -1,87 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
from bs4 import BeautifulSoup
|
||||
import random
|
||||
import requests
|
||||
|
||||
|
||||
def get_philosophy(word, max_steps=20):
|
||||
step_words = [word]
|
||||
steps = 0
|
||||
|
||||
url = "https://en.wikipedia.org/wiki/%s" % word
|
||||
while steps < max_steps:
|
||||
print("url: {}".format(url))
|
||||
soup = BeautifulSoup(requests.get(url).content, "html.parser")
|
||||
title = soup.find("h1", id="firstHeading")
|
||||
content = soup.find("div", id="mw-content-text")
|
||||
if not content:
|
||||
break
|
||||
item = [
|
||||
item
|
||||
for item in content.find_all("a")
|
||||
if not item.get("class")
|
||||
and not item.get("target")
|
||||
and item.get("title")
|
||||
and not "Wikipedia:" in item.get("title")
|
||||
and not "Category:" in item.get("title")
|
||||
and not "Help:" in item.get("title")
|
||||
and not "Portal:" in item.get("title")
|
||||
and not "Special:" in item.get("title")
|
||||
and not "Talk:" in item.get("title")
|
||||
and not "Template:" in item.get("title")
|
||||
and not "File:" in item.get("title")
|
||||
and "Edit section:" not in item.get("title")
|
||||
and "Commons:" not in item.get("title")
|
||||
and not item.get("title") in step_words
|
||||
][0]
|
||||
step_words.append(item.get("title"))
|
||||
# print item.get('title') + "\n"
|
||||
url = "https://en.wikipedia.org{}".format(item.get("href"))
|
||||
steps += 1
|
||||
return step_words
|
||||
|
||||
|
||||
def containsAny(str, set):
|
||||
return 1 in [c in str for c in set]
|
||||
|
||||
|
||||
def get_philosophy_lower(word, max_steps=20):
|
||||
step_words = [word]
|
||||
steps = 0
|
||||
|
||||
url = "https://en.wikipedia.org/wiki/{}".format(word.replace(" ", "%20"))
|
||||
while steps < max_steps:
|
||||
print("url: {}".format(url))
|
||||
soup = BeautifulSoup(requests.get(url).content, "html.parser")
|
||||
|
||||
if soup.find(id="noarticletext"):
|
||||
step_words.append("(not found)")
|
||||
break
|
||||
|
||||
title = soup.find("h1", id="firstHeading")
|
||||
content = soup.find("div", id="mw-content-text")
|
||||
if not content:
|
||||
break
|
||||
links = [
|
||||
item
|
||||
for item in content.find_all("a")
|
||||
if not item.get("class")
|
||||
and item.text
|
||||
and item.text[0].islower()
|
||||
and not containsAny(item.text, ":()")
|
||||
and item.get("title")
|
||||
and not containsAny(item.get("title"), ":()")
|
||||
and not item.get("title") in step_words
|
||||
]
|
||||
if not links:
|
||||
step_words.append("(dead end)")
|
||||
break
|
||||
item = links[0] # grab the first good link item
|
||||
# print "Checking %s %s" % (item.get('title'), item.text)
|
||||
step_words.append(item.get("title"))
|
||||
if item.get("title") == "Philosophy":
|
||||
break
|
||||
# print item.get('title') + "\n"
|
||||
url = "https://en.wikipedia.org%s" % item.get("href")
|
||||
steps += 1
|
||||
return step_words
|
|
@ -1,32 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
import duckduckgo
|
||||
import urllib
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
def xkcd(query):
|
||||
res = duckduckgo.get_zci("site:xkcd.com " + query)
|
||||
title = ""
|
||||
try: # ddg returns a url for these searches. i want a title as well
|
||||
title = BeautifulSoup(urllib.urlopen(res).read(), "html.parser").title.text
|
||||
except:
|
||||
pass # just swallow the error. maybe the result wasn't a url or something else bad happened
|
||||
return [(((title + " - ") if title else "") + res)]
|
||||
|
||||
|
||||
# never mind, blocked by ddg
|
||||
# def xkcd_links(query):
|
||||
# url = "https://duckduckgo.com/html/?q=site%3Axkcd.com+" + query.replace(' ', '+')
|
||||
# soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser')
|
||||
# items = soup.find_all("a", class_="result__a")
|
||||
# print items
|
||||
# items = list(filter(lambda i: i[0:8] == 'xkcd.com',
|
||||
# [i.find(class_="result__title").text.strip() for i in items]))
|
||||
# print items
|
||||
# def pretty_link(item):
|
||||
# url = item.find(class_="result__url").text.strip()
|
||||
# title = item.find(class_="result__title").text.strip()
|
||||
# return (title + ' - ' + url) if title else url
|
||||
#
|
||||
# links = map(lambda url: pretty_link(url), items)
|
||||
# return links
|
Loading…
Reference in New Issue