This commit is contained in:
RussellChamp committed 2018-10-25 10:41:09 -04:00
commit 6770c70068
43 files changed
+4277 -2753

No files matched your search

+1 -1
View File
@@ -102,7 +102,7 @@ fi
PERL_MB_OPT="--install_base \"/home/krowbar/perl5\""; export PERL_MB_OPT; PERL_MB_OPT="--install_base \"/home/krowbar/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/krowbar/perl5"; export PERL_MM_OPT; PERL_MM_OPT="INSTALL_BASE=/home/krowbar/perl5"; export PERL_MM_OPT;
export TZ=EDT TZ='America/Detroit'; export TZ
export PS1='$(beats):'$PS1 export PS1='$(beats):'$PS1
man() { man() {
+2
View File
@@ -0,0 +1,2 @@
*.pyc
__pycache__/
+90 -57
View File
@@ -3,63 +3,96 @@ from bs4 import BeautifulSoup
import random import random
import string import string
dict = '/usr/share/dict/american-english' dict = "/usr/share/dict/american-english"
(userId,token) = open("/home/krowbar/.secret/s4token").readline().rstrip().split(',') (userId, token) = open("/home/krowbar/.secret/s4token").readline().rstrip().split(",")
def get_acros(word, silly, short): def get_acros(word, silly, short):
acros = [] acros = []
url = "http://www.stands4.com/services/v2/abbr.php?uid=%s&tokenid=%s&term=%s" % (userId, token, word) url = "http://www.stands4.com/services/v2/abbr.php?uid={}&tokenid={}&term={}".format(
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html5lib') userId, token, word
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 soup = BeautifulSoup(urllib.urlopen(url).read(), "html5lib")
defs = [] results = soup.find_all("result")
for r in results: # 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
rdef = r.find('definition').text defs = []
match = next((x for x in defs if x['definition'].lower() == rdef.lower()), None) for r in results:
if match is not None: rdef = r.find("definition").text
#if we find a match, add the category to the existing categories and increase the score match = next((x for x in defs if x["definition"].lower() == rdef.lower()), None)
match['categories'].append(((r.find('parentcategoryname').text + '\\') if r.find('parentcategoryname') else '') + r.find('categoryname').text) if match is not None:
match['score'] = str(float(match['score']) + float(r.find('score').text)) # if we find a match, add the category to the existing categories and increase the score
else: #add a new item match["categories"].append(
defs.append({\ (
'term': r.find('term').text,\ (r.find("parentcategoryname").text + "\\")
'definition': r.find('definition').text,\ if r.find("parentcategoryname")
'categories': [((r.find('parentcategoryname').text + '\\') if r.find('parentcategoryname') else '') + r.find('categoryname').text],\ else ""
'score': r.find('score').text\ )
}); + 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): for d in sorted(defs, key=lambda x: float(x["score"]), reverse=True):
#print d; # print d;
if short is True: if short is True:
acros.append("\"%s\"" % d['definition']) acros.append('"%s"' % d["definition"])
else: else:
acros.append(("%s: \"%s\" (%s, score: %s)" % \ acros.append(
(d['term'], d['definition'], ', '.join(d['categories']), d['score'])\ (
).encode('ascii', 'ignore')) '{}: "{}" ({}, score: {})'.format(
if silly is True: d["term"],
newDef = [] d["definition"],
words = open(dict, 'r').readlines() ", ".join(d["categories"]),
try: d["score"],
for idx,letter in enumerate(word): )
newWord = random.choice(\ ).encode("ascii", "ignore")
filter(lambda w: (idx is 0 or not w.strip().lower().endswith('\'s'))\ )
and w.lower().startswith(letter.lower()), words)\ if silly is True:
).strip() newDef = []
print str(idx) + ' -> ' + newWord words = open(dict, "r").readlines()
newDef.append(newWord) try:
newWord = string.capwords(' '.join(newDef)) for idx, letter in enumerate(word):
if short is True: newWord = random.choice(
acros.append("\"%s\"" % newWord) filter(
else: lambda w: (idx is 0 or not w.strip().lower().endswith("'s"))
acros.append(("%s: \"%s\" (%s, score: %s)" % \ and w.lower().startswith(letter.lower()),
(word.upper(), newWord, 'Tilde.town Original', '0')\ words,
).encode('ascii', 'ignore')) )
except IndexError: ).strip()
acros.append("Future hazy, try again later: Tilde.town Error"); print(str(idx) + " -> " + newWord)
if short is True: newDef.append(newWord)
shortList = acros[0:5] newWord = string.capwords(" ".join(newDef))
if len(acros) > 5: if short is True:
shortList.append(acros[-1]) acros.append('"%s"' % newWord)
return [word.upper() + ': ' + ', '.join(shortList)] else:
else: acros.append(
return acros (
'{}: "{}" ({}, score: {})'.format(
word.upper(), newWord, "Tilde.town Original", "0"
)
).encode("ascii", "ignore")
)
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
+269 -197
View File
@@ -10,50 +10,62 @@ import fileinput
import random import random
import re import re
import subprocess import subprocess
import textwrap
import time import time
import datetime import datetime
import formatter
import get_users
import mentions
import pretty_date
import inflect import inflect
from rhymesWith import getRhymes from rhymesWith import getRhymes
from rhymesWith import rhymeZone from rhymesWith import rhymeZone
from defineWord import defWord from defineWord import defWord
from rainbow import makeRainbow
import welch import welch
import evil import evil
import tumblr import tumblr
import xkcdApropos import xkcdApropos
import wikiphilosophy import wikiphilosophy
import acronymFinder import acronymFinder
import util
from whosaid import whoSaid from whosaid import whoSaid
parser = OptionParser() parser = OptionParser()
parser.add_option("-s", "--server", dest="server", default='127.0.0.1', parser.add_option(
help="the server to connect to", metavar="SERVER") "-s",
parser.add_option("-c", "--channel", dest="channel", default='#bot_test', "--server",
help="the channel to join", metavar="CHANNEL") dest="server",
parser.add_option("-n", "--nick", dest="nick", default='tildebot', default="127.0.0.1:6667",
help="the nick to use", metavar="NICK") 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="banterbot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
p = inflect.engine() p = inflect.engine()
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan): def joinchan(chan):
ircsock.send("JOIN "+ chan +"\n") ircsock.send("JOIN " + chan + "\r\n")
def hello(): def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n") util.sendmsg(ircsoc, channel, "Hello!")
def score_banter(channel, user, messageText): def score_banter(channel, user, messageText):
score = 5 score = 5
@@ -63,286 +75,346 @@ def score_banter(channel, user, messageText):
for word in words: for word in words:
for bant in bantz: for bant in bantz:
bword = bant.strip("\n").split("|") bword = bant.strip("\n").split("|")
if re.sub('[^a-z0-9]+','',word.lower()) == bword[0]: if re.sub("[^a-z0-9]+", "", word.lower()) == bword[0]:
score += int(bword[1]) score += int(bword[1])
score += messageText.count('!') * 2 #hype is banter score += messageText.count("!") * 2 # hype is banter
score -= messageText.count('!!!') * 6 #too much hype is not banter score -= messageText.count("!!!") * 6 # too much hype is not banter
score += messageText.count('#') * 3 #hashs are mad bantz score += messageText.count("#") * 3 # hashs are mad bantz
score -= messageText.count('##') * 6 #but too many is garbage score -= messageText.count("##") * 6 # but too many is garbage
names = ['mate', 'lad', 'my best boy'] names = ["mate", "lad", "my best boy"]
compliment = ['top-drawer', 'top-shelf', 'bangin\'', 'legendary', 'smashing', 'incredible', 'impeccable', 'stunning'] compliment = [
"top-drawer",
"top-shelf",
"bangin'",
"legendary",
"smashing",
"incredible",
"impeccable",
"stunning",
]
msg = "" msg = ""
if score > 100: if score > 100:
msg = "Truely " + random.choice(compliment).capitalize() + ", " + random.choice(names) \ msg = "Truely {}, {}! That was some #banter! You earned a {} for that!".format(
+ "! That was some #banter! You earned a " + str(score) + " for that!" random.choice(compliment).capitalize(), random.choice(names), score
)
elif score > 50: elif score > 50:
msg = random.choice(compliment).capitalize() + " #banter! You get a " + str(score) + " from me!" msg = "{} #banter! You get a {} from me!".format(
random.choice(compliment).capitalize(), score
)
elif score > 10: elif score > 10:
msg = random.choice(["acceptible", "reasonable", "passable"]).capitalize() + " #banter. You get a " + str(score) msg = "{} #banter. You get a {}".format(
random.choice(["acceptible", "reasonable", "passable"]).capitalize(), score
)
else: else:
msg = "That " + random.choice(["was hardly", "was barely", "wasn't", "won't pass for", "was awful"]) \ msg = "That {} #banter, {}. I'll give you a {}. Maybe try again?".format(
+ " #banter" + random.choice([", lad",", lah",", boy","",""]) + ". I'll give you a " + str(score) + ". Maybe try again?" 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)
ircsock.send("PRIVMSG " + channel + " :" + msg + "\n")
def get_new_banter(channel, user): def get_new_banter(channel, user):
with open("/usr/share/dict/words", "r") as dict: with open("/usr/share/dict/words", "r") as dict:
words = filter(lambda word:re.search(r"^[^']*$", word), dict.readlines()) words = filter(lambda word: re.search(r"^[^']*$", word), dict.readlines())
if(random.randint(0,1)): #look for *ant words if random.randint(0, 1): # look for *ant words
words = filter(lambda word:re.search(r"ant", word), words) words = filter(lambda word: re.search(r"ant", word), words)
random.shuffle(words) random.shuffle(words)
word = words[0].strip("\n") word = words[0].strip("\n")
start = word.find('ant') start = word.find("ant")
if(start == 0): if start == 0:
word = 'b' + word word = "b" + word
else: else:
if('aeiou'.find(word[start]) > -1): #just append a 'b' if "aeiou".find(word[start]) > -1: # just append a 'b'
word = word[:start] + 'b' + word[start:] word = word[:start] + "b" + word[start:]
else: #replace the letter with 'b' else: # replace the letter with 'b'
word = word[:start-1] + 'b' + word[start:] word = word[: start - 1] + "b" + word[start:]
else: #look for ban* words else: # look for ban* words
words = filter(lambda word:re.search(r"ban", word), words) words = filter(lambda word: re.search(r"ban", word), words)
random.shuffle(words) random.shuffle(words)
word = words[0].strip("\n") word = words[0].strip("\n")
end = word.find('ban') + 3 end = word.find("ban") + 3
if(end == len(word)): if end == len(word):
word = word + 't' word = word + "t"
else: else:
if('aeiou'.find(word[end]) > -1): #just append 't' if "aeiou".find(word[end]) > -1: # just append 't'
word = word[:end] + 't' + word[end:] word = word[:end] + "t" + word[end:]
else: #replace the letter with 'b' else: # replace the letter with 'b'
word = word[:end] + 't' + word[end+1:] word = word[:end] + "t" + word[end + 1 :]
ircsock.send("PRIVMSG " + channel + " :" + user + ": Here, why don't you try '" + word + "'?\n") util.sendmsg(
ircsock, channel, "{} : Here, why don't you try '{}'?".format(user, word)
)
def get_rhymes(channel, user, text): def get_rhymes(channel, user, text):
word = "" word = ""
if(len(text.split(' ')) > 1): if len(text.split(" ")) > 1:
word = text.split(' ')[1] word = text.split(" ")[1]
else: else:
with open("/home/nossidge/poems/words_poetic.txt", "r") as words: with open("/home/nossidge/poems/words_poetic.txt", "r") as words:
word = random.choice(words.readlines()).strip("\n") word = random.choice(words.readlines()).strip("\n")
rhymes = rhymeZone(word) rhymes = rhymeZone(word)
if(len(rhymes) == 0): if len(rhymes) == 0:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Couldn't find anything that rhymes with '" + word + "' :(\n") util.sendmsg(
ircsock,
channel,
"{}: Couldn't find anything that rhymes with '{}' :(".format(user, word),
)
else: else:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Here, these words rhyme with '" + word + "': " + ', '.join(rhymes) + "\n") util.sendmsg(
ircsock,
channel,
"{}: Here, these words rhyme with '{}': {}".format(
user, word, ", ".join(rhymes)
),
)
def define_word(channel, user, text): def define_word(channel, user, text):
word = "" word = ""
defs = [] defs = []
if(len(text.split(' ')) > 1): if len(text.split(" ")) > 1:
word = text.split(' ')[1] word = text.split(" ")[1]
defs = defWord(word) defs = defWord(word)
if(len(defs) == 0): if len(defs) == 0:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Couldn't find the definition of '" + word + "' :(\n") util.sendmsg(
elif(isinstance(defs, list)): ircsock,
channel,
"{}: Couldn't find the definition of '{}' :(".format(user, word),
)
elif isinstance(defs, list):
for entry in defs: for entry in defs:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Define '" + word + "'" + entry[0:400] + "\n") util.sendmsg(
ircsock, channel, "{} : Define '{}' {}".format(user, word, entry[0:400])
)
else: else:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Define '" + word + "'" + defs[0:400] + "\n") util.sendmsg(
ircsock, channel, "{} : Define '{}' {}".format(user, word, defs[0:400])
)
def make_rainbow(channel, user, text): def make_rainbow(channel, user, text):
rbword = makeRainbow(text[9:]) rbword = util.makeRainbow(text[9:])
ircsock.send("PRIVMSG " + channel + " :" + rbword + "\n") util.sendmsg(ircsock, channel, rbword)
def get_welch(channel): def get_welch(channel):
ircsock.send("PRIVMSG " + channel + " :" + welch.get_thing()[0:400] + "\n") util.sendmsg(ircsock, channel, welch.get_thing()[0:400])
def get_evil(channel): def get_evil(channel):
evilThing = evil.get_thing() evilThing = evil.get_thing()
for line in [evilThing[i:i+400] for i in range(0, len(evilThing), 400)]: for line in [evilThing[i : i + 400] for i in range(0, len(evilThing), 400)]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n") util.sendmsg(ircsock, channel, line)
def get_tumble(url, channel): def get_tumble(url, channel):
tumble = tumblr.tumble(url) tumble = tumblr.tumble(url)
for line in [tumble[i:i+400] for i in range(0, len(tumble), 400)]: for line in [tumble[i : i + 400] for i in range(0, len(tumble), 400)]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n") util.sendmsg(ircsock, channel, line)
def get_xkcd(channel, text): def get_xkcd(channel, text):
links = xkcdApropos.xkcd(text[6:]) links = xkcdApropos.xkcd(text[6:])
joined_links = ', '.join(links) joined_links = ", ".join(links)
for line in [joined_links[i:i+400] for i in range(0, len(joined_links), 400)]: for line in [joined_links[i : i + 400] for i in range(0, len(joined_links), 400)]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n") util.sendmsg(ircsock, channel, line)
#res = xkcdApropos.xkcd(text[6:]) # res = xkcdApropos.xkcd(text[6:])
#ircsock.send("PRIVMSG " + channel + " :" + res + "\n") # ircsock.send("PRIVMSG " + channel + " :" + res + "\n")
def get_wphilosophy(channel, text): def get_wphilosophy(channel, text):
steps = wikiphilosophy.get_philosophy_lower(text[17:]) steps = wikiphilosophy.get_philosophy_lower(text[17:])
if not steps: if not steps:
ircsock.send("PRIVMSG " + channel + " :Couldn't find a wikipedia entry for " + text + "\n") util.sendmsg(
else: ircsock, channel, "Couldn't find a wikipedia entry for {}".format(text)
joined_steps = ' > '.join(steps) )
if steps[-1] == 'Philosophy': else:
joined_steps += "!!!" joined_steps = " > ".join(steps)
for line in [joined_steps[i:i+400] for i in range(0, len(joined_steps), 400)]: if steps[-1] == "Philosophy":
ircsock.send("PRIVMSG " + channel + " :" + line + "\n") 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): def figlet(channel, text):
if not text: if not text:
ircsock.send("PRIVMSG " + channel + " :No text given. :(\n") util.sendmsg(ircsock, channel, "No text given. :(")
else: else:
lines = subprocess.Popen(["figlet", "-w140"] + text.split(' '), shell=False, stdout=subprocess.PIPE).stdout.read() lines = subprocess.Popen(
for line in lines.split('\n'): ["figlet", "-w140"] + text.split(" "), shell=False, stdout=subprocess.PIPE
ircsock.send("PRIVMSG " + channel + " :" + line + "\n") ).stdout.read()
time.sleep(0.4) #to avoid channel throttle due to spamming 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): def toilet(channel, text):
if not text: if not text:
ircsock.send("PRIVMSG " + channel + " :No text given. :(\n") util.sendmsg(ircsock, channel, "No text given. :(")
else: else:
lines = subprocess.Popen(["toilet", "-w140", "--irc"] + text.split(' '), shell=False, stdout=subprocess.PIPE).stdout.read() lines = subprocess.Popen(
for line in lines.split('\n'): ["toilet", "-w140", "--irc"] + text.split(" "),
ircsock.send("PRIVMSG " + channel + " :" + line + "\n") shell=False,
time.sleep(0.4) #to avoid channel throttle due to spamming stdout=subprocess.PIPE,
).stdout.read()
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): def get_acronym(channel, text):
if not text: if not text:
ircsock.send("PRIVMSG " + channel + " :No text given :(\n") util.sendmsg(ircsock, channel, "No text given :(")
else: else:
defs = acronymFinder.get_acros(text, True, True) defs = acronymFinder.get_acros(text, True, True)
for d in defs[0:5]: #only the first five. they are already sorted by 'score' for d in defs[0:5]: # only the first five. they are already sorted by 'score'
ircsock.send("PRIVMSG " + channel + " :" + d.encode('utf-8') + "\n") util.sendmsg(ircsock, channel, d.encode("utf-8"))
if len(defs) > 5: if len(defs) > 5:
ircsock.send("PRIVMSG " + channel + " :" + defs[-1] + "\n") util.sendmsg(ircsock, channel, defs[-1])
def get_whosaid(channel, text): def get_whosaid(channel, text):
if not text: if not text:
ircsock.send("PRIVMSG " + channel + " :No text given :(\n") 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: else:
msg = 'Since %s, %s said \'%s\' %d times' % (dateStr, result['data'][0][0], text, result['data'][0][1]) result = whoSaid(text)
if len(result['data']) > 1: date = datetime.date.fromtimestamp(result["timecutoff"])
msg += ' and %s said it %d times' % (result['data'][1][0], result['data'][1][1]) dateStr = date.strftime("%B %d")
ircsock.send("PRIVMSG " + channel + " :" + msg + ".\n") 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): def get_notice(user, channel):
ircsock.send("CNOTICE " + user + " " + channel + " :Notice me sempai!\n") ircsock.send("CNOTICE " + user + " " + channel + " :Notice me senpai!\r\n")
def get_water(user, channel, msg, botnick): def get_water(user, channel, msg, botnick):
if msg.find(botnick) == 0: if msg.find(botnick) == 0:
ircsock.send("PRIVMSG " + channel + " :Fight me, " + user + "!\n") util.sendmsg(ircsock, channel, "Fight me, {}!".format(user))
def mug_off(channel): def mug_off(channel):
ircsock.send("PRIVMSG " + channel + " :u want some of this, m8?\n") util.sendmsg(ircsock, channel, "u want some of this, m8?")
def rollcall(channel): def rollcall(channel):
ircsock.send("PRIVMSG "+ channel +" :U wot m8? I score all the top drawer #banter and #bantz on this channel! \ text = """
Find new top-shelf banter with !newbanter, !rhymes, and !define. \ U wot m8? I score all the top drawer #banter and #bantz on this channel!
Look up things with !acronym and !whosaid. \ Find new top-shelf banter with !newbanter, !rhymes, and !define.
Make your chatter #legend with !rainbow, !toilet, and !figlet. \ Look up things with !acronym and !whosaid.
Find interesting things with !xkcd and !wiki-philosophy. \ Make your chatter #legend with !rainbow, !toilet, and !figlet.
Get jokes with !welch and !evil\n") Find interesting things with !xkcd and !wiki-philosophy.
Get jokes with !welch and !evil
"""
for line in textwrap.dedent(text).split("\n"):
if line == "":
continue
util.sendmsg(ircsock, channel, line)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :krowbar\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
joinchan(channel)
joinchan("#bots")
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
def listen(botnick): def listen(botnick):
while 1: while 1:
ircmsg = ircsock.recv(2048) ircmsg = ircsock.recv(2048).decode()
ircmsg = ircmsg.strip('\n\r') ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING": if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1]) util.ping(ircsock, ircmsg)
formatted = formatter.format_message(ircmsg) formatted = util.format_message(ircmsg)
if "" == formatted: if "" == formatted:
continue continue
# print formatted # print formatted
split = formatted.split("\t") _time, user, _command, channel, messageText = formatted.split("\t")
#time = split[0]
user = split[1]
command = split[2]
channel = split[3]
messageText = split[4]
if ircmsg.find("#banter") != -1 or ircmsg.find("#bantz") != -1: if ircmsg.find("#banter") != -1 or ircmsg.find("#bantz") != -1:
score_banter(channel, user, messageText) score_banter(channel, user, messageText)
if ircmsg.find(":!newbanter") != -1: if ircmsg.find(":!newbanter") != -1:
get_new_banter(channel, user) get_new_banter(channel, user)
if ircmsg.find(":!rhymes") != -1: if ircmsg.find(":!rhymes") != -1:
get_rhymes(channel, user, messageText) get_rhymes(channel, user, messageText)
if ircmsg.find(":!define") != -1: if ircmsg.find(":!define") != -1:
define_word(channel, user, messageText) define_word(channel, user, messageText)
if ircmsg.find(":!rainbow") != -1: if ircmsg.find(":!rainbow") != -1:
make_rainbow(channel, user, messageText) make_rainbow(channel, user, messageText)
if ircmsg.find(":!welch") != -1: if ircmsg.find(":!welch") != -1:
get_welch(channel) get_welch(channel)
if ircmsg.find(":!evil") != -1: if ircmsg.find(":!evil") != -1:
get_evil(channel) get_evil(channel)
if ircmsg.find(":!kjp") != -1: if ircmsg.find(":!kjp") != -1:
get_tumble('http://kingjamesprogramming.tumblr.com', channel) get_tumble("http://kingjamesprogramming.tumblr.com", channel)
if ircmsg.find(":!help") != -1: if ircmsg.find(":!help") != -1:
get_tumble('http://thedoomthatcametopuppet.tumblr.com', channel) get_tumble("http://thedoomthatcametopuppet.tumblr.com", channel)
if ircmsg.find(":!xkcd") != -1: if ircmsg.find(":!xkcd") != -1:
get_xkcd(channel, messageText) get_xkcd(channel, messageText)
if ircmsg.find(":!wiki-philosophy") != -1: if ircmsg.find(":!wiki-philosophy") != -1:
get_wphilosophy(channel, messageText); get_wphilosophy(channel, messageText)
if ircmsg.find(":!figlet") != -1: if ircmsg.find(":!figlet") != -1:
figlet(channel, messageText[8:]) figlet(channel, messageText[8:])
if ircmsg.find(":!toilet") != -1: if ircmsg.find(":!toilet") != -1:
toilet(channel, messageText[8:]) toilet(channel, messageText[8:])
if ircmsg.find(":!acronym") != -1: if ircmsg.find(":!acronym") != -1:
get_acronym(channel, messageText[9:]) get_acronym(channel, messageText[9:])
if ircmsg.find(":!whosaid") != -1: if ircmsg.find(":!whosaid") != -1:
get_whosaid(channel, messageText[9:]) get_whosaid(channel, messageText[9:])
if ircmsg.find(":!notice") != -1: if ircmsg.find(":!notice") != -1:
get_notice(user, channel) get_notice(user, channel)
if ircmsg.find(":!water") != -1: if ircmsg.find(":!water") != -1:
get_water(user, channel, messageText[7:], botnick) get_water(user, channel, messageText[7:], botnick)
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
if ircmsg.find(":!rollcall") != -1: if ircmsg.find(":" + botnick + ":") != -1:
rollcall(channel) mug_off(channel)
if ircmsg.find(":" + botnick + ":") != -1: if ircmsg[:4] == "PING":
mug_off(channel) util.ping(ircsock, ircmsg)
if ircmsg[:4] == "PING": sys.stdout.flush()
ping(ircmsg.split(" ")[1]) time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick) util.connect(ircsock, options)
listen(options.nick) listen(options.nick)
+21 -16
View File
@@ -1,28 +1,33 @@
import urllib import urllib
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import random import random
def define(word): def define(word):
defs = [] defs = []
url = 'http://www.merriam-webster.com/dictionary/%s' % word url = "http://www.merriam-webster.com/dictionary/{}".format(word)
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser') soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
head = soup.find('div', id='headword') head = soup.find("div", id="headword")
if head: if head:
for p in head.find_all('p'): for p in head.find_all("p"):
defs.append(p.text.encode('ascii', 'ignore')) defs.append(p.text.encode("ascii", "ignore"))
return defs return defs
key = open("/home/krowbar/.secret/key").readline().rstrip() key = open("/home/krowbar/.secret/key").readline().rstrip()
def defWord(word, short = True):
def defWord(word, short=True):
defs = [] defs = []
url = 'http://www.dictionaryapi.com/api/v1/references/collegiate/xml/%s?key=%s' % (word, key) url = "http://www.dictionaryapi.com/api/v1/references/collegiate/xml/{}?key={}".format(
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html5lib') word, key
entry = soup.find('entry') )
soup = BeautifulSoup(urllib.urlopen(url).read(), "html5lib")
entry = soup.find("entry")
if entry: if entry:
for d in entry.find_all('dt'): for d in entry.find_all("dt"):
defs.append(d.text.encode('ascii', 'ignore')) defs.append(d.text.encode("ascii", "ignore"))
if short: if short:
return ' '.join(defs) return " ".join(defs)
else: else:
return defs return defs
+20 -13
View File
@@ -6,8 +6,10 @@ p = inflect.engine()
dictionary = "/usr/share/dict/american-english-small" dictionary = "/usr/share/dict/american-english-small"
BAD_WORDS_FILE = "badwords.txt" BAD_WORDS_FILE = "badwords.txt"
def get_wordlist():
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 # 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: with open(BAD_WORDS_FILE, "r") as fp:
bad_words = set(fp) bad_words = set(fp)
@@ -15,23 +17,27 @@ def get_wordlist():
if "'" not in word and word not in bad_words: if "'" not in word and word not in bad_words:
yield word.rstrip() yield word.rstrip()
def get_puzzle(): def get_puzzle():
dict_words = list(get_wordlist()) dict_words = list(gen_wordlist())
words = random.sample(dict_words, 3) words = random.sample(dict_words, 3)
key = random.randrange(0,3) #get values 1-3 key = random.randrange(0, 3) # get values 1-3
puzzle = "When alphebetized, what is the " + p.ordinal(p.number_to_words(key+1)) + " in " + ", ".join(words) puzzle = "When alphebetized, what is the {} in {}?".format(
p.ordinal(p.number_to_words(key + 1)), ", ".join(words)
)
words.sort() words.sort()
answer = words[key] answer = words[key]
return [answer, puzzle] return [answer, puzzle]
def get_anagram(maxlen = 6):
dict_words = [word for word in get_wordlist() if len(word) > 2 and len(word) <= maxlen+1] 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) word = random.choice(dict_words)
while True: anagram = list(word)
anagram = ''.join(random.sample(word, len(word))) random.shuffle(anagram)
if anagram != word: anagram = "".join(anagram)
break
puzzle = "Unscramble the following word: '" + anagram + "'"
# Anagrams can have multiple answers, so we provide a check function that accepts all possibilities # Anagrams can have multiple answers, so we provide a check function that accepts all possibilities
def answer_checker(guess): def answer_checker(guess):
@@ -42,5 +48,6 @@ def get_anagram(maxlen = 6):
if sorted(guess) != sorted(word): if sorted(guess) != sorted(word):
return False return False
# Ok, gotta actually check if it's a word now # Ok, gotta actually check if it's a word now
return any(guess == item for item in get_wordlist()) return any(guess == item for item in gen_wordlist())
return [answer_checker, puzzle]
return [answer_checker, "Unscramble the following word: '{}'".format(anagram)]
+91 -72
View File
@@ -1,12 +1,19 @@
import requests
import urllib import urllib
import urllib2
import json as j import json as j
import sys import sys
__version__ = 0.242 __version__ = 0.242
def query(query, useragent='python-duckduckgo '+str(__version__), safesearch=True, html=False, meanings=True, **kwargs): def query(
query,
useragent="python-duckduckgo " + str(__version__),
safesearch=True,
html=False,
meanings=True,
**kwargs
):
""" """
Query DuckDuckGo, returning a Results object. Query DuckDuckGo, returning a Results object.
@@ -28,78 +35,77 @@ def query(query, useragent='python-duckduckgo '+str(__version__), safesearch=Tru
Any other keyword arguments are passed directly to DuckDuckGo as URL params. Any other keyword arguments are passed directly to DuckDuckGo as URL params.
""" % __version__ """ % __version__
safesearch = '1' if safesearch else '-1' safesearch = "1" if safesearch else "-1"
html = '0' if html else '1' html = "0" if html else "1"
meanings = '0' if meanings else '1' meanings = "0" if meanings else "1"
params = { params = {
'q': query, "q": query,
'o': 'json', "o": "json",
'kp': safesearch, "kp": safesearch,
'no_redirect': '1', "no_redirect": "1",
'no_html': html, "no_html": html,
'd': meanings, "d": meanings,
} }
params.update(kwargs) params.update(kwargs)
encparams = urllib.urlencode(params) encparams = urllib.urlencode(params)
url = 'http://api.duckduckgo.com/?' + encparams url = "http://api.duckduckgo.com/?" + encparams
request = urllib2.Request(url, headers={'User-Agent': useragent}) request = requests.get(url, headers={"User-Agent": useragent})
response = urllib2.urlopen(request)
json = j.loads(response.read())
response.close()
return Results(json) return Results(request.json())
class Results(object): class Results(object):
def __init__(self, json): def __init__(self, json):
self.type = {'A': 'answer', 'D': 'disambiguation', self.type = {
'C': 'category', 'N': 'name', "A": "answer",
'E': 'exclusive', '': 'nothing'}.get(json.get('Type',''), '') "D": "disambiguation",
"C": "category",
"N": "name",
"E": "exclusive",
"": "nothing",
}.get(json.get("Type", ""), "")
self.json = json self.json = json
self.api_version = None # compat self.api_version = None # compat
self.heading = json.get('Heading', '') self.heading = json.get("Heading", "")
self.results = [Result(elem) for elem in json.get('Results',[])] self.results = [Result(elem) for elem in json.get("Results", [])]
self.related = [Result(elem) for elem in self.related = [Result(elem) for elem in json.get("RelatedTopics", [])]
json.get('RelatedTopics',[])]
self.abstract = Abstract(json) self.abstract = Abstract(json)
self.redirect = Redirect(json) self.redirect = Redirect(json)
self.definition = Definition(json) self.definition = Definition(json)
self.answer = Answer(json) self.answer = Answer(json)
self.image = Image({'Result':json.get('Image','')}) self.image = Image({"Result": json.get("Image", "")})
class Abstract(object): class Abstract(object):
def __init__(self, json): def __init__(self, json):
self.html = json.get('Abstract', '') self.html = json.get("Abstract", "")
self.text = json.get('AbstractText', '') self.text = json.get("AbstractText", "")
self.url = json.get('AbstractURL', '') self.url = json.get("AbstractURL", "")
self.source = json.get('AbstractSource') self.source = json.get("AbstractSource")
class Redirect(object): class Redirect(object):
def __init__(self, json): def __init__(self, json):
self.url = json.get('Redirect', '') self.url = json.get("Redirect", "")
class Result(object): class Result(object):
def __init__(self, json): def __init__(self, json):
self.topics = json.get('Topics', []) self.topics = json.get("Topics", [])
if self.topics: if self.topics:
self.topics = [Result(t) for t in self.topics] self.topics = [Result(t) for t in self.topics]
return return
self.html = json.get('Result') self.html = json.get("Result")
self.text = json.get('Text') self.text = json.get("Text")
self.url = json.get('FirstURL') self.url = json.get("FirstURL")
icon_json = json.get('Icon') icon_json = json.get("Icon")
if icon_json is not None: if icon_json is not None:
self.icon = Image(icon_json) self.icon = Image(icon_json)
else: else:
@@ -107,51 +113,61 @@ class Result(object):
class Image(object): class Image(object):
def __init__(self, json): def __init__(self, json):
self.url = json.get('Result') self.url = json.get("Result")
self.height = json.get('Height', None) self.height = json.get("Height", None)
self.width = json.get('Width', None) self.width = json.get("Width", None)
class Answer(object): class Answer(object):
def __init__(self, json): def __init__(self, json):
self.text = json.get('Answer') self.text = json.get("Answer")
self.type = json.get('AnswerType', '') self.type = json.get("AnswerType", "")
class Definition(object): class Definition(object):
def __init__(self, json): def __init__(self, json):
self.text = json.get('Definition','') self.text = json.get("Definition", "")
self.url = json.get('DefinitionURL') self.url = json.get("DefinitionURL")
self.source = json.get('DefinitionSource') self.source = json.get("DefinitionSource")
def get_zci(q, web_fallback=True, priority=['answer', 'abstract', 'related.0', 'definition'], urls=True, **kwargs): def get_zci(
'''A helper method to get a single (and hopefully the best) ZCI result. 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. 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. 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.' passed to query. This method will fall back to 'Sorry, no results.'
if it cannot find anything.''' if it cannot find anything."""
ddg = query('\\'+q, **kwargs) ddg = query("\\" + q, **kwargs)
response = '' response = ""
for p in priority: for p in priority:
ps = p.split('.') ps = p.split(".")
type = ps[0] type = ps[0]
index = int(ps[1]) if len(ps) > 1 else None index = int(ps[1]) if len(ps) > 1 else None
result = getattr(ddg, type) result = getattr(ddg, type)
if index is not None: if index is not None:
if not hasattr(result, '__getitem__'): raise TypeError('%s field is not indexable' % type) if not hasattr(result, "__getitem__"):
raise TypeError("%s field is not indexable" % type)
result = result[index] if len(result) > index else None result = result[index] if len(result) > index else None
if not result: continue if not result:
continue
if result.text: response = result.text if result.text:
if result.text and hasattr(result,'url') and urls: response = result.text
if result.url: response += ' (%s)' % result.url if result.text and hasattr(result, "url") and urls:
if response: break if result.url:
response += " (%s)" % result.url
if response:
break
# if there still isn't anything, try to get the first web result # if there still isn't anything, try to get the first web result
if not response and web_fallback: if not response and web_fallback:
@@ -159,21 +175,24 @@ def get_zci(q, web_fallback=True, priority=['answer', 'abstract', 'related.0', '
response = ddg.redirect.url response = ddg.redirect.url
# final fallback # final fallback
if not response: if not response:
response = 'Sorry, no results.' response = "Sorry, no results."
return response return response
def main(): def main():
if len(sys.argv) > 1: if len(sys.argv) > 1:
q = query(' '.join(sys.argv[1:])) q = query(" ".join(sys.argv[1:]))
keys = q.json.keys() keys = q.json.keys()
keys.sort() keys.sort()
for key in keys: for key in keys:
sys.stdout.write(key) sys.stdout.write(key)
if type(q.json[key]) in [str,unicode]: print(':', q.json[key]) if type(q.json[key]) in [str, unicode]:
else: print(":", q.json[key])
sys.stdout.write('\n') else:
for i in q.json[key]: print('\t',i) sys.stdout.write("\n")
for i in q.json[key]:
print("\t", i)
else: else:
print('Usage: %s [query]' % sys.argv[0]) print("Usage: %s [query]" % sys.argv[0])
+4 -1
View File
@@ -1,6 +1,9 @@
import random import random
def get_thing(): def get_thing():
file = "/home/krowbar/logs/evildata.txt" file = "/home/krowbar/logs/evildata.txt"
thing = "" thing = ""
return "If I Ever Become an Evil Overlord: " + random.choice(list(open(file))).rstrip() return (
"If I Ever Become an Evil Overlord: " + random.choice(list(open(file))).rstrip()
)
-16
View File
@@ -1,16 +0,0 @@
import time
import re
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)
-12
View File
@@ -1,12 +0,0 @@
# Return a list of users on this system
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
+2037 -1186
View File
File diff suppressed because it is too large. Load diff
-65
View File
@@ -1,65 +0,0 @@
# 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 "]
Binary file not shown.
+48 -28
View File
@@ -8,15 +8,20 @@ import re
p = inflect.engine() p = inflect.engine()
file_pattern = "/home/*/madlibs/*.madlib" file_pattern = "/home/*/madlibs/*.madlib"
file_regex = re.compile(r'^/home/(.*?)/.*/([^/]*)\.madlib$') file_regex = re.compile(r"^/home/(.*?)/.*/([^/]*)\.madlib$")
word_regex = re.compile(r'{{(.*?)(#.*?)?(\|.*)?}}') word_regex = re.compile(r"{{(.*?)(#.*?)?(\|.*)?}}")
word_replace_regex = re.compile(r'^(.*)#(\d*)$') word_replace_regex = re.compile(r"^(.*)#(\d*)$")
# Take a file path and return a tuple with the title and original path # Take a file path and return a tuple with the title and original path
def munge_story(file_name): def munge_story(file_name):
match = re.match(file_regex, file_name) match = re.match(file_regex, file_name)
count = count_words_file(file_name) count = count_words_file(file_name)
return ("'" + match.group(2).replace('_', ' ') + "' by ~" + match.group(1), match.group(0), count) return (
"'" + match.group(2).replace("_", " ") + "' by ~" + match.group(1),
match.group(0),
count,
)
# Retrive a list of all madlib story files # Retrive a list of all madlib story files
def find_stories(limit=999, shuffle=False): def find_stories(limit=999, shuffle=False):
@@ -27,25 +32,28 @@ def find_stories(limit=999, shuffle=False):
files = files[:limit] files = files[:limit]
return map(munge_story, files) return map(munge_story, files)
# Count the number of replacable words in the story # Count the number of replacable words in the story
def count_words(story): def count_words(story):
# words that have a '#' part and match should only be counted once # words that have a '#' part and match should only be counted once
count = 0 count = 0
repeats = [] repeats = []
for match in re.finditer(word_regex, story): for match in re.finditer(word_regex, story):
if match.group(2) is None: #the '#' part if match.group(2) is None: # the '#' part
count += 1 count += 1
elif match.group(1) + match.group(2) not in repeats: elif match.group(1) + match.group(2) not in repeats:
count += 1 count += 1
repeats.append(match.group(1) + match.group(2)) repeats.append(match.group(1) + match.group(2))
return count return count
# Count the number of replacable words in the story when given a file path # Count the number of replacable words in the story when given a file path
def count_words_file(storyPath): def count_words_file(storyPath):
with open(storyPath, "r") as storyFile: with open(storyPath, "r") as storyFile:
story = storyFile.read() story = storyFile.read()
return count_words(story) return count_words(story)
# Get the next replaceable word in the story. Includes full token and just the word # Get the next replaceable word in the story. Includes full token and just the word
# If you specify rand as True, it will get a random word instead of the next one # If you specify rand as True, it will get a random word instead of the next one
def find_next_word(story, rand=False): def find_next_word(story, rand=False):
@@ -58,19 +66,27 @@ def find_next_word(story, rand=False):
return (match.group(0), match.group(1)) return (match.group(0), match.group(1))
# Using a query phrase, replace a word and return the entire story body # Using a query phrase, replace a word and return the entire story body
def replace_word(story, query, word): def replace_word(story, query, word):
rquery = word_regex.search(query) rquery = word_regex.search(query)
# '{{foo#bar|baz|bang}}' => ('foo', '#bar', '|baz|bang') # '{{foo#bar|baz|bang}}' => ('foo', '#bar', '|baz|bang')
pipes = [p.lower() for p in (rquery.group(3) if rquery.group(3) is not None else '').strip('|').split('|')] pipes = [
p.lower()
for p in (rquery.group(3) if rquery.group(3) is not None else "")
.strip("|")
.split("|")
]
munged_word = process_pipes(word, pipes) munged_word = process_pipes(word, pipes)
story = story.replace(query, munged_word, 1) story = story.replace(query, munged_word, 1)
if rquery.group(2) is not None: #if there is a '#' part we replace all instances if rquery.group(2) is not None: # if there is a '#' part we replace all instances
print "Looking for {{" + rquery.group(1) + rquery.group(2) + ".*?}}" print("Looking for {{" + rquery.group(1) + rquery.group(2) + ".*?}}")
others = re.findall(r'{{' + rquery.group(1) + rquery.group(2) + '.*?}}', story) others = re.findall(r"{{" + rquery.group(1) + rquery.group(2) + ".*?}}", story)
if len(others) > 0: if len(others) > 0:
story = replace_word(story, others[0], word) #iteratively replace the next instance story = replace_word(
story, others[0], word
) # iteratively replace the next instance
return story return story
@@ -80,17 +96,18 @@ def process_pipes(word, pipes):
for pipe in pipes: for pipe in pipes:
try: try:
word = { word = {
'upper': lambda word: word.upper(), "upper": lambda word: word.upper(),
'lower': lambda word: word.lower(), "lower": lambda word: word.lower(),
'title': lambda word: word.title(), "title": lambda word: word.title(),
'numeric': lambda word: p.number_to_words(word), "numeric": lambda word: p.number_to_words(word),
'ordinal': lambda word: p.ordinal(word), "ordinal": lambda word: p.ordinal(word),
collections.defaultdict: lambda word: word collections.defaultdict: lambda word: word,
}[pipe](word) }[pipe](word)
except Exception: except Exception:
pass # just keep going if an error occurs processing a pipe pass # just keep going if an error occurs processing a pipe
return word return word
# A helper function that will split the story up into chat-printable lengths # A helper function that will split the story up into chat-printable lengths
def yield_lines(line, max_size): def yield_lines(line, max_size):
words = [] words = []
@@ -101,17 +118,18 @@ def yield_lines(line, max_size):
while len(word) > max_size: while len(word) > max_size:
splitsize = max_size - words_length - 1 splitsize = max_size - words_length - 1
words.append(word[:splitsize] + "-") words.append(word[:splitsize] + "-")
yield ' '.join(words) yield " ".join(words)
words = [] words = []
words_length = 0 words_length = 0
word = word[splitsize:] word = word[splitsize:]
if words_length + len(word) + 1 > max_size: if words_length + len(word) + 1 > max_size:
yield ' '.join(words) yield " ".join(words)
words = [] words = []
words_length = 0 words_length = 0
words.append(word) words.append(word)
words_length += len(word) + 1 # For the space words_length += len(word) + 1 # For the space
yield ' '.join(words) # For any words left over yield " ".join(words) # For any words left over
# Open a story file and ask for the parts # Open a story file and ask for the parts
def make_story(storyFile): def make_story(storyFile):
@@ -119,23 +137,24 @@ def make_story(storyFile):
story = storyFile.read() story = storyFile.read()
match = word_regex.search(story) match = word_regex.search(story)
while match is not None: while match is not None:
word = raw_input('Give me {}: '.format(match.group(1))) word = raw_input("Give me {}: ".format(match.group(1)))
print "Replacing '{}' with '{}'".format(match.group(0), word) print("Replacing '{}' with '{}'".format(match.group(0), word))
print story print(story)
story = re.sub(match.group(0), word, story, 1) story = re.sub(match.group(0), word, story, 1)
match = word_regex.search(story) match = word_regex.search(story)
print story print(story)
def start(): def start():
stories = find_stories(20, True) stories = find_stories(20, True)
if len(stories) == 0: if len(stories) == 0:
print "Sorry, no stories found. :/" print("Sorry, no stories found. :/")
return return
input = -1 input = -1
while input < 0 or input >= len(stories): while input < 0 or input >= len(stories):
for idx, story in enumerate(stories): for idx, story in enumerate(stories):
print "[{}] {}".format(idx, story[0]) print("[{}] {}".format(idx, story[0]))
input = raw_input("Which story would you like?: ") input = raw_input("Which story would you like?: ")
try: try:
# Try to convert the string input into a number # Try to convert the string input into a number
@@ -147,5 +166,6 @@ def start():
# Call make_story with the file path of the selected story # Call make_story with the file path of the selected story
make_story(stories[input][1]) make_story(stories[input][1])
if __name__ == "__main__": if __name__ == "__main__":
start() start()
+97 -47
View File
@@ -12,36 +12,59 @@ import time
import re import re
import operator import operator
import msgformatter from .. import util
import madlib import madlib
class State: class State:
idle = 0 # When the bot is started and after it has finished a story idle = 0 # When the bot is started and after it has finished a story
thinking = 1 # I intentionally speed throttle this bot so it feels a little more natural thinking = (
story_selection = 2 # When the bot is waiting for a user input for story selection 1
word_input = 3 # When the bot is waiting for user input after prompted for a word ) # I intentionally speed throttle this bot so it feels a little more natural
story_selection = 2 # When the bot is waiting for a user input for story selection
word_input = 3 # When the bot is waiting for user input after prompted for a word
# Globals # Globals
MAX_LINE = 80 # The maximum number of characters in a line MAX_LINE = 80 # The maximum number of characters in a line
MAX_STORIES = 5 # The maximum number of stories a user can pick from MAX_STORIES = 5 # The maximum number of stories a user can pick from
THROTTLE_FACTOR = 1 # A factor by which all sleep event durations will be multiplied THROTTLE_FACTOR = 1 # A factor by which all sleep event durations will be multiplied
# Allow madlbibbot to run multiple simultaneous stories # Allow madlbibbot to run multiple simultaneous stories
state = {} # The current state of the bot state = {} # The current state of the bot
stories = {} # The list of stories available to users stories = {} # The list of stories available to users
story = {} # The madlib story currently being worked on story = {} # The madlib story currently being worked on
nextword = {} # The word that the bot is currently expecting data for nextword = {} # The word that the bot is currently expecting data for
parser = OptionParser() parser = OptionParser()
parser.add_option("-s", "--server", dest="server", default='127.0.0.1', parser.add_option(
help="the server to connect to", metavar="SERVER") "-s",
parser.add_option("-c", "--channel", dest="channel", default='#madlibs', "--server",
help="the channel to join", metavar="CHANNEL") dest="server",
parser.add_option("-n", "--nick", dest="nick", default='madlibbot', default="127.0.0.1:6667",
help="the nick to use", metavar="NICK") help="the server to connect to",
metavar="SERVER",
)
parser.add_option(
"-c",
"--channel",
dest="channel",
default="#madlibs",
help="the channel to join",
metavar="CHANNEL",
)
parser.add_option(
"-n",
"--nick",
dest="nick",
default="madlibbot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
def resetGlobals(channel=""): def resetGlobals(channel=""):
global state global state
global stories global stories
@@ -59,6 +82,7 @@ def resetGlobals(channel=""):
story[channel] = "" story[channel] = ""
nextword[channel] = {} nextword[channel] = {}
def get_stories(channel, botnick): def get_stories(channel, botnick):
global state global state
global stories global stories
@@ -73,9 +97,13 @@ def get_stories(channel, botnick):
for idx, story in enumerate(stories[channel]): for idx, story in enumerate(stories[channel]):
sendmsg(channel, "[{}] {} ({} words)".format(idx, story[0], story[2])) sendmsg(channel, "[{}] {} ({} words)".format(idx, story[0], story[2]))
time.sleep(0.5 * THROTTLE_FACTOR) time.sleep(0.5 * THROTTLE_FACTOR)
sendmsg(channel, "Please select a story by index by saying '{}: <number>':".format(botnick)) sendmsg(
channel,
"Please select a story by index by saying '{}: <number>':".format(botnick),
)
state[channel] = State.story_selection state[channel] = State.story_selection
# Handle user input when the bot is directly addressed # Handle user input when the bot is directly addressed
def handle_bot_msg(channel, msg, botnick): def handle_bot_msg(channel, msg, botnick):
global state global state
@@ -100,11 +128,13 @@ def handle_bot_msg(channel, msg, botnick):
else: else:
state[channel] = State.idle state[channel] = State.idle
# Handle how to quit the game # Handle how to quit the game
def quit_game(channel): def quit_game(channel):
resetGlobals(channel) resetGlobals(channel)
sendmsg(channel, "Ok, quitting the current game.") sendmsg(channel, "Ok, quitting the current game.")
# Handle user input when we are in story selection mode # Handle user input when we are in story selection mode
def handle_story_selection(channel, msg, botnick): def handle_story_selection(channel, msg, botnick):
global stories global stories
@@ -115,16 +145,19 @@ def handle_story_selection(channel, msg, botnick):
sendmsg(channel, "Selection out of bounds. Try again!") sendmsg(channel, "Selection out of bounds. Try again!")
return return
time.sleep(1 * THROTTLE_FACTOR) time.sleep(1 * THROTTLE_FACTOR)
sendmsg(channel, "Give me a second to load up {}".format(stories[channel][imsg][0])) sendmsg(
channel, "Give me a second to load up {}".format(stories[channel][imsg][0])
)
with open(stories[channel][imsg][1], "r") as storyFile: with open(stories[channel][imsg][1], "r") as storyFile:
story[channel] = storyFile.read() story[channel] = storyFile.read()
stories[channel] = {} # Clear out the saved selectable stories in memory stories[channel] = {} # Clear out the saved selectable stories in memory
story_start(channel, botnick) story_start(channel, botnick)
except ValueError: except ValueError:
sendmsg(channel, "Invalid selection. Try again!") sendmsg(channel, "Invalid selection. Try again!")
state[channel] = State.story_selection state[channel] = State.story_selection
# Handle when a story is being started # Handle when a story is being started
def story_start(channel, botnick): def story_start(channel, botnick):
global story global story
@@ -132,12 +165,18 @@ def story_start(channel, botnick):
global nextword global nextword
state[channel] = State.thinking state[channel] = State.thinking
sendmsg(channel, "Alright! Let's get started! Say '{}: <word>' to give me words.".format(botnick)) sendmsg(
channel,
"Alright! Let's get started! Say '{}: <word>' to give me words.".format(
botnick
),
)
nextword[channel] = madlib.find_next_word(story[channel], True) nextword[channel] = madlib.find_next_word(story[channel], True)
time.sleep(0.5 * THROTTLE_FACTOR) time.sleep(0.5 * THROTTLE_FACTOR)
sendmsg(channel, "Give me {}:".format(nextword[channel][1])) sendmsg(channel, "Give me {}:".format(nextword[channel][1]))
state[channel] = State.word_input state[channel] = State.word_input
# Handle user input when we have asked the user for input and are expecting a # Handle user input when we have asked the user for input and are expecting a
# response # response
def handle_story_step(channel, msg): def handle_story_step(channel, msg):
@@ -146,7 +185,7 @@ def handle_story_step(channel, msg):
global nextword global nextword
state[channel] = State.thinking state[channel] = State.thinking
word = nextword[channel] #madlib.find_next_word(story[channel]) word = nextword[channel] # madlib.find_next_word(story[channel])
if word is not None: if word is not None:
story[channel] = madlib.replace_word(story[channel], nextword[channel][0], msg) story[channel] = madlib.replace_word(story[channel], nextword[channel][0], msg)
time.sleep(1 * THROTTLE_FACTOR) time.sleep(1 * THROTTLE_FACTOR)
@@ -155,67 +194,74 @@ def handle_story_step(channel, msg):
if nextword[channel] is None: if nextword[channel] is None:
finish_story(channel) finish_story(channel)
return return
#else # else
count = madlib.count_words(story[channel]) count = madlib.count_words(story[channel])
sendmsg(channel, "Thanks! Now give me {} ({} words left)".format(nextword[channel][1], count)) sendmsg(
channel,
"Thanks! Now give me {} ({} words left)".format(nextword[channel][1], count),
)
state[channel] = State.word_input state[channel] = State.word_input
# Finish the story # Finish the story
def finish_story(channel): def finish_story(channel):
global state global state
global story global story
sendmsg(channel, "Ok, here's the story..."); sendmsg(channel, "Ok, here's the story...")
sendmsg(channel, '=' * MAX_LINE) sendmsg(channel, "=" * MAX_LINE)
for line in story[channel].splitlines(): for line in story[channel].splitlines():
for part in madlib.yield_lines(line, MAX_LINE): for part in madlib.yield_lines(line, MAX_LINE):
time.sleep(0.6 * THROTTLE_FACTOR) time.sleep(0.6 * THROTTLE_FACTOR)
sendmsg(channel, part) sendmsg(channel, part)
padlen = (MAX_LINE - 9)/2 padlen = (MAX_LINE - 9) / 2
mod = (MAX_LINE - 9) % 2 mod = (MAX_LINE - 9) % 2
sendmsg(channel, '=' * padlen + ' THE END ' + '=' * (padlen + mod)) sendmsg(channel, "=" * padlen + " THE END " + "=" * (padlen + mod))
story[channel] = "" story[channel] = ""
state[channel] = State.idle state[channel] = State.idle
# System things # System things
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG {} :{}\n".format(chan, msg))
def joinchan(chan): def joinchan(chan):
global state global state
state[chan] = State.idle state[chan] = State.idle
ircsock.send("JOIN {}\n".format(chan)) ircsock.send("JOIN {}\n".format(chan))
def rollcall(channel, botnick): def rollcall(channel, botnick):
global state global state
if channel not in state: if channel not in state:
state[channel] = State.idle state[channel] = State.idle
if state[channel] == State.idle: if state[channel] == State.idle:
sendmsg(channel, "Do you like MadLibs? Start a collaborative story by saying '{}: startgame'".format(botnick)) sendmsg(
channel,
"Do you like MadLibs? Start a collaborative story by saying '{}: startgame'".format(
botnick
),
)
else: else:
sendmsg(channel, "A game is already in progress. Say '{}: <word>' to provide me with the next word or '{}: !quit' to stop the current game".format(botnick, botnick)) sendmsg(
channel,
"A game is already in progress. Say '{}: <word>' to provide me with the next word or '{}: !quit' to stop the current game".format(
botnick, botnick
),
)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER {} {} {} :krowbar\n".format(botnick, botnick, botnick)) # user authentication
ircsock.send("NICK {}\n".format(botnick))
joinchan(channel)
def listen(botnick): def listen(botnick):
botmsgre = re.compile('^{}\:?\s*(.*)$'.format(botnick)) # re to strip the bot's name from a message botmsgre = re.compile(
"^{}\:?\s*(.*)$".format(botnick)
) # re to strip the bot's name from a message
while 1: while 1:
ircmsg = ircsock.recv(2048) ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r') ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING": if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1]) ping(ircmsg.split(" ")[1])
formatted = msgformatter.format_message(ircmsg) formatted = util.format_message(ircmsg)
if "" == formatted: if "" == formatted:
continue continue
# print formatted # print formatted
@@ -227,7 +273,10 @@ def listen(botnick):
channel = split[3] channel = split[3]
message = split[4] message = split[4]
if message.startswith("!rollcall") == True or message.startswith("!help") == True: if (
message.startswith("!rollcall") == True
or message.startswith("!help") == True
):
rollcall(channel, botnick) rollcall(channel, botnick)
elif message.startswith(botnick) == True: elif message.startswith(botnick) == True:
botmsg = botmsgre.match(message).group(1) botmsg = botmsgre.match(message).group(1)
@@ -236,6 +285,7 @@ def listen(botnick):
sys.stdout.flush() sys.stdout.flush()
time.sleep(1 * THROTTLE_FACTOR) time.sleep(1 * THROTTLE_FACTOR)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick) util.connect(ircsock, options)
listen(options.nick) listen(options.nick)
-16
View File
@@ -1,16 +0,0 @@
import time
import re
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)
-15
View File
@@ -1,15 +0,0 @@
#!/usr/bin/python
import json
names_file='/home/jumblesale/Code/canonical_names/canonical_names.json'
def get_name(name):
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
-42
View File
@@ -1,42 +0,0 @@
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"
+147 -78
View File
@@ -8,85 +8,154 @@ p = inflect.engine()
primes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] primes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
fuzz_amount = 3 fuzz_amount = 3
def make_puzzle(obfuscate=True): def make_puzzle(obfuscate=True):
answer = 0 answer = 0
bonus = 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: "]) puzzle = random.choice(
puzzle += random.choice(["What is", "How many is", "What do you get from", "What do you get with", "What is the value of", "Can you answer", "Can you tell me"]) [
puzzle += " " "Prove you're not a robot: ",
roll = random.randrange(0,18) "Are you a robot?: ",
var1 = random.randrange(1,10) "Anti-bot check: ",
var2 = random.randrange(1,10) "Counter-cnd0rphant measures: ",
var3 = random.randrange(1,20) "Cosn0k countermeasures: ",
var4 = random.randrange(1,20) "Anti-tilde7hief precautions: ",
let1_ord = random.randrange(ord('a'), ord('z')+1) ]
)
puzzle += random.choice(
[
"What is",
"How many is",
"What do you get from",
"What do you get with",
"What is the value of",
"Can you answer",
"Can you tell me",
]
)
puzzle += " "
roll = random.randrange(0, 18)
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: if roll == 0:
answer = var1 + var2 answer = var1 + var2
puzzle += p.number_to_words(var1) + " " + random.choice(["and", "plus", "sum", "add"]) + " " + p.number_to_words(var2) puzzle += "{} {} {}".format(
p.number_to_words(var1),
random.choice(["and", "plus", "sum", "add"]),
p.number_to_words(var2),
)
elif roll == 1: elif roll == 1:
answer = var1 * var2 answer = var1 * var2
puzzle += p.number_to_words(var1) + " " + random.choice(["times", "multiply", "multiplied by", "product"]) + " " + p.number_to_words(var2) puzzle += "{} {} {}".format(
elif roll == 2: p.number_to_words(var1),
if var2 > var1: random.choice(["times", "multiply", "multiplied by", "product"]),
var1,var2 = var2,var1 p.number_to_words(var2),
answer = var1 - var2 )
puzzle += 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 += p.number_to_words(var1*2) + " " + random.choice(["divided by", "over"]) + " " + p.number_to_words(var2) + " (no remainder)"
elif roll == 4:
answer = var1 ** var2
puzzle += p.number_to_words(var1) + " to the " + p.ordinal(p.number_to_words(var2)) + " power"
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 += p.number_to_words(p1 * p2) + " when factored into its two primes (answer in the form of the two primes with a comma between)"
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 = "What letter comes " + p.number_to_words(var1) + " letters after '" + chr(let1_ord) + "'"
obfuscate = False
elif roll == 8:
if let1_ord - var1 < ord('a'):
let1_ord += var1
answer = chr(let1_ord - var1)
puzzle = "What letter comes " + p.number_to_words(var1) + " letters before '" + 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 = "What is the " + random.choice(["smallest", "lowest"]) + " of " + p.number_to_words(var1) + ", " + p.number_to_words(var2) + ", " + p.number_to_words(var3) + ", and " + p.number_to_words(var4)
elif roll == 11:
answer = str(max(var1, var2, var3, var4))
puzzle = "What is the " + random.choice(["biggest", "largest"]) + " of " + p.number_to_words(var1) + ", " + p.number_to_words(var2) + ", " + p.number_to_words(var3) + ", and " + 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
puzzle += "?" elif roll == 2:
if obfuscate == True: if var2 > var1:
for _ in range(fuzz_amount): var1, var2 = var2, var1
idx = random.randrange(len(puzzle)-1) #get between 0 and string length answer = var1 - var2
puzzle = ''.join([puzzle[0:idx], chr(random.randint(33,126)), puzzle[idx+1:]]) puzzle += "{} {} {}".format(
return [puzzle, answer, bonus] 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 += "What 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 += "What 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 += "What is 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 += "What is 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
puzzle += "?"
if obfuscate == True:
for _ in range(fuzz_amount):
idx = random.randrange(len(puzzle) - 1) # get between 0 and string length
puzzle = "".join(
[puzzle[0:idx], chr(random.randint(33, 126)), puzzle[idx + 1 :]]
)
return [puzzle, answer, bonus]
+72 -78
View File
@@ -7,113 +7,107 @@ import os
import sys import sys
from optparse import OptionParser from optparse import OptionParser
import get_users import util
import mentions
import formatter
parser = OptionParser() parser = OptionParser()
parser.add_option("-s", "--server", dest="server", default='127.0.0.1', parser.add_option(
help="the server to connect to", metavar="SERVER") "-s",
parser.add_option("-c", "--channel", dest="channel", default='#tildetown', "--server",
help="the channel to join", metavar="CHANNEL") dest="server",
parser.add_option("-n", "--nick", dest="nick", default='quote_bot', default="127.0.0.1:6667",
help="the nick to use", metavar="NICK") help="the server to connect to",
metavar="SERVER",
)
parser.add_option(
"-c",
"--channel",
dest="channel",
default="#tildetown",
help="the channel to join",
metavar="CHANNEL",
)
parser.add_option(
"-n",
"--nick",
dest="nick",
default="quotebot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan):
ircsock.send("JOIN "+ chan +"\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
def random_quote(channel): def random_quote(channel):
quote = os.popen("/home/frs/quotes/randquote.py").read() quote = os.popen("/home/frs/quotes/randquote.py").read()
if len(quote) >= 256: if len(quote) >= 256:
quote = quote[:253] + '...' quote = quote[:253] + "..."
ircsock.send("PRIVMSG "+ channel +" :" + quote + "\n") util.sendmsg(ircsock, channel, quote)
def haiku(channel): def haiku(channel):
h = os.popen("haiku").read().replace("\n", " // ") h = os.popen("haiku").read().replace("\n", " // ")
ircsock.send("PRIVMSG "+ channel +" :" + h + "\n") util.sendmsg(ircsock, channel, h)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :This bot is a result of a tutoral covered on http://shellium.org/wiki.\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
joinchan(channel)
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
def say_mentions(user, message): def say_mentions(user, message):
nick = get_user_from_message(message) nick = util.get_user_from_message(message)
menschns = os.popen("/home/karlen/bin/mensch -u %s -t 24 -z +0" % (user)).read().replace("\t", ": ").split("\n") menschns = (
for mention in menschns: os.popen("/home/karlen/bin/mensch -u {} -t 24 -z +0".format(user))
if not "" == mention: .read()
toSend = "PRIVMSG "+ nick + " :" + mention + "\n" .replace("\t", ": ")
if len(toSend) >= 256: .split("\n")
toSend = toSend[:253] + '...' )
ircsock.send(toSend) for mention in menschns:
if not "" == mention:
toSend = "PRIVMSG " + nick + " :" + mention + "\n"
if len(toSend) >= 256:
toSend = toSend[:253] + "..."
ircsock.send(toSend)
def say_chatty(channel): def say_chatty(channel):
chattyOut = os.popen("/home/karlen/bin/chatty").read().split("\n") chattyOut = os.popen("/home/karlen/bin/chatty").read().split("\n")
for line in chattyOut: for line in chattyOut:
if line: if line:
ircsock.send("PRIVMSG "+ channel + " :" + line + "\n") util.sendmsg(ircsock, channel, line)
def listen(): def listen():
while 1: while 1:
ircmsg = ircsock.recv(2048) ircmsg = ircsock.recv(2048).decode()
ircmsg = ircmsg.strip('\n\r') ircmsg = ircmsg.strip("\r\n")
if ircmsg[:4] == "PING": formatted = util.format_message(ircmsg)
ping(ircmsg.split(" ")[1])
formatted = formatter.format_message(ircmsg) if "" == formatted:
continue
if "" == formatted: print(formatted)
continue
print formatted user = formatted.split("\t")[1]
split = formatted.split("\t") if ircmsg.find(":!quote") != -1:
time = split[0] random_quote(options.channel)
user = split[1]
messageText = split[2]
if ircmsg.find(":!quote") != -1: if ircmsg.find(":!mentions") != -1:
random_quote(options.channel) say_mentions(user, ircmsg)
if ircmsg.find(":!mentions") != -1: if ircmsg.find(":!chatty") != -1:
say_mentions(user, ircmsg) say_chatty(options.channel)
if ircmsg.find(":!chatty") != -1: if ircmsg.find(":!haiku") != -1:
say_chatty(options.channel) haiku(options.channel)
if ircmsg.find(":!haiku") != -1: if ircmsg[:4] == "PING":
haiku(options.channel) util.ping(ircsock, ircmsg)
if ircmsg[:4] == "PING": sys.stdout.flush()
ping(ircmsg.split(" ")[1]) # time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick) util.connect(ircsock, options)
listen() listen()
+5 -4
View File
@@ -3,10 +3,11 @@ import re
quotefile = "/home/karlen/irc/quotes.txt" quotefile = "/home/karlen/irc/quotes.txt"
def get_quote(): def get_quote():
quotes = open(quotefile, "r").read().split("---") quotes = open(quotefile, "r").read().split("---")
quote,attr = random.choice(quotes).strip().splitlines() quote, attr = random.choice(quotes).strip().splitlines()
quote = quote[:200] #get only the first 200 chars quote = quote[:200] # get only the first 200 chars
word = random.choice([q for q in quote.split(' ') if len(q) > 1]) word = random.choice([q for q in quote.split(" ") if len(q) > 1])
quote = quote.replace(word, re.sub(r"[a-zA-Z]", "_", word)) quote = quote.replace(word, re.sub(r"[a-zA-Z]", "_", word))
return [word, "Fill in the blank: \"" + quote + "\" " + attr] return [word, 'Fill in the blank: "' + quote + '" ' + attr]
-18
View File
@@ -1,18 +0,0 @@
import random
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
+28 -14
View File
@@ -1,25 +1,39 @@
import urllib import urllib
#from lxml.html import fromstring
# from lxml.html import fromstring
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import random import random
def getRhymes(word): def getRhymes(word):
words = [] words = []
url = 'http://www.rhymer.com/RhymingDictionaryLast/%s.html' % word url = "http://www.rhymer.com/RhymingDictionaryLast/%s.html" % word
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser') soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
for t in soup.find_all('table', 'table'): 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])) words.append(
return words 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): def rhymeZone(word):
words = [] words = []
url = 'http://rhymezone.com/r/rhyme.cgi?Word=%s&typeofrhyme=perfect&org1=syl&org2=l&org3=y' % word url = (
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser') "http://rhymezone.com/r/rhyme.cgi?Word=%s&typeofrhyme=perfect&org1=syl&org2=l&org3=y"
% word
)
soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
for t in soup.find_all('a', 'd'): for t in soup.find_all("a", "d"):
w = t.text.rstrip() w = t.text.rstrip()
if w not in [u'', u'\xa0'] and '?' not in t: if w not in [u"", u"\xa0"] and "?" not in t:
words.append(w.encode('ascii', 'ignore')) words.append(w.encode("ascii", "ignore"))
random.shuffle(words) random.shuffle(words)
return words[0:5] return words[0:5]
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
nohup ./wangbot.py -s 127.0.0.1 -n numberwang_bot -c \#bots >> wanglog 2>> wanglog & 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 & #nohup ./wangbot.py -s 127.0.0.1 -n numberwang_bot -c \#bot_test >> wanglog 2>> wanglog &
+1 -1
View File
@@ -4,7 +4,7 @@ After=tildebot.service
[Service] [Service]
Type=simple Type=simple
ExecStart=/home/krowbar/Code/irc/tildebot.py -s 127.0.0.1 -n tildebot -c \#tildetown ExecStart=/home/krowbar/Code/irc/tildebot.py -n tildebot -c \#tildetown
WorkingDirectory=/home/krowbar/Code/irc/ WorkingDirectory=/home/krowbar/Code/irc/
Restart=always Restart=always
RestartSec=5 RestartSec=5
-89
View File
@@ -1,89 +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 get_users
import mentions
import formatter
parser = OptionParser()
parser.add_option("-s", "--server", dest="server", default='127.0.0.1',
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='tilde_bot',
help="the nick to use", metavar="NICK")
(options, args) = parser.parse_args()
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan):
ircsock.send("JOIN "+ chan +"\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
def tilde(channel, user, time):
#h = os.popen("haiku").read().replace("\n", " // ")
msg = time + ":" + user
print msg
ircsock.send("PRIVMSG "+ channel +" :" + msg + "\n")
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :This bot is a result of a tutoral covered on http://shellium.org/wiki.\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
joinchan(channel)
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
def listen():
while 1:
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r')
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
formatted = formatter.format_message(ircmsg)
if "" == formatted:
continue
print formatted
split = formatted.split("\t")
time = split[0]
user = split[1]
messageText = split[2]
if ircmsg.find(":!tilde") != -1:
tilde(options.channel, user, time)
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
sys.stdout.flush()
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)
listen()
+269 -129
View File
@@ -10,22 +10,36 @@ from optparse import OptionParser
import fileinput import fileinput
import random import random
import formatter
import get_users
import names
import mentions
import pretty_date
import inflect import inflect
import puzzle import puzzle
import util
parser = OptionParser() parser = OptionParser()
parser.add_option("-s", "--server", dest="server", default='127.0.0.1', parser.add_option(
help="the server to connect to", metavar="SERVER") "-s",
parser.add_option("-c", "--channel", dest="channel", default='#bot_test', "--server",
help="the channel to join", metavar="CHANNEL") dest="server",
parser.add_option("-n", "--nick", dest="nick", default='tildebot', default="127.0.0.1:6667",
help="the nick to use", metavar="NICK") help="the server to connect to",
metavar="SERVER",
)
parser.add_option(
"-c",
"--channel",
dest="channel",
default="#bot_test",
help="the channel to join",
metavar="CHANNEL",
)
parser.add_option(
"-n",
"--nick",
dest="nick",
default="tildebot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
@@ -36,69 +50,188 @@ JACKPOT_FILE = "tildejackpot.txt"
JACKPOT_MIN = 3 JACKPOT_MIN = 3
DEBUG = False DEBUG = False
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan):
ircsock.send("JOIN "+ chan +"\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
def too_recent(time1, time2): def too_recent(time1, time2):
if(int(time1) - int(time2) < 60*60): return int(time1) - int(time2) < 60 * 60
return True
else:
return False
def get_positive(): 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']) return random.choice(
[
"Yes",
"Yep",
"Yeppers",
"Correct",
"You got it",
"Yeah",
"Right on",
"Uh-huh",
"Positive",
"Totally right",
"Close enough",
"That's it",
]
)
def get_negative(): def get_negative():
return random.choice(['No', 'Nope', 'Sorry', 'Wrong', 'Nuh-uh', 'Negatory', 'Incorrect', 'Not today', 'Try again', 'Maybe later', 'Probably not', 'Answer hazy', 'Not quite',\ return random.choice(
'Not even close']) [
"No",
"Nope",
"Sorry",
"Wrong",
"Nuh-uh",
"Negatory",
"Incorrect",
"Not today",
"Try again",
"Maybe later",
"Probably not",
"Answer hazy",
"Not quite",
"Not even close",
]
)
def get_superlative(score): def get_superlative(score):
if score > 4: 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",\ return random.choice(
"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"]); [
"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: 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",\ return random.choice(
"going the distance", "a hard worker", "my sunshine", "ready to rumble"]); [
"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: 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",\ return random.choice(
"valuable to the team"]); [
"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",
]
)
def get_bad_thing(): def get_bad_thing():
return random.choice(["is a meanie", "mugs me right off", "is worse than a horse", "smells like a ghost", "probably didn't bathe today", "didn't guess hard enough", "isn't lucky",\ return random.choice(
"smells of elderberries", "should reconsider their life choices", "did't believe in the heart of the tilde", "came to the wrong chat channel", "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"]); "is a meanie",
"mugs me right off",
"is worse than a horse",
"smells like a ghost",
"probably didn't bathe today",
"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 chat channel",
"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",
]
)
def get_prize(name, isHuman, bonus=0): def get_prize(name, isHuman, bonus=0):
prizes = [1] * 8 + [2] * 4 + [3] * 2 + [5] * isHuman #no 5pt prize for non-humans prizes = [1] * 8 + [2] * 4 + [3] * 2 + [5] * isHuman # no 5pt prize for non-humans
prize = random.choice(prizes) + bonus 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) if (
return [prize, name + ": " + (get_positive() if isHuman else get_negative()) + "! You are " + get_superlative(prize) + " and get " + p.number_to_words(prize) + " tildes!"] random.randint(1, 10) > 6 - 4 * isHuman
else: #20% of the time its a jackpot situation ): # 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: with open(JACKPOT_FILE, "r+") as jackpotfile:
jackpot = int(jackpotfile.readline().strip("\n")) jackpot = int(jackpotfile.readline().strip("\n"))
jackpotfile.seek(0) jackpotfile.seek(0)
jackpotfile.truncate() 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 if (
new_jackpot = jackpot+max(1,prize) random.randint(1, 10) > 1 or not isHuman
jackpotfile.write(str(new_jackpot)) #increase the jackpot by the prize size ): # 90% of the time it's a non-prize. non-humans never win jackpot
return [0, name + " " + get_bad_thing() + " and gets no tildes! (Jackpot is now " + str(new_jackpot) + " tildes)"] new_jackpot = jackpot + max(1, prize)
else: #hit jackpot! 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)) jackpotfile.write(str(JACKPOT_MIN))
return [jackpot, name + " hit the jackpot and won **" + p.number_to_words(jackpot) + " tildes!**"] return [
jackpot,
"{} hit the jackpot and won **{}** tildes!".format(
name, p.number_to_words(jackpot)
),
]
def show_jackpot(channel): def show_jackpot(channel):
with open(JACKPOT_FILE, "r") as jackpotfile: with open(JACKPOT_FILE, "r") as jackpotfile:
jackpot = int(jackpotfile.readline().strip("\n")) jackpot = int(jackpotfile.readline().strip("\n"))
ircsock.send("PRiVMSG " + channel + " :The jackpot is currently " + p.number_to_words(jackpot) + " tildes!\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): def give_tilde(channel, user, name, time, human, bonus=0):
found = False found = False
@@ -107,118 +240,125 @@ def give_tilde(channel, user, name, time, human, bonus=0):
scorefile.seek(0) scorefile.seek(0)
scorefile.truncate() scorefile.truncate()
for score in scores: for score in scores:
person = score.strip("\n").split("&^%") name, score_on_file, timestamp = score.strip("\n").split("&^%")
if(person[0] == user): if name == user:
found = True found = True
if(too_recent(time, person[2]) and not DEBUG): if too_recent(time, timestamp) and not DEBUG:
ircsock.send("PRIVMSG " + channel + " :" + name + " asked for a tilde too recently and " + get_bad_thing() + ". Try again later.\n") util.sendmsg(
ircsock,
channel,
"{} asked for a tilde too recently and {}. Try again later.".format(
name, get_bad_thing()
),
)
else: else:
prize = get_prize(name, human, bonus) prizevalue, prizetext = get_prize(name, human, bonus)
score = person[0] + "&^%" + str(int(person[1]) + prize[0]) + "&^%" + time + "\n" score = "{}&^%{}&^%{}\n".format(
ircsock.send("PRIVMSG " + channel + " :" + prize[1] + "\n") name, str(int(score_on_file) + prizevalue), time
)
util.sendmsg(ircsock, channel, prizetext)
scorefile.write(score) scorefile.write(score)
if(not found): if not found:
prize = get_prize(name, True, bonus) prizevalue, prizetext = get_prize(name, True, bonus)
ircsock.send("PRIVMSG " + channel + " :Welcome to the tilde game! Here's " + p.number_to_words(prize[0]+1) + " free tilde(s) to start you off.\n") util.sendmsg(
scorefile.write(user + "&^%" + str(prize[0]+1) + "&^%" + time + "\n") 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): def show_tildescore(channel, user, name):
with open(SCORE_FILE, "r") as scorefile: with open(SCORE_FILE, "r") as scorefile:
for idx,score in enumerate(scorefile): for _idx, score in enumerate(scorefile):
person = score.strip("\n").split("&^%") person = score.strip("\n").split("&^%")
if(person[0] == user): if person[0] == user:
ircsock.send("PRIVMSG " + channel + " :" + name + " has " + p.number_to_words(person[1]) + " tildes!\n") util.sendmsg(
ircsock,
channel,
"{} has {} tildes!".format(name, p.number_to_words(person[1])),
)
return return
#person has not played yet # person has not played yet
ircsock.send("PRIVMSG " + channel + " :" + name + " has no tildes yet!\n") util.sendmsg(ircsock, channel, "{} has no tildes yet!".format(name))
def challenge(channel, user, name, time): def challenge(channel, user, name, time):
if(channel != "#bots" and not DEBUG): if channel != "#bots" and not DEBUG:
ircsock.send("PRIVMSG " + channel + " :" + name + " is a meanie and gets no tildes. **Tildebot now only gives out tildes in the #bots channel.**\n") util.sendmsg(
ircsock,
channel,
"{} is a meanie and gets no tildes. **Tildebot now only gives out tildes in the #bots channel.**".format(
name
),
)
return return
global challenges; global challenges
challenge = puzzle.make_puzzle(); challenge = puzzle.make_puzzle()
challenges[user] = challenge[1:]; #challenges[USER] = [ANSWER, BONUS] challenges[user] = challenge[1:]
ircsock.send("PRIVMSG " + channel + " :" + name + ": " + challenge[0] + "\n") util.sendmsg(ircsock, channel, "{}: {}".format(name, challenge[0]))
def challenge_response(channel, user, name, time, msg): def challenge_response(channel, user, name, time, msg):
global challenges global challenges
print(msg); print(msg)
if(challenges.has_key(user)): if user in challenges:
answer, bonus = challenges[user] answer, bonus = challenges[user]
if((callable(answer) and answer(msg.lower())) or (msg.lower() == str(answer).lower() or msg == p.number_to_words(answer))): if (callable(answer) and answer(msg.lower())) or (
give_tilde(channel, user, name, time, True, bonus); msg.lower() == str(answer).lower() or msg == p.number_to_words(answer)
):
give_tilde(channel, user, name, time, True, bonus)
else: else:
give_tilde(channel, user, name, time, False, 0); give_tilde(channel, user, name, time, False, 0)
del challenges[user]; #delete the user from challenges either way del challenges[user]
# delete the user from challenges either way
def rollcall(channel): def rollcall(channel):
ircsock.send("PRIVMSG "+ channel +" :tildebot reporting! I respond to !tilde !tildescore\n") util.sendmsg(
ircsock, channel, "tildebot reporting! I respond to !tilde !tildescore"
)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :krowbar\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
joinchan(channel)
if(not DEBUG):
joinchan("#bots")
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
def listen(): def listen():
while 1: while 1:
ircmsg = ircsock.recv(2048) ircmsg = ircsock.recv(2048).decode()
for msg in ircmsg.split('\n'): for msg in ircmsg.split("\n"):
msg = msg.strip('\n\r') msg = msg.strip("\n\r")
if msg[:4] == "PING": if msg[:4] == "PING":
ping(msg.split(" ")[1]) util.ping(ircsock, msg)
continue
formatted = formatter.format_message(msg) formatted = util.format_message(msg)
print(formatted)
if "" == formatted: if "" == formatted:
continue continue
# print formatted iTime, user, _command, channel, messageText = formatted.split("\t")
name = util.get_name(user)
split = formatted.split("\t") if msg.find(":!tildescore") != -1:
iTime = split[0] show_tildescore(channel, user, name)
user = split[1] elif msg.find(":!tilde") != -1 and user not in challenges:
name = names.get_name(user) challenge(channel, user, name, iTime)
command = split[2] elif user in challenges and (channel == "#bots" or DEBUG):
channel = split[3] challenge_response(channel, user, name, iTime, messageText)
messageText = split[4]
if msg.find(":!tildescore") != -1: if msg.find(":!jackpot") != -1:
show_tildescore(channel, user, name) show_jackpot(channel)
elif msg.find(":!tilde") != -1 and not challenges.has_key(user):
challenge(channel, user, name, iTime)
elif challenges.has_key(user) and (channel == "#bots" or DEBUG):
challenge_response(channel, user, name, iTime, messageText)
#give_tilde(channel, user, name, iTime)
if msg.find(":!jackpot") != -1: if msg.find(":!rollcall") != -1:
show_jackpot(channel) rollcall(channel)
if msg.find(":!rollcall") != -1: sys.stdout.flush()
rollcall(channel) time.sleep(1)
if msg[:4] == "PING":
ping(msg.split(" ")[1])
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick) util.connect(ircsock, options)
listen() listen()
+150 -137
View File
@@ -10,189 +10,202 @@ import fileinput
import random import random
import time import time
import formatter
import get_users
import mentions
import pretty_date
import inflect import inflect
import names import util
parser = OptionParser() parser = OptionParser()
parser.add_option("-s", "--server", dest="server", default='127.0.0.1', parser.add_option(
help="the server to connect to", metavar="SERVER") "-s",
parser.add_option("-c", "--channel", dest="channel", default='#bot_test', "--server",
help="the channel to join", metavar="CHANNEL") dest="server",
parser.add_option("-n", "--nick", dest="nick", default='topicbot', default="127.0.0.1:6667",
help="the nick to use", metavar="NICK") 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="topicbot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
p = inflect.engine() p = inflect.engine()
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan):
ircsock.send("JOIN "+ chan +"\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
def get_topic(channel, user, time): def get_topic(channel, user, time):
#topic scores are saved as <USER>&^%<GETS SCORE>&^%<SETS SCORE> # topic scores are saved as <USER>&^%<GETS SCORE>&^%<SETS SCORE>
with open("topicscores.txt", "r") as scorefile: with open("topicscores.txt", "r") as scorefile:
scores = scorefile.readlines() scores = scorefile.readlines()
userscore = 1 userscore = 1
found = False found = False
with open("topicscores.txt", "w") as scorefile: with open("topicscores.txt", "w") as scorefile:
for idx,score in enumerate(scores): for idx, score in enumerate(scores):
data = score.strip("\n").split("&^%") data = score.strip("\n").split("&^%")
if(data[0] == user): if data[0] == user:
found = True found = True
userscore = int(data[1])+1 userscore = int(data[1]) + 1
scores[idx] = data[0] + "&^%" + str(userscore) + "&^%" + data[2] + "\n" scores[idx] = data[0] + "&^%" + str(userscore) + "&^%" + data[2] + "\n"
scorefile.writelines(scores) scorefile.writelines(scores)
if(not found): if not found:
scorefile.write(user + "&^%1&^%0\n") 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])),
),
)
with open("topics_" + channel + ".txt", "r") as topics:
topic = topics.readlines()[-1].strip("\n").split("&^%", 3)
byuser = names.get_name(topic[1])
ircsock.send("PRIVMSG "+ channel +" :I've told you " + p.number_to_words(userscore) + " times! It's \"" + topic[2] + "\" (Set by " + byuser + " " + pretty_date.pretty_date(int(topic[0])) + ")\n")
def count_topic(channel, user, time, msg): def count_topic(channel, user, time, msg):
with open("topics_" + channel + ".txt", "a") as topics: with open("topics_" + channel + ".txt", "a") as topics:
topics.write(time + "&^%" + user + "&^%" + msg + "\n") topics.write(time + "&^%" + user + "&^%" + msg + "\n")
with open("topicscores.txt", "r") as scorefile: with open("topicscores.txt", "r") as scorefile:
scores = scorefile.readlines() scores = scorefile.readlines()
userscore = 1 userscore = 1
found = False found = False
with open("topicscores.txt", "w") as scorefile: with open("topicscores.txt", "w") as scorefile:
for idx,score in enumerate(scores): for idx, score in enumerate(scores):
data = score.strip("\n").split("&^%") data = score.strip("\n").split("&^%")
if(data[0] == user): if data[0] == user:
found = True found = True
userscore = int(data[2])+1 userscore = int(data[2]) + 1
scores[idx] = data[0] + "&^%" + data[1] + "&^%" + str(userscore) + "\n" scores[idx] = data[0] + "&^%" + data[1] + "&^%" + str(userscore) + "\n"
scorefile.writelines(scores) scorefile.writelines(scores)
if(not found): if not found:
scorefile.write(user + "&^%0&^%1") scorefile.write(user + "&^%0&^%1")
ircsock.send("PRIVMSG "+ channel +" :" + user + " has changed the topic " + p.number_to_words(userscore) + " times!\n") util.sendmsg(
ircsock,
channel,
"{} has changed the topic {} times!".format(user, p.number_to_words(userscore)),
)
def set_topic(channel, user, time, msg): def set_topic(channel, user, time, msg):
ircsock.send("TOPIC "+ channel +" :" + msg + "\n") ircsock.send("TOPIC " + channel + " :" + msg + "\n")
count_topic(channel, user, time, msg) count_topic(channel, user, time, msg)
def random_topic(channel, user, time, setTopic=False): def random_topic(channel, user, time, setTopic=False):
with open("randomtopics.txt") as rtopics: with open("randomtopics.txt") as rtopics:
msg = random.choice(rtopics.readlines()).strip("\n") msg = random.choice(rtopics.readlines()).strip("\n")
if(setTopic): if setTopic:
set_topic(channel, user, time, msg) set_topic(channel, user, time, msg)
else: else:
ircsock.send("PRIVMSG "+channel +" :Suggested Topic: " + msg + "\n") util.sendmsg(ircsock, channel, "Suggested Topic: {}".format(msg))
def rollcall(channel): def rollcall(channel):
ircsock.send("PRIVMSG "+ channel +" :topicbot reporting! I respond to !topic !settopic !suggesttopic !thistory\n") util.sendmsg(
ircsock,
channel,
"topicbot reporting! I respond to !topic !settopic !suggesttopic !thistory",
)
def topic_score(channel): def topic_score(channel):
ircsock.send("PRIVMSG "+ channel +" :Not implemented yet") util.sendmsg(ircsock, channel, "Not implemented yet")
def topic_scores(channel): def topic_scores(channel):
ircsock.send("PRIVMSG "+ channel +" :Not implemented yet") util.sendmsg(ircsock, channel, "Not implemented yet")
def topic_history(channel, user, count): def topic_history(channel, user, count):
try: try:
iCount = int(count.split()[1]) iCount = int(count.split()[1])
except (ValueError, IndexError) as e: except (ValueError, IndexError):
iCount = 3 iCount = 3
if(iCount > 10): if iCount > 10:
iCount = 10 iCount = 10
if(iCount < 1): if iCount < 1:
iCount = 3 iCount = 3
with open("topics_" + channel + ".txt", "r") as topicsfile: with open("topics_" + channel + ".txt", "r") as topicsfile:
#topics = topicsfile.readlines()[-iCount:].reverse() # topics = topicsfile.readlines()[-iCount:].reverse()
ircsock.send("PRIVMSG "+ channel +" :Ok, here were the last " + p.number_to_words(iCount) + " topics\n") util.sendmsg(
for idx,topic in enumerate(reversed(topicsfile.readlines()[-iCount:])): ircsock,
topic = topic.strip("\n").split("&^%", 3) channel,
byuser = names.get_name(topic[1]) "Ok, here are the last {} topics".format(p.number_to_words(iCount)),
ircsock.send("PRIVMSG "+ channel +" :" + str(idx+1) + ": \"" + topic[2] + "\" (Set by " + byuser + " " + pretty_date.pretty_date(int(topic[0])) + ")\n") )
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 connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :krowbar\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
joinchan(channel)
joinchan("#bots")
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
def listen(): def listen():
while 1: while 1:
ircmsg = ircsock.recv(2048) ircmsg = ircsock.recv(2048).decode()
ircmsg = ircmsg.strip('\n\r') ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING": if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1]) util.ping(ircsock, ircmsg)
formatted = formatter.format_message(ircmsg) formatted = util.format_message(ircmsg)
if "" == formatted: if "" == formatted:
continue continue
# print formatted # print formatted
split = formatted.split("\t") msgtime, user, command, channel, messageText = formatted.split("\t")
msgtime = split[0]
user = split[1]
command = split[2]
channel = split[3]
messageText = split[4]
if(command == "TOPIC" and user != options.nick): if command == "TOPIC" and user != options.nick:
count_topic(channel,user, msgtime, messageText) count_topic(channel, user, msgtime, messageText)
if ircmsg.find(":!topic") != -1: if ircmsg.find(":!topic") != -1:
get_topic(channel, user, msgtime) get_topic(channel, user, msgtime)
if ircmsg.find(":!settopic") != -1: if ircmsg.find(":!settopic") != -1:
set_topic(channel, user, msgtime, messageText[10:]) set_topic(channel, user, msgtime, messageText[10:])
if ircmsg.find(":!tscores") != -1: if ircmsg.find(":!tscores") != -1:
topic_scores(channel) topic_scores(channel)
elif ircmsg.find(":!tscores") != -1: elif ircmsg.find(":!tscores") != -1:
topic_score(channel) topic_score(channel)
if ircmsg.find(":!randomtopic") != -1: if ircmsg.find(":!randomtopic") != -1:
random_topic(channel, user, msgtime, True) random_topic(channel, user, msgtime, True)
if ircmsg.find(":!suggesttopic") != -1: if ircmsg.find(":!suggesttopic") != -1:
random_topic(channel,user,msgtime, False) random_topic(channel, user, msgtime, False)
if ircmsg.find(":!thistory") != -1: if ircmsg.find(":!thistory") != -1:
topic_history(channel, user, messageText) topic_history(channel, user, messageText)
if ircmsg.find(":!rollcall") != -1: if ircmsg.find(":!rollcall") != -1:
rollcall(channel) rollcall(channel)
if ircmsg[:4] == "PING": sys.stdout.flush()
ping(ircmsg.split(" ")[1]) time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick) util.connect(ircsock, options)
listen() listen()
+42 -24
View File
@@ -2,30 +2,48 @@ import urllib
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import random import random
import re import re
def tumble(url): def tumble(url):
#Find the max pages # Find the max pages
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser') soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
pages = soup.findAll('span', 'page-numbers')[0].text.split('/')[1] #this could totally fail several ways pages = soup.findAll("span", "page-numbers")[0].text.split("/")[
tries = 3 1
while True: ] # this could totally fail several ways
try: tries = 3
page = random.randrange(1, int(pages)+1) while True:
try:
page = random.randrange(1, int(pages) + 1)
#Parse a page # Parse a page
soup = BeautifulSoup(urllib.urlopen(url + '/page/' + str(page)).read(), 'html.parser') soup = BeautifulSoup(
article = random.choice(soup.findAll('article')) urllib.urlopen(url + "/page/" + str(page)).read(), "html.parser"
quote = article.find('blockquote').text.replace('\n',''); )
if len(article.find('footer').findAll('ul')) > 1: article = random.choice(soup.findAll("article"))
quote += re.sub('\n+', ' ', article.find('footer').findAll('ul')[0].text); #the hash tags quote = article.find("blockquote").text.replace("\n", "")
quote += '(' + re.sub('\n+', ' ', article.find('footer').findAll('ul')[1].text) + ')'; #and the date and notes if len(article.find("footer").findAll("ul")) > 1:
else: quote += re.sub(
quote += '(' + re.sub('\n+', ' ', article.find('footer').findAll('ul')[0].text) + ')'; #just the date and notes "\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.encode('ascii', 'ignore') return quote.encode("ascii", "ignore")
except: #sometimes we fail. let's retry a few times except: # sometimes we fail. let's retry a few times
if tries == 0: if tries == 0:
return '' return ""
else: else:
tries -= 1 tries -= 1
break break
+264
View File
@@ -0,0 +1,264 @@
import json
import time
import random
import re
def ping(ircsock, msg):
ircsock.send("PONG {}\n".format(msg.split(" ")[1]).encode())
def sendmsg(ircsock, chan, msg):
print("sending {} to {}".format(msg, chan))
ircsock.send("PRIVMSG {} :{}\r\n".format(chan, 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)
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
+194 -137
View File
@@ -12,20 +12,35 @@ import time
import re import re
import operator import operator
import formatter
import get_users
import mentions
import pretty_date
import inflect import inflect
import util
parser = OptionParser() parser = OptionParser()
parser.add_option("-s", "--server", dest="server", default='127.0.0.1', parser.add_option(
help="the server to connect to", metavar="SERVER") "-s",
parser.add_option("-c", "--channel", dest="channel", default='#bot_test', "--server",
help="the channel to join", metavar="CHANNEL") dest="server",
parser.add_option("-n", "--nick", dest="nick", default='numberwang_bot', default="127.0.0.1:6667",
help="the nick to use", metavar="NICK") 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() (options, args) = parser.parse_args()
@@ -43,116 +58,165 @@ guesses = 0
lastGuesser = "" lastGuesser = ""
currentScores = {} currentScores = {}
def resetGlobals(): def resetGlobals():
global roundsLeft
global bonusRound
global guesses
global lastGuesser
global currentScores
roundsLeft = 0
bonusRound = 0
guesses = 0
lastGuesser = ""
currentScores.clear()
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan):
ircsock.send("JOIN "+ chan +"\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
def start_numberwang(channel, user):
if(channel != "#bots"):
ircsock.send("PRIVMSG " + channel + " :Numberwang has been disabled for " + channel + " due to spamminess. Please join " + GOOD_CHAN + " to start a game.\n")
return
print user + " started a game"
resetGlobals()
ircsock.send("PRIVMSG " + channel + " :It's time for Numberwang!\n")
time.sleep(1)
ircsock.send("PRIVMSG " + channel + " :Here's how to play:\n")
ircsock.send("PRIVMSG " + channel + " :1. There are 10 rounds\n")
ircsock.send("PRIVMSG " + channel + " :2. Each round lasts 10 seconds. You're up against the clock!\n")
ircsock.send("PRIVMSG " + channel + " :3. Play your numbers, as long as they're between 0 and 99.\n")
ircsock.send("PRIVMSG " + channel + " :4. That's Numberwang!\n")
time.sleep(2)
ircsock.send("PRIVMSG " + channel + " :Let's get started!\n")
global roundsLeft global roundsLeft
global bonusRound global bonusRound
roundsLeft = random.randint(MIN_ROUNDS,MAX_ROUNDS) global guesses
bonusRound = random.randint(2,roundsLeft-1) global lastGuesser
print "There will be " + str(roundsLeft) + " rounds with the bonus on round " + str(roundsLeft - bonusRound + 1) 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): def print_scores(channel):
scoreStrs = [] scoreStrs = []
first = True first = True
for name in currentScores: for name in currentScores:
scoreStrs.append(name + " is " + ("also " if not first and random.randint(1,3) == 3 else "") + "on " + str(currentScores[name])) scoreStrs.append(
"{} is {} on {}".format(
name,
("also " if not first and random.randint(1, 3) == 3 else ""),
currentScores[name],
)
)
first = False first = False
ircsock.send("PRIVMSG " + channel + " :" + p.join(scoreStrs) + "!\n") util.sendmsg(ircsock, channel, p.join(scoreStrs))
def guess_numberwang(channel, user, messageText): def guess_numberwang(channel, user, messageText):
global guesses global guesses
global lastGuesser global lastGuesser
global currentScores global currentScores
global roundsLeft global roundsLeft
print user + " guessed '" + messageText + "'" print(user + " guessed '" + messageText + "'")
guess = re.sub('[^0-9]','',messageText.split()[0]) #must have a number in the first 'word' guess = re.sub(
if(guess): "[^0-9]", "", messageText.split()[0]
if(LIMIT_GUESSING and user == lastGuesser): ) # must have a number in the first 'word'
ircsock.send("PRIVMSG " + channel + " :" + user + ", you just guessed! Give another player a try!\n") if guess:
if LIMIT_GUESSING and user == lastGuesser:
util.sendmsg(
ircsock,
channel,
"{}, you just guessed! Give another player a try!".format(user),
)
else: else:
guesses += 1 guesses += 1
lastGuesser = user lastGuesser = user
###CORRECT GUESS### ###CORRECT GUESS###
if(random.randint(0,10) > 10 - guesses): #the more guesses, the higher the probability if (
random.randint(0, 10) > 10 - guesses
): # the more guesses, the higher the probability
guesses = 0 guesses = 0
lastGuesser = "" lastGuesser = ""
ircsock.send("PRIVMSG " + channel + " :" + user + ": THAT'S NUMBERWANG!\n") util.sendmsg(ircsock, channel, "{}: THAT'S NUMBERWANG!".format(user))
points = random.randint(2,10) * (random.randint(2,4) if roundsLeft == bonusRound else 1) points = random.randint(2, 10) * (
random.randint(2, 4) if roundsLeft == bonusRound else 1
)
if user in currentScores.keys(): if user in currentScores.keys():
currentScores[user] += points currentScores[user] += points
else: else:
currentScores[user] = points currentScores[user] = points
roundsLeft -= 1 roundsLeft -= 1
time.sleep(2) time.sleep(2)
if(roundsLeft == 0): if roundsLeft == 0:
ircsock.send("PRIVMSG " + channel + " :Numberwang is now over. Thank you for playing!\n") util.sendmsg(
ircsock.send("PRIVMSG " + channel + " :Final scores:\n") ircsock,
channel,
"Numberwang is now over. Thank you for playing!",
)
util.sendmsg(ircsock, channel, "Final scores:")
print_scores(channel) print_scores(channel)
save_scores() save_scores()
else: else:
print_scores(channel) print_scores(channel)
newRoundStr = "" newRoundStr = ""
if(roundsLeft == 1): if roundsLeft == 1:
newRoundStr += "The last round is Wangernumb!" newRoundStr += "The last round is Wangernumb!"
elif(roundsLeft == bonusRound): elif roundsLeft == bonusRound:
newRoundStr += "**Bonus Round!**" newRoundStr += "**Bonus Round!**"
else: else:
newRoundStr += "New Round!" newRoundStr += "New Round!"
if(random.randint(1,10) > 8): if random.randint(1, 10) > 8:
newRoundStr += " Let's rotate the board!" newRoundStr += " Let's rotate the board!"
ircsock.send("PRIVMSG " + channel + " :" + newRoundStr + " Start guessing!\n") util.sendmsg(
ircsock, channel, "{} Start guessing!".format(newRoundStr)
)
###INCORRECT GUESS### ###INCORRECT GUESS###
else: else:
ircsock.send("PRIVMSG " + channel + " :" + random.choice(["Sorry", "I'm sorry", "No", "Nope"]) + ", " + user + ", " \ util.sendmsg(
+ random.choice(["that's not", "that is not", "that isn't", "that is not", "that won't make", "that will not make"])\ ircsock,
+ " Numberwang!\n") 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): def stop_numberwang(channel, user):
print user + " stopped a game" print(user + " stopped a game")
resetGlobals() resetGlobals()
ircsock.send("PRIVMSG " + channel + " :Numberwang has been stopped. No points have been awarded. " + user + " is such a party pooper!\n") util.sendmsg(
ircsock,
channel,
"Numberwang has been stopped. No points have been awarded. {} is such a party pooper!".format(
user
),
)
def save_scores(): def save_scores():
with open(SCORE_FILE, "r+") as scorefile: with open(SCORE_FILE, "r+") as scorefile:
@@ -162,15 +226,17 @@ def save_scores():
for line in scores: for line in scores:
for name in currentScores: for name in currentScores:
score = line.strip("\n").split("&^%") score = line.strip("\n").split("&^%")
if(score[0] == name): if score[0] == name:
line = score[0] + "&^%" + str(int(score[1]) + currentScores[name]) + "\n" line = "{}&^%{}\n".format(
score[0], int(score[1]) + currentScores[name]
)
del currentScores[name] del currentScores[name]
break break
scorefile.write(line) scorefile.write(line)
for name in currentScores: #new wangers for name in currentScores: # new wangers
line = name + "&^%" + str(currentScores[name]) + "\n" scorefile.write("{}&^%{}\n".format(name, currentScores[name]))
scorefile.write(line)
def show_highscores(channel): def show_highscores(channel):
with open(SCORE_FILE, "r") as scorefile: with open(SCORE_FILE, "r") as scorefile:
@@ -180,86 +246,77 @@ def show_highscores(channel):
scores.append((int(sline[1]), sline[0])) scores.append((int(sline[1]), sline[0]))
scores = sorted(scores, reverse=True)[:SHOW_TOP_NUM] scores = sorted(scores, reverse=True)[:SHOW_TOP_NUM]
ircsock.send("PRIVMSG " + channel + " : ====TOP WANGERS====\n") util.sendmsg(ircsock, channel, "====TOP WANGERS====")
for score in scores: for score in scores:
ircsock.send("PRIVMSG " + channel + " :== ~" + score[1] + " (" + str(score[0]) + " points!) ==\n") util.sendmsg(
ircsock, channel, " :== ~{} ({} points!) ==".format(score[1], score[0])
)
def show_user_score(channel, user): def show_user_score(channel, user):
with open(SCORE_FILE, "r") as scorefile: with open(SCORE_FILE, "r") as scorefile:
for line in scorefile.readlines(): for line in scorefile.readlines():
score = line.strip("\n").split("&^%") score = line.strip("\n").split("&^%")
if(user == score[0]): if user == score[0]:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Your global numberwang score is " + str(score[1]) + "!\n") util.sendmsg(
ircsock,
channel,
"{}: Your global numberwang score is {}!".format(user, score[1]),
)
return return
#if we don't find a score line # if we don't find a score line
ircsock.send("PRIVMSG " + channel + " :" + user + ": You haven't scored any points yet!\n") util.sendmsg(
ircsock, channel, "{} You haven't scored any points yet!".format(user)
)
def rollcall(channel): def rollcall(channel):
ircsock.send("PRIVMSG "+ 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\n") 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 connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :krowbar\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
joinchan(channel)
joinchan(GOOD_CHAN)
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
def listen(): def listen():
while 1: while 1:
ircmsg = ircsock.recv(2048) ircmsg = ircsock.recv(2048).decode()
ircmsg = ircmsg.strip('\n\r') ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING": if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1]) util.ping(ircsock, ircmsg)
formatted = formatter.format_message(ircmsg) formatted = util.format_message(ircmsg)
if "" == formatted: if "" == formatted:
continue continue
# print formatted # print formatted
split = formatted.split("\t") _time, user, _command, channel, messageText = formatted.split("\t")
time = split[0]
user = split[1]
command = split[2]
channel = split[3]
messageText = split[4]
if ircmsg.find(":!numberwang") != -1 and roundsLeft == 0: if ircmsg.find(":!numberwang") != -1 and roundsLeft == 0:
start_numberwang(channel, user) start_numberwang(channel, user)
if channel == GOOD_CHAN: if channel == GOOD_CHAN:
if ircmsg.find(":!wangernumb") != -1 and roundsLeft > 0: if ircmsg.find(":!wangernumb") != -1 and roundsLeft > 0:
stop_numberwang(channel, user) stop_numberwang(channel, user)
if roundsLeft > 0: if roundsLeft > 0:
guess_numberwang(channel, user, messageText) guess_numberwang(channel, user, messageText)
if ircmsg.find(":!topwangers") != -1: if ircmsg.find(":!topwangers") != -1:
show_highscores(channel) show_highscores(channel)
if ircmsg.find(":!myscore") != -1: if ircmsg.find(":!myscore") != -1:
show_user_score(channel, user) show_user_score(channel, user)
if ircmsg.find(":!rollcall") != -1: if ircmsg.find(":!rollcall") != -1:
rollcall(channel) rollcall(channel)
if ircmsg[:4] == "PING": sys.stdout.flush()
ping(ircmsg.split(" ")[1]) time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick) util.connect(ircsock, options)
listen() listen()
+5 -1
View File
@@ -1,6 +1,10 @@
import random import random
def get_thing(): def get_thing():
file = "/home/krowbar/logs/welchdata.txt" file = "/home/krowbar/logs/welchdata.txt"
thing = "" thing = ""
return "Thing Mr. Welch can no longer do in a RPG #" + random.choice(list(open(file))).rstrip() return (
"Thing Mr. Welch can no longer do in a RPG #"
+ random.choice(list(open(file))).rstrip()
)
+17 -13
View File
@@ -8,20 +8,24 @@ import operator
MAX_NODES = 5 MAX_NODES = 5
logfile = "/home/jumblesale/Code/irc/log" logfile = "/home/jumblesale/Code/irc/log"
timeCutoff = calendar.timegm(time.gmtime()) - (3 * 7 * 24 * 60 * 60) #3 weeks timeCutoff = calendar.timegm(time.gmtime()) - (3 * 7 * 24 * 60 * 60) # 3 weeks
nameFix = { nameFix = {
'jumblesal': 'jumblesale', "jumblesal": "jumblesale",
'hardmath1': 'kc', "hardmath1": "kc",
'hardmath123': 'kc', "hardmath123": "kc",
'bendorphan': 'endorphant', "bendorphan": "endorphant",
'endorphan': 'endorphant', "endorphan": "endorphant",
'synergian': 'synergiance' "synergian": "synergiance",
} }
def whoSaid(word): def whoSaid(word):
word = word.lower() word = word.lower()
userData = {} #hash keyed by "user" that contains a hash of mentioned other users with count userData = (
#Get a list of all user names by checking the logs for people who have said things {}
) # 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: with open(logfile, "r") as log:
for line in log: for line in log:
try: try:
@@ -32,12 +36,12 @@ def whoSaid(word):
else: else:
user = user.lower() user = user.lower()
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse 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 time > timeCutoff and message[0] is not "!" and word in message.lower():
if user in userData: if user in userData:
userData[user] += 1 userData[user] += 1
else: else:
userData[user] = 1 userData[user] = 1
userData = sorted(userData.items(), key=operator.itemgetter(1), reverse=True) userData = sorted(userData.items(), key=operator.itemgetter(1), reverse=True)
return {'timecutoff': timeCutoff, 'data': userData} return {"timecutoff": timeCutoff, "data": userData}
+69 -40
View File
@@ -1,50 +1,79 @@
import urllib import urllib
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import random import random
def get_philosophy(word, max_steps=20):
step_words = [word]
steps = 0
url = 'https://en.wikipedia.org/wiki/%s' % word
while steps < max_steps: def get_philosophy(word, max_steps=20):
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser') step_words = [word]
title = soup.find('h1', id='firstHeading') steps = 0
content = soup.find('div', id='mw-content-text')
if not content: url = "https://en.wikipedia.org/wiki/%s" % word
break while steps < max_steps:
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] soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
step_words.append(item.get('title')) title = soup.find("h1", id="firstHeading")
#print item.get('title') + "\n" content = soup.find("div", id="mw-content-text")
url = 'https://en.wikipedia.org%s' % item.get('href') if not content:
steps += 1 break
return step_words 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%s" % item.get("href")
steps += 1
return step_words
def containsAny(str, set): def containsAny(str, set):
return 1 in [c in str for c in set] return 1 in [c in str for c in set]
def get_philosophy_lower(word, max_steps=20): def get_philosophy_lower(word, max_steps=20):
step_words = [word] step_words = [word]
steps = 0 steps = 0
url = 'https://en.wikipedia.org/wiki/%s' % word
while steps < max_steps:
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser')
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
url = "https://en.wikipedia.org/wiki/%s" % word
while steps < max_steps:
soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
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
+9 -7
View File
@@ -2,17 +2,19 @@ import duckduckgo
import urllib import urllib
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
def xkcd(query): def xkcd(query):
res = duckduckgo.get_zci('site:xkcd.com ' + query); res = duckduckgo.get_zci("site:xkcd.com " + query)
title = ""; title = ""
try: #ddg returns a url for these searches. i want a title as well try: # ddg returns a url for these searches. i want a title as well
title = BeautifulSoup(urllib.urlopen(res).read(), 'html.parser').title.text title = BeautifulSoup(urllib.urlopen(res).read(), "html.parser").title.text
except: except:
pass #just swallow the error. maybe the result wasn't a url or something else bad happened pass # just swallow the error. maybe the result wasn't a url or something else bad happened
return [(((title + ' - ') if title else '') + res).encode('ascii', 'ignore')] return [(((title + " - ") if title else "") + res).encode("ascii", "ignore")]
# never mind, blocked by ddg # never mind, blocked by ddg
#def xkcd_links(query): # def xkcd_links(query):
# url = "https://duckduckgo.com/html/?q=site%3Axkcd.com+" + query.replace(' ', '+') # url = "https://duckduckgo.com/html/?q=site%3Axkcd.com+" + query.replace(' ', '+')
# soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser') # soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser')
# items = soup.find_all("a", class_="result__a") # items = soup.find_all("a", class_="result__a")
+88 -55
View File
@@ -11,29 +11,30 @@ import operator
MAX_NODES = 4 MAX_NODES = 4
logfile = "/home/archangelic/irc/log" logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log" # logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/chatBesties.json" outfile = "/home/krowbar/logs/chatBesties.json"
outCircle = "/home/krowbar/logs/chatcircle.json" outCircle = "/home/krowbar/logs/chatcircle.json"
timePeriod = calendar.timegm(time.gmtime()) - (2 * 7 * 24 * 60 * 60) #2 weeks timePeriod = calendar.timegm(time.gmtime()) - (2 * 7 * 24 * 60 * 60) # 2 weeks
userData = {} #hash keyed by "user" that contains a hash of mentioned other users with count # hash keyed by "user" that contains a hash of mentioned other users with count
userData = {}
nameFix = { nameFix = {
'jumblesal': 'jumblesale', "jumblesal": "jumblesale",
'hardmath1': 'kc', "hardmath1": "kc",
'hardmath123': 'kc', "hardmath123": "kc",
'bendorphan': 'endorphant', "bendorphan": "endorphant",
'endorphan': 'endorphant', "endorphan": "endorphant",
'synergian': 'synergiance' "synergian": "synergiance",
} }
users = [] users = []
#Get a list of all user names by checking the logs for people who have said things # Get a list of all user names by checking the logs for people who have said things
with open(logfile, "r") as log: with open(logfile, "r") as log:
for line in log: for line in log:
try: try:
time, user, message = line.split("\t", 3) time, user, message = line.split("\t", 3)
if int(time) < timePeriod: if int(time) < timePeriod:
continue #only add users who have spoken in the last period continue # only add users who have spoken in the last period
if nameFix.has_key(user): if nameFix.has_key(user):
user = nameFix[user] user = nameFix[user]
else: else:
@@ -42,73 +43,105 @@ with open(logfile, "r") as log:
if user not in users: if user not in users:
users.append(user) users.append(user)
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse continue # There are some bad lines in the log file that we'll ignore if we can't parse
d3data = {} d3data = {}
d3data['nodes'] = [] d3data["nodes"] = []
#re-read the log and this time look for instances of user names in messages # re-read the log and this time look for instances of user names in messages
with open(logfile, "r") as log: with open(logfile, "r") as log:
for line in log: for line in log:
try: try:
time, user, message = line.split("\t", 3) time, user, message = line.split("\t", 3)
if int(time) < timePeriod: if int(time) < timePeriod:
continue #only consider the past three weeks of chats continue # only consider the past three weeks of chats
if nameFix.has_key(user): if nameFix.has_key(user):
user = nameFix[user] user = nameFix[user]
else: else:
user = user.lower() user = user.lower()
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse continue # There are some bad lines in the log file that we'll ignore if we can't parse
for word in message.split(' '): for word in message.split(" "):
word = re.sub('[^A-Za-z0-9]+', '', word) word = re.sub("[^A-Za-z0-9]+", "", word)
if word in users: #SOMEONE MENTIONED SOMEONE if word in users: # SOMEONE MENTIONED SOMEONE
if userData.has_key(user): #This user is already set up if userData.has_key(user): # This user is already set up
if userData[user]['data'].has_key(word): #This user has mentioned this person before if userData[user]["data"].has_key(
userData[user]['data'][word] += 1 word
else: #This user never mentioned this person before ): # This user has mentioned this person before
userData[user]['data'][word] = 1 userData[user]["data"][word] += 1
#give both the target and mentioner a point else: # This user never mentioned this person before
else: #This user was never set up userData[user]["data"][word] = 1
userData[user] = {} #make it a dictionary! # give both the target and mentioner a point
userData[user]['data'] = {} else: # This user was never set up
userData[user]['data'][word] = 1 userData[user] = {} # make it a dictionary!
userData[user]['score'] = 0 userData[user]["data"] = {}
userData[user]['id'] = len(d3data['nodes']) #so we know how to match people during the links phase userData[user]["data"][word] = 1
d3data['nodes'].append({"name": user, "group": 1}) userData[user]["score"] = 0
if not userData.has_key(word): #check if the target has not been set up userData[user]["id"] = len(
d3data["nodes"]
) # so we know how to match people during the links phase
d3data["nodes"].append({"name": user, "group": 1})
if not userData.has_key(
word
): # check if the target has not been set up
userData[word] = {} userData[word] = {}
userData[word]['data'] = {} userData[word]["data"] = {}
userData[word]['score'] = 0 userData[word]["score"] = 0
userData[word]['id'] = len(d3data['nodes']) userData[word]["id"] = len(d3data["nodes"])
d3data['nodes'].append({"name": word, "group": 1}) d3data["nodes"].append({"name": word, "group": 1})
userData[user]['score'] += 1 userData[user]["score"] += 1
userData[word]['score'] += 1 userData[word]["score"] += 1
d3data['links'] = [] d3data["links"] = []
#Now connect all the pople to their stuff # Now connect all the pople to their stuff
for user, values in userData.iteritems(): for user, values in userData.iteritems():
#give the user a 'group' based on their total score # give the user a 'group' based on their total score
d3data['nodes'][values['id']]['group'] = int(math.ceil(math.log(values['score']))) d3data["nodes"][values["id"]]["group"] = int(math.ceil(math.log(values["score"])))
besties = sorted(values['data'].items(), key=operator.itemgetter(1), reverse=True)[0:MAX_NODES] #ONLY the top besties besties = sorted(values["data"].items(), key=operator.itemgetter(1), reverse=True)[
0:MAX_NODES
] # ONLY the top besties
for target, score in besties: for target, score in besties:
try: try:
print "Adding link from " + user + " (" + str(values['id']) + ") to " + target + " (" + str(userData[target]['id']) + ") with strength " + str(score) print(
d3data['links'].append({"source": values['id'], "target": userData[target]['id'], "value": math.ceil(math.sqrt(score))*2 }) "Adding link from "
+ user
+ " ("
+ str(values["id"])
+ ") to "
+ target
+ " ("
+ str(userData[target]["id"])
+ ") with strength "
+ str(score)
)
d3data["links"].append(
{
"source": values["id"],
"target": userData[target]["id"],
"value": math.ceil(math.sqrt(score)) * 2,
}
)
except KeyError: except KeyError:
print "! Error when trying to link " + user + " to " + target print("! Error when trying to link " + user + " to " + target)
continue continue
if len(values['data']) > MAX_NODES: if len(values["data"]) > MAX_NODES:
print " ...ignoring " + str(len(values['data']) - MAX_NODES) + " more connections from " + user print(
" ...ignoring "
+ str(len(values["data"]) - MAX_NODES)
+ " more connections from "
+ user
)
d3Circle = {} d3Circle = {}
d3Circle['names'] = [''] * len(userData) d3Circle["names"] = [""] * len(userData)
d3Circle['matrix'] = [[0] * len(userData)] * len(userData) d3Circle["matrix"] = [[0] * len(userData)] * len(userData)
for user, values in userData.iteritems(): for user, values in userData.iteritems():
d3Circle['names'][values['id']] = user d3Circle["names"][values["id"]] = user
for name, score in values['data'].iteritems(): for name, score in values["data"].iteritems():
d3Circle['matrix'][values['id']][userData[name]['id']] = score if score > 1 else 0 d3Circle["matrix"][values["id"]][userData[name]["id"]] = (
score if score > 1 else 0
)
with open(outfile + ".tmp", "w") as tmpFile: with open(outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(d3data)) tmpFile.write(json.dumps(d3data))
+11 -11
View File
@@ -6,10 +6,10 @@ import calendar
import shutil import shutil
logfile = "/home/archangelic/irc/log" logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log" # logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/userData.json" outfile = "/home/krowbar/logs/userData.json"
userData = {} #hash keyed by "user" that contains an array of timestamps userData = {} # hash keyed by "user" that contains an array of timestamps
#we only care about recent chats, let's say for the past couple weeks # we only care about recent chats, let's say for the past couple weeks
oneWeek = 7 * 24 * 60 * 60 oneWeek = 7 * 24 * 60 * 60
fiveMinutes = 5 * 60 fiveMinutes = 5 * 60
timeCutoff = calendar.timegm(time.gmtime()) - (5 * oneWeek) timeCutoff = calendar.timegm(time.gmtime()) - (5 * oneWeek)
@@ -20,17 +20,17 @@ with open(logfile, "r") as log:
time, user, message = line.split("\t", 3) time, user, message = line.split("\t", 3)
time = int(time) time = int(time)
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse continue # There are some bad lines in the log file that we'll ignore if we can't parse
if time > timeCutoff: if time > timeCutoff:
#standardize all times into a single "week" # standardize all times into a single "week"
#time %= oneWeek # time %= oneWeek
#if the user already exists in the list # if the user already exists in the list
if user in userData: if user in userData:
if time < userData[user][-1] + fiveMinutes: if time < userData[user][-1] + fiveMinutes:
continue #only record times that are at least five minutes apart continue # only record times that are at least five minutes apart
userData[user].append(time) #append the new time userData[user].append(time) # append the new time
else: #if they are new else: # if they are new
userData[user] = [time] #create a new list userData[user] = [time] # create a new list
with open(outfile + ".tmp", "w") as tmpFile: with open(outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(userData)) tmpFile.write(json.dumps(userData))
shutil.move(outfile + ".tmp", outfile) shutil.move(outfile + ".tmp", outfile)
+29 -20
View File
@@ -7,22 +7,27 @@ import re
import shutil import shutil
logfile = "/home/archangelic/irc/log" logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log" # logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/chatcloud.json" outfile = "/home/krowbar/logs/chatcloud.json"
#outfile = "/home/krowbar/logs/chatcloud_2016_10.json" # outfile = "/home/krowbar/logs/chatcloud_2016_10.json"
bannedUsersFile = "/home/krowbar/Code/python/bannedUsers" bannedUsersFile = "/home/krowbar/Code/python/bannedUsers"
bannedWordsFile = "/home/krowbar/Code/python/bannedWords" bannedWordsFile = "/home/krowbar/Code/python/bannedWords"
wordData = {} # keyed by "word" that contains a count wordData = {} # keyed by "word" that contains a count
#we only care about recent chats, let's say for the past sixteen hours # we only care about recent chats, let's say for the past sixteen hours
timeTo = calendar.timegm(time.gmtime()) timeTo = calendar.timegm(time.gmtime())
#timeTo = calendar.timegm(time.strptime("1 Nov 16", "%d %b %y")) # timeTo = calendar.timegm(time.strptime("1 Nov 16", "%d %b %y"))
timeCutoff = timeTo - (16 * 60 * 60) timeCutoff = timeTo - (16 * 60 * 60)
#timeCutoff = calendar.timegm(time.strptime("1 Oct 16", "%d %b %y")) # timeCutoff = calendar.timegm(time.strptime("1 Oct 16", "%d %b %y"))
print "Generating word cloud based off words from " + str(timeCutoff) + " to " + str(timeTo) print(
minOccurance = 3 #we'll have to reduce the minOccurances if we reduce the timeCutoff "Generating word cloud based off words from "
minLength = 3 #number of letters long + str(timeCutoff)
+ " to "
+ str(timeTo)
)
minOccurance = 3 # we'll have to reduce the minOccurances if we reduce the timeCutoff
minLength = 3 # number of letters long
bannedWords = open(bannedWordsFile).read().splitlines() bannedWords = open(bannedWordsFile).read().splitlines()
bannedUsers = open(bannedUsersFile).read().splitlines() bannedUsers = open(bannedUsersFile).read().splitlines()
@@ -32,24 +37,28 @@ with open(logfile, "r") as log:
time, user, message = line.split("\t", 3) time, user, message = line.split("\t", 3)
time = int(time) time = int(time)
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse continue # There are some bad lines in the log file that we'll ignore if we can't parse
if user in bannedUsers: if user in bannedUsers:
continue #We don't care what they say continue # We don't care what they say
if time >= timeCutoff and time <= timeTo: if time >= timeCutoff and time <= timeTo:
#print "Processing line from " + user + " at " + str(time) # print "Processing line from " + user + " at " + str(time)
for word in re.sub('[\'\"\`\/\\;:,.?!*&^\-()<>\{\}|_\[\]0-9]', ' ', message).lower().split(): for word in (
#changing symbols into spaces instead of stripping them avoids compounded words re.sub("['\"\`\/\\;:,.?!*&^\-()<>\{\}|_\[\]0-9]", " ", message)
.lower()
.split()
):
# changing symbols into spaces instead of stripping them avoids compounded words
if len(word) < minLength or word in bannedWords: if len(word) < minLength or word in bannedWords:
#print "Rejecting " + word # print "Rejecting " + word
continue continue
#if the word already exists in the list # if the word already exists in the list
if word in wordData: if word in wordData:
wordData[word] += 1 wordData[word] += 1
else: #if they are new else: # if they are new
wordData[word] = 1 wordData[word] = 1
#print "Added word: " + word # print "Added word: " + word
wordData = {i:wordData[i] for i in wordData if wordData[i] >= minOccurance } wordData = {i: wordData[i] for i in wordData if wordData[i] >= minOccurance}
if(len(wordData) == 0): if len(wordData) == 0:
wordData = {"NOTHING": 1, "INTERESTING": 1, "TODAY": 1} wordData = {"NOTHING": 1, "INTERESTING": 1, "TODAY": 1}
with open(outfile + ".tmp", "w") as tmpFile: with open(outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(wordData)) tmpFile.write(json.dumps(wordData))
+69 -26
View File
@@ -10,27 +10,66 @@ import logging, sys
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
parser = argparse.ArgumentParser(description='Generate word cloud data based off of irc chat logs') parser = argparse.ArgumentParser(
parser.add_argument('-logfile', help='irc log file to read from', default='/home/archangelic/irc/log') description="Generate word cloud data based off of irc chat logs"
parser.add_argument('-outfile', help='output file to write to', default='') )
parser.add_argument(
"-logfile", help="irc log file to read from", default="/home/archangelic/irc/log"
)
parser.add_argument("-outfile", help="output file to write to", default="")
parser.add_argument('-timeend', type=int, help='end time of the word cloud (in epoch time)', default=calendar.timegm(time.gmtime())) parser.add_argument(
parser.add_argument('-timestart', type=int, help='start time of the word cloud (in epoch time)', default=-1) "-timeend",
type=int,
help="end time of the word cloud (in epoch time)",
default=calendar.timegm(time.gmtime()),
)
parser.add_argument(
"-timestart",
type=int,
help="start time of the word cloud (in epoch time)",
default=-1,
)
parser.add_argument('-bannedUsersFile', help='file containing list of banned users', default='/home/krowbar/Code/python/bannedUsers') parser.add_argument(
parser.add_argument('-bannedWordsFile', help='file containing list of banned words', default='/home/krowbar/Code/python/bannedWords') "-bannedUsersFile",
help="file containing list of banned users",
default="/home/krowbar/Code/python/bannedUsers",
)
parser.add_argument(
"-bannedWordsFile",
help="file containing list of banned words",
default="/home/krowbar/Code/python/bannedWords",
)
parser.add_argument('-minLength', type=int, help='minimum size of words to include in the cloud', default=3) parser.add_argument(
parser.add_argument('-minOccurrence', type=int, help='the minimum occurence of a word to include it in the cloud', default=3) "-minLength",
type=int,
help="minimum size of words to include in the cloud",
default=3,
)
parser.add_argument(
"-minOccurrence",
type=int,
help="the minimum occurence of a word to include it in the cloud",
default=3,
)
args = parser.parse_args() args = parser.parse_args()
wordData = {} # keyed by "word" that contains a count wordData = {} # keyed by "word" that contains a count
#we only care about recent chats, let's say for the past sixteen hours # we only care about recent chats, let's say for the past sixteen hours
args.timestart = args.timestart if args.timestart != -1 else args.timeend - (16 * 60 * 60) args.timestart = (
#timeCutoff = calendar.timegm(time.strptime("1 Oct 16", "%d %b %y")) args.timestart if args.timestart != -1 else args.timeend - (16 * 60 * 60)
logging.info("Generating word cloud based off words from " + str(args.timestart) + " to " + str(args.timeend)) )
# timeCutoff = calendar.timegm(time.strptime("1 Oct 16", "%d %b %y"))
logging.info(
"Generating word cloud based off words from "
+ str(args.timestart)
+ " to "
+ str(args.timeend)
)
bannedWords = open(args.bannedWordsFile).read().splitlines() bannedWords = open(args.bannedWordsFile).read().splitlines()
bannedUsers = open(args.bannedUsersFile).read().splitlines() bannedUsers = open(args.bannedUsersFile).read().splitlines()
@@ -41,27 +80,31 @@ with open(args.logfile, "r") as log:
time, user, message = line.split("\t", 3) time, user, message = line.split("\t", 3)
time = int(time) time = int(time)
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse continue # There are some bad lines in the log file that we'll ignore if we can't parse
if user in bannedUsers: if user in bannedUsers:
continue #We don't care what they say continue # We don't care what they say
if time >= args.timestart and time <= args.timeend: if time >= args.timestart and time <= args.timeend:
#print "Processing line from " + user + " at " + str(time) # print "Processing line from " + user + " at " + str(time)
for word in re.sub('[\'\"\`\/\\;:,.?!*&^\-()<>\{\}|_\[\]0-9]', ' ', message).lower().split(): for word in (
#changing symbols into spaces instead of stripping them avoids compounded words re.sub("['\"\`\/\\;:,.?!*&^\-()<>\{\}|_\[\]0-9]", " ", message)
.lower()
.split()
):
# changing symbols into spaces instead of stripping them avoids compounded words
if len(word) < args.minLength or word in bannedWords: if len(word) < args.minLength or word in bannedWords:
#print "Rejecting " + word # print "Rejecting " + word
continue continue
#if the word already exists in the list # if the word already exists in the list
if word in wordData: if word in wordData:
wordData[word] += 1 wordData[word] += 1
else: #if they are new else: # if they are new
wordData[word] = 1 wordData[word] = 1
#print "Added word: " + word # print "Added word: " + word
wordData = {i:wordData[i] for i in wordData if wordData[i] >= args.minOccurrence } wordData = {i: wordData[i] for i in wordData if wordData[i] >= args.minOccurrence}
if len(wordData) == 0: if len(wordData) == 0:
wordData = {"NOTHING": 1, "INTERESTING": 1, "TODAY": 1} wordData = {"NOTHING": 1, "INTERESTING": 1, "TODAY": 1}
if args.outfile == '': if args.outfile == "":
print json.dumps(wordData) print(json.dumps(wordData))
else: else:
with open(args.outfile + ".tmp", "w") as tmpFile: with open(args.outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(wordData)) tmpFile.write(json.dumps(wordData))
+29 -14
View File
@@ -6,10 +6,13 @@ import calendar
import shutil import shutil
logfile = "/home/archangelic/irc/log" logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log" # logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/chatStack.json" outfile = "/home/krowbar/logs/chatStack.json"
chatData = { 'hours': [], 'regions': {} } #hash keyed by "region" and then hour that counts chat instances chatData = {
#we only care about recent chats, let's say for the past couple weeks "hours": [],
"regions": {},
} # hash keyed by "region" and then hour that counts chat instances
# we only care about recent chats, let's say for the past couple weeks
oneHour = 60 * 60 oneHour = 60 * 60
oneWeek = 7 * 24 * 60 * 60 oneWeek = 7 * 24 * 60 * 60
timeNow = calendar.timegm(time.gmtime()) timeNow = calendar.timegm(time.gmtime())
@@ -17,38 +20,50 @@ timeCutoff = calendar.timegm(time.gmtime()) - (2 * oneWeek)
# this will eventually represent each region users are from # this will eventually represent each region users are from
def getAllRegions(): def getAllRegions():
return ['unknown'] return ["unknown"]
# this will provide a way to look up what region a user is from # this will provide a way to look up what region a user is from
def getRegion(user): def getRegion(user):
return 'unknown' return "unknown"
# populate the hours array with time 1 hour away from each other # populate the hours array with time 1 hour away from each other
startTime = timeCutoff startTime = timeCutoff
while startTime < timeNow: while startTime < timeNow:
chatData['hours'].append(startTime) chatData["hours"].append(startTime)
startTime += oneHour startTime += oneHour
# populate the regions array with blank data for each region # populate the regions array with blank data for each region
for region in getAllRegions(): for region in getAllRegions():
chatData['regions'][region] = { 'name': region, 'values': [0] * len(chatData['hours']) } chatData["regions"][region] = {
"name": region,
"values": [0] * len(chatData["hours"]),
}
with open(logfile, "r") as log: with open(logfile, "r") as log:
hourIdx = 0 # starting with the oldest time slot, we will count instances of user chatting hourIdx = (
0
) # starting with the oldest time slot, we will count instances of user chatting
for line in log: for line in log:
try: try:
time, user, message = line.split("\t", 3) time, user, message = line.split("\t", 3)
time = int(time) time = int(time)
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse continue # There are some bad lines in the log file that we'll ignore if we can't parse
if time > timeCutoff: if time > timeCutoff:
region = getRegion(user) region = getRegion(user)
while time > chatData['hours'][hourIdx] + oneHour: # we are past the current hour idx, move ahead until we find the right idx while (
hourIdx += 1; time > chatData["hours"][hourIdx] + oneHour
if hourIdx >= len(chatData['hours']): ): # we are past the current hour idx, move ahead until we find the right idx
break; #uh oh! somehow we are parsing a line from the future! we're in pretty bad shape! hourIdx += 1
if hourIdx >= len(chatData["hours"]):
break
# uh oh! somehow we are parsing a line from the future! we're in pretty bad shape!
# hourIdx should now be a good value # hourIdx should now be a good value
chatData['regions'][region]['values'][hourIdx] += 1 # increment the user region's count for the current hour chatData["regions"][region]["values"][
hourIdx
] += 1 # increment the user region's count for the current hour
with open(outfile + ".tmp", "w") as tmpFile: with open(outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(chatData)) tmpFile.write(json.dumps(chatData))
+61 -56
View File
@@ -7,25 +7,26 @@ import shutil
import re import re
logfile = "/home/archangelic/irc/log" logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log" # logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/chatStats.json" outfile = "/home/krowbar/logs/chatStats.json"
userData = {} #hash keyed by "user" that contains a start timestamp, last timestamp, last said string, chat count, letter count, and word count # hash keyed by "user" that contains a start timestamp, last timestamp, last said string, chat count, letter count, and word count
#also now happy emotes and sad emotes userData = {}
# also now happy emotes and sad emotes
rejectRegexp = "http[s]?://|[0-9]{2}[;:][0-9]{2}" rejectRegexp = "http[s]?://|[0-9]{2}[;:][0-9]{2}"
happyRegexp = ":[-]?[])}]" happyRegexp = ":[-]?[])}]"
sadRegexp = ":[-]?[[({]" sadRegexp = ":[-]?[[({]"
nameFix = { nameFix = {
'archangel': 'archangelic', "archangel": "archangelic",
'jumblesal': 'jumblesale', "jumblesal": "jumblesale",
'hardmath1': 'kc', "hardmath1": "kc",
'hardmath123': 'kc', "hardmath123": "kc",
'bendorphan': 'endorphant', "bendorphan": "endorphant",
'endorphan': 'endorphant', "endorphan": "endorphant",
'synergian': 'synergiance' "synergian": "synergiance",
} }
with open(logfile, "r") as log: with open(logfile, "r") as log:
lastUser = ""; lastUser = ""
currentStreak = 1 currentStreak = 1
for line in log: for line in log:
try: try:
@@ -36,66 +37,70 @@ with open(logfile, "r") as log:
else: else:
user = user.lower() user = user.lower()
except ValueError: except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse continue # There are some bad lines in the log file that we'll ignore if we can't parse
if user in userData: if user in userData:
day = time / 86400 #seconds in a day day = time / 86400 # seconds in a day
if userData[user]['startTime'] == 0: if userData[user]["startTime"] == 0:
userData[user]['startTime'] = time userData[user]["startTime"] = time
if userData[user]['lastDay'] != day: if userData[user]["lastDay"] != day:
userData[user]['daysActive'] += 1 userData[user]["daysActive"] += 1
userData[user]['lastDay'] = day userData[user]["lastDay"] = day
if lastUser == user: if lastUser == user:
currentStreak += 1 currentStreak += 1
if currentStreak > userData[user]['streak']: if currentStreak > userData[user]["streak"]:
userData[user]['streak'] = currentStreak userData[user]["streak"] = currentStreak
else: else:
currentStreak = 1 currentStreak = 1
if userData[user]['lastMention']: if userData[user]["lastMention"]:
resTime = time - userData[user]['lastMention'] resTime = time - userData[user]["lastMention"]
userData[user]['responseTime'] += min(resTime, 7200) #cap the value at 2hrs, things get skewed toward the high end otherwise userData[user]["responseTime"] += min(
userData[user]['lastMention'] = 0 resTime, 7200
) # cap the value at 2hrs, things get skewed toward the high end otherwise
userData[user]["lastMention"] = 0
userData[user]['endTime'] = time userData[user]["endTime"] = time
#userData[user]['lastSaid'] = message # userData[user]['lastSaid'] = message
userData[user]['lineCount'] += 1 userData[user]["lineCount"] += 1
userData[user]['wordCount'] += len(message.split()) userData[user]["wordCount"] += len(message.split())
userData[user]['charCount'] += len(message) userData[user]["charCount"] += len(message)
else: #if they are new else: # if they are new
userData[user] = {} userData[user] = {}
userData[user]['startTime'] = time userData[user]["startTime"] = time
userData[user]['endTime'] = time userData[user]["endTime"] = time
#userData[user]['lastSaid'] = message # userData[user]['lastSaid'] = message
userData[user]['lineCount'] = 1 userData[user]["lineCount"] = 1
userData[user]['wordCount'] = len(message.split()) userData[user]["wordCount"] = len(message.split())
userData[user]['charCount'] = len(message) userData[user]["charCount"] = len(message)
userData[user]['daysActive'] = 1 userData[user]["daysActive"] = 1
userData[user]['lastDay'] = time / 86400 userData[user]["lastDay"] = time / 86400
userData[user]['streak'] = 1 userData[user]["streak"] = 1
userData[user]['mentions'] = 0 userData[user]["mentions"] = 0
userData[user]['lastMention'] = 0 userData[user]["lastMention"] = 0
userData[user]['responseTime'] = 0 userData[user]["responseTime"] = 0
userData[user]['botUse'] = 0 userData[user]["botUse"] = 0
userData[user]['happyEmotes'] = 0 userData[user]["happyEmotes"] = 0
userData[user]['sadEmotes'] = 0 userData[user]["sadEmotes"] = 0
lastUser = user; lastUser = user
if message.rstrip() and message[0] == '!': if message.rstrip() and message[0] == "!":
userData[user]['botUse'] += 1 userData[user]["botUse"] += 1
if not re.search(rejectRegexp, message): if not re.search(rejectRegexp, message):
if re.search(happyRegexp, message): if re.search(happyRegexp, message):
userData[user]['happyEmotes'] += 1 userData[user]["happyEmotes"] += 1
if re.search(sadRegexp, message): if re.search(sadRegexp, message):
userData[user]['sadEmotes'] += 1 userData[user]["sadEmotes"] += 1
try: try:
if message.rstrip() and message.split()[0][-1] == ':': #last character of first word if (
message.rstrip() and message.split()[0][-1] == ":"
): # last character of first word
name = message.split()[0][0:-1] name = message.split()[0][0:-1]
if user != name and userData.has_key(name): if user != name and userData.has_key(name):
userData[name]['mentions'] += 1 userData[name]["mentions"] += 1
if not userData[name]['lastMention']: if not userData[name]["lastMention"]:
userData[name]['lastMention'] = time userData[name]["lastMention"] = time
except IndexError: except IndexError:
print '##' + message + '##' print("##" + message + "##")
continue continue
+2
View File
@@ -1,4 +1,6 @@
import urllib import urllib
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
def get_track(): def get_track():
pass
+35 -16
View File
@@ -4,26 +4,45 @@ import random
import sys import sys
import argparse import argparse
parser = argparse.ArgumentParser(description='Print some random dictionary words.') parser = argparse.ArgumentParser(description="Print some random dictionary words.")
parser.add_argument('-d', dest='dictionary', metavar='DICT', parser.add_argument(
help='supply a dictionary', default='/usr/share/dict/american-english-large') "-d",
parser.add_argument('-c', dest='count', type=int, dest="dictionary",
help='specify how many words you want per line', default=10) metavar="DICT",
parser.add_argument('-l', dest='lines', type=int, help="supply a dictionary",
help='specify how many lines of random words you want', default=1) default="/usr/share/dict/american-english-large",
parser.add_argument('--no-appos', action='store_true', )
help='remove words with appostrophes') parser.add_argument(
parser.add_argument('--no-proper', action='store_true', "-c",
help='remove words that start with a capital letter') dest="count",
type=int,
help="specify how many words you want per line",
default=10,
)
parser.add_argument(
"-l",
dest="lines",
type=int,
help="specify how many lines of random words you want",
default=1,
)
parser.add_argument(
"--no-appos", action="store_true", help="remove words with appostrophes"
)
parser.add_argument(
"--no-proper",
action="store_true",
help="remove words that start with a capital letter",
)
args = parser.parse_args() args = parser.parse_args()
#print args # print args
with open(args.dictionary, "r") as wordsfile: with open(args.dictionary, "r") as wordsfile:
words = wordsfile.readlines() words = wordsfile.readlines()
if(args.no_appos): if args.no_appos:
words[:] = [word for word in words if word.find('\'') == -1] words[:] = [word for word in words if word.find("'") == -1]
if(args.no_proper): if args.no_proper:
words[:] = [word for word in words if not word[0].isupper()] words[:] = [word for word in words if not word[0].isupper()]
for _ in range(0, args.lines): for _ in range(0, args.lines):
print ' '.join([w.strip("\n") for w in random.sample(words, args.count)]) print(" ".join([w.strip("\n") for w in random.sample(words, args.count)]))