This commit is contained in:
Ben Harris 2018-10-05 16:02:38 -04:00
parent a8a5de36f2
commit 58753c7234
Signed by untrusted user: ben
GPG Key ID: 4E0AF802FFF7960C
38 changed files with 4549 additions and 2523 deletions

View File

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

View File

@ -33,28 +33,51 @@ from whosaid import whoSaid
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='tildebot',
help="the nick to use", metavar="NICK")
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="tildebot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args()
p = inflect.engine()
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
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")
ircsock.send("JOIN " + chan + "\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
ircsock.send("PRIVMSG " + channel + " :Hello!\n")
def score_banter(channel, user, messageText):
score = 5
@ -64,285 +87,421 @@ def score_banter(channel, user, messageText):
for word in words:
for bant in bantz:
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 += messageText.count('!') * 2 #hype is banter
score -= messageText.count('!!!') * 6 #too much hype is not banter
score += messageText.count('#') * 3 #hashs are mad bantz
score -= messageText.count('##') * 6 #but too many is garbage
score += messageText.count("!") * 2 # hype is banter
score -= messageText.count("!!!") * 6 # too much hype is not banter
score += messageText.count("#") * 3 # hashs are mad bantz
score -= messageText.count("##") * 6 # but too many is garbage
names = ['mate', 'lad', 'my best boy']
compliment = ['top-drawer', 'top-shelf', 'bangin\'', 'legendary', 'smashing', 'incredible', 'impeccable', 'stunning']
names = ["mate", "lad", "my best boy"]
compliment = [
"top-drawer",
"top-shelf",
"bangin'",
"legendary",
"smashing",
"incredible",
"impeccable",
"stunning",
]
msg = ""
if score > 100:
msg = "Truely " + random.choice(compliment).capitalize() + ", " + random.choice(names) \
+ "! That was some #banter! You earned a " + str(score) + " for that!"
msg = (
"Truely "
+ random.choice(compliment).capitalize()
+ ", "
+ random.choice(names)
+ "! That was some #banter! You earned a "
+ str(score)
+ " for that!"
)
elif score > 50:
msg = random.choice(compliment).capitalize() + " #banter! You get a " + str(score) + " from me!"
msg = (
random.choice(compliment).capitalize()
+ " #banter! You get a "
+ str(score)
+ " from me!"
)
elif score > 10:
msg = random.choice(["acceptible", "reasonable", "passable"]).capitalize() + " #banter. You get a " + str(score)
msg = (
random.choice(["acceptible", "reasonable", "passable"]).capitalize()
+ " #banter. You get a "
+ str(score)
)
else:
msg = "That " + random.choice(["was hardly", "was barely", "wasn't", "won't pass for", "was awful"]) \
+ " #banter" + random.choice([", lad",", lah",", boy","",""]) + ". I'll give you a " + str(score) + ". Maybe try again?"
msg = (
"That "
+ random.choice(
["was hardly", "was barely", "wasn't", "won't pass for", "was awful"]
)
+ " #banter"
+ random.choice([", lad", ", lah", ", boy", "", ""])
+ ". I'll give you a "
+ str(score)
+ ". Maybe try again?"
)
ircsock.send("PRIVMSG " + channel + " :" + msg + "\n")
def get_new_banter(channel, user):
with open("/usr/share/dict/words", "r") as dict:
words = filter(lambda word:re.search(r"^[^']*$", word), dict.readlines())
if(random.randint(0,1)): #look for *ant words
words = filter(lambda word:re.search(r"ant", word), words)
words = filter(lambda word: re.search(r"^[^']*$", word), dict.readlines())
if random.randint(0, 1): # look for *ant words
words = filter(lambda word: re.search(r"ant", word), words)
random.shuffle(words)
word = words[0].strip("\n")
start = word.find('ant')
if(start == 0):
word = 'b' + word
start = word.find("ant")
if start == 0:
word = "b" + word
else:
if('aeiou'.find(word[start]) > -1): #just append a 'b'
word = word[:start] + 'b' + word[start:]
else: #replace the letter with 'b'
word = word[:start-1] + 'b' + word[start:]
else: #look for ban* words
words = filter(lambda word:re.search(r"ban", word), words)
if "aeiou".find(word[start]) > -1: # just append a 'b'
word = word[:start] + "b" + word[start:]
else: # replace the letter with 'b'
word = word[: start - 1] + "b" + word[start:]
else: # look for ban* words
words = filter(lambda word: re.search(r"ban", word), words)
random.shuffle(words)
word = words[0].strip("\n")
end = word.find('ban') + 3
if(end == len(word)):
word = word + 't'
end = word.find("ban") + 3
if end == len(word):
word = word + "t"
else:
if('aeiou'.find(word[end]) > -1): #just append 't'
word = word[:end] + 't' + word[end:]
else: #replace the letter with 'b'
word = word[:end] + 't' + word[end+1:]
ircsock.send("PRIVMSG " + channel + " :" + user + ": Here, why don't you try '" + word + "'?\n")
if "aeiou".find(word[end]) > -1: # just append 't'
word = word[:end] + "t" + word[end:]
else: # replace the letter with 'b'
word = word[:end] + "t" + word[end + 1 :]
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": Here, why don't you try '"
+ word
+ "'?\n"
)
def get_rhymes(channel, user, text):
word = ""
if(len(text.split(' ')) > 1):
word = text.split(' ')[1]
if len(text.split(" ")) > 1:
word = text.split(" ")[1]
else:
with open("/home/nossidge/poems/words_poetic.txt", "r") as words:
word = random.choice(words.readlines()).strip("\n")
rhymes = rhymeZone(word)
if(len(rhymes) == 0):
ircsock.send("PRIVMSG " + channel + " :" + user + ": Couldn't find anything that rhymes with '" + word + "' :(\n")
if len(rhymes) == 0:
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": Couldn't find anything that rhymes with '"
+ word
+ "' :(\n"
)
else:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Here, these words rhyme with '" + word + "': " + ', '.join(rhymes) + "\n")
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": Here, these words rhyme with '"
+ word
+ "': "
+ ", ".join(rhymes)
+ "\n"
)
def define_word(channel, user, text):
word = ""
defs = []
if(len(text.split(' ')) > 1):
word = text.split(' ')[1]
if len(text.split(" ")) > 1:
word = text.split(" ")[1]
defs = defWord(word)
if(len(defs) == 0):
ircsock.send("PRIVMSG " + channel + " :" + user + ": Couldn't find the definition of '" + word + "' :(\n")
elif(isinstance(defs, list)):
if len(defs) == 0:
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": Couldn't find the definition of '"
+ word
+ "' :(\n"
)
elif isinstance(defs, list):
for entry in defs:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Define '" + word + "'" + entry[0:400] + "\n")
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": Define '"
+ word
+ "'"
+ entry[0:400]
+ "\n"
)
else:
ircsock.send("PRIVMSG " + channel + " :" + user + ": Define '" + word + "'" + defs[0:400] + "\n")
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": Define '"
+ word
+ "'"
+ defs[0:400]
+ "\n"
)
def make_rainbow(channel, user, text):
rbword = makeRainbow(text[9:])
ircsock.send("PRIVMSG " + channel + " :" + rbword + "\n")
def get_welch(channel):
ircsock.send("PRIVMSG " + channel + " :" + welch.get_thing()[0:400] + "\n")
def get_evil(channel):
evilThing = evil.get_thing()
for line in [evilThing[i:i+400] for i in range(0, len(evilThing), 400)]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
for line in [evilThing[i : i + 400] for i in range(0, len(evilThing), 400)]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
def get_tumble(url, channel):
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")
def get_xkcd(channel, text):
links = xkcdApropos.xkcd(text[6:])
joined_links = ', '.join(links)
for line in [joined_links[i:i+400] for i in range(0, len(joined_links), 400)]:
joined_links = ", ".join(links)
for line in [joined_links[i : i + 400] for i in range(0, len(joined_links), 400)]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
#res = xkcdApropos.xkcd(text[6:])
#ircsock.send("PRIVMSG " + channel + " :" + res + "\n")
# res = xkcdApropos.xkcd(text[6:])
# ircsock.send("PRIVMSG " + channel + " :" + res + "\n")
def get_wphilosophy(channel, text):
steps = wikiphilosophy.get_philosophy_lower(text[17:])
if not steps:
ircsock.send("PRIVMSG " + channel + " :Couldn't find a wikipedia entry for " + text + "\n")
else:
joined_steps = ' > '.join(steps)
if steps[-1] == 'Philosophy':
joined_steps += "!!!"
for line in [joined_steps[i:i+400] for i in range(0, len(joined_steps), 400)]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
steps = wikiphilosophy.get_philosophy_lower(text[17:])
if not steps:
ircsock.send(
"PRIVMSG "
+ channel
+ " :Couldn't find a wikipedia entry for "
+ text
+ "\n"
)
else:
joined_steps = " > ".join(steps)
if steps[-1] == "Philosophy":
joined_steps += "!!!"
for line in [
joined_steps[i : i + 400] for i in range(0, len(joined_steps), 400)
]:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
def figlet(channel, text):
if not text:
ircsock.send("PRIVMSG " + channel + " :No text given. :(\n")
else:
lines = subprocess.Popen(["figlet", "-w140"] + text.split(' '), shell=False, stdout=subprocess.PIPE).stdout.read()
for line in lines.split('\n'):
lines = subprocess.Popen(
["figlet", "-w140"] + text.split(" "), shell=False, stdout=subprocess.PIPE
).stdout.read()
for line in lines.split("\n"):
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
time.sleep(0.4) #to avoid channel throttle due to spamming
time.sleep(0.4) # to avoid channel throttle due to spamming
def toilet(channel, text):
if not text:
ircsock.send("PRIVMSG " + channel + " :No text given. :(\n")
else:
lines = subprocess.Popen(["toilet", "-w140", "--irc"] + text.split(' '), shell=False, stdout=subprocess.PIPE).stdout.read()
for line in lines.split('\n'):
lines = subprocess.Popen(
["toilet", "-w140", "--irc"] + text.split(" "),
shell=False,
stdout=subprocess.PIPE,
).stdout.read()
for line in lines.split("\n"):
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
time.sleep(0.4) #to avoid channel throttle due to spamming
time.sleep(0.4) # to avoid channel throttle due to spamming
def get_acronym(channel, text):
if not text:
ircsock.send("PRIVMSG " + channel + " :No text given :(\n")
else:
defs = acronymFinder.get_acros(text, True, True)
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")
if len(defs) > 5:
ircsock.send("PRIVMSG " + channel + " :" + defs[-1] + "\n")
if not text:
ircsock.send("PRIVMSG " + channel + " :No text given :(\n")
else:
defs = acronymFinder.get_acros(text, True, True)
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")
if len(defs) > 5:
ircsock.send("PRIVMSG " + channel + " :" + defs[-1] + "\n")
def get_whosaid(channel, text):
if not text:
ircsock.send("PRIVMSG " + channel + " :No text given :(\n")
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)
if not text:
ircsock.send("PRIVMSG " + channel + " :No text given :(\n")
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])
ircsock.send("PRIVMSG " + channel + " :" + msg + ".\n")
result = whoSaid(text)
date = datetime.date.fromtimestamp(result["timecutoff"])
dateStr = date.strftime("%B %d")
if not result["data"]:
msg = "Nobody said '%s' since %s" % (text, dateStr)
else:
msg = "Since %s, %s said '%s' %d times" % (
dateStr,
result["data"][0][0],
text,
result["data"][0][1],
)
if len(result["data"]) > 1:
msg += " and %s said it %d times" % (
result["data"][1][0],
result["data"][1][1],
)
ircsock.send("PRIVMSG " + channel + " :" + msg + ".\n")
def get_notice(user, channel):
ircsock.send("CNOTICE " + user + " " + channel + " :Notice me sempai!\n")
def get_water(user, channel, msg, botnick):
if msg.find(botnick) == 0:
ircsock.send("PRIVMSG " + channel + " :Fight me, " + user + "!\n")
def mug_off(channel):
ircsock.send("PRIVMSG " + channel + " :u want some of this, m8?\n")
def rollcall(channel):
ircsock.send("PRIVMSG "+ channel +" :U wot m8? I score all the top drawer #banter and #bantz on this channel! \
ircsock.send(
"PRIVMSG "
+ channel
+ " :U wot m8? I score all the top drawer #banter and #bantz on this channel! \
Find new top-shelf banter with !newbanter, !rhymes, and !define. \
Look up things with !acronym and !whosaid. \
Make your chatter #legend with !rainbow, !toilet, and !figlet. \
Find interesting things with !xkcd and !wiki-philosophy. \
Get jokes with !welch and !evil\n")
Get jokes with !welch and !evil\n"
)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :krowbar\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
ircsock.connect((server, 6667))
ircsock.send(
"USER " + botnick + " " + botnick + " " + botnick + " :krowbar\n"
) # user authentication
ircsock.send("NICK " + botnick + "\n")
joinchan(channel)
joinchan("#bots")
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 ""
try:
i1 = msg.index(":") + 1
i2 = msg.index("!")
return msg[i1:i2]
except ValueError:
return ""
def listen(botnick):
while 1:
while 1:
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r')
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
formatted = util.format_message(ircmsg)
formatted = util.format_message(ircmsg)
if "" == formatted:
continue
if "" == formatted:
continue
# print formatted
# print formatted
split = formatted.split("\t")
#time = split[0]
user = split[1]
command = split[2]
channel = split[3]
messageText = split[4]
split = 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:
score_banter(channel, user, messageText)
if ircmsg.find("#banter") != -1 or ircmsg.find("#bantz") != -1:
score_banter(channel, user, messageText)
if ircmsg.find(":!newbanter") != -1:
get_new_banter(channel, user)
if ircmsg.find(":!newbanter") != -1:
get_new_banter(channel, user)
if ircmsg.find(":!rhymes") != -1:
get_rhymes(channel, user, messageText)
if ircmsg.find(":!rhymes") != -1:
get_rhymes(channel, user, messageText)
if ircmsg.find(":!define") != -1:
define_word(channel, user, messageText)
if ircmsg.find(":!define") != -1:
define_word(channel, user, messageText)
if ircmsg.find(":!rainbow") != -1:
make_rainbow(channel, user, messageText)
if ircmsg.find(":!rainbow") != -1:
make_rainbow(channel, user, messageText)
if ircmsg.find(":!welch") != -1:
get_welch(channel)
if ircmsg.find(":!welch") != -1:
get_welch(channel)
if ircmsg.find(":!evil") != -1:
get_evil(channel)
if ircmsg.find(":!evil") != -1:
get_evil(channel)
if ircmsg.find(":!kjp") != -1:
get_tumble('http://kingjamesprogramming.tumblr.com', channel)
if ircmsg.find(":!kjp") != -1:
get_tumble("http://kingjamesprogramming.tumblr.com", channel)
if ircmsg.find(":!help") != -1:
get_tumble('http://thedoomthatcametopuppet.tumblr.com', channel)
if ircmsg.find(":!help") != -1:
get_tumble("http://thedoomthatcametopuppet.tumblr.com", channel)
if ircmsg.find(":!xkcd") != -1:
get_xkcd(channel, messageText)
if ircmsg.find(":!wiki-philosophy") != -1:
get_wphilosophy(channel, messageText);
if ircmsg.find(":!xkcd") != -1:
get_xkcd(channel, messageText)
if ircmsg.find(":!wiki-philosophy") != -1:
get_wphilosophy(channel, messageText)
if ircmsg.find(":!figlet") != -1:
figlet(channel, messageText[8:])
if ircmsg.find(":!figlet") != -1:
figlet(channel, messageText[8:])
if ircmsg.find(":!toilet") != -1:
toilet(channel, messageText[8:])
if ircmsg.find(":!toilet") != -1:
toilet(channel, messageText[8:])
if ircmsg.find(":!acronym") != -1:
get_acronym(channel, messageText[9:])
if ircmsg.find(":!acronym") != -1:
get_acronym(channel, messageText[9:])
if ircmsg.find(":!whosaid") != -1:
get_whosaid(channel, messageText[9:])
if ircmsg.find(":!whosaid") != -1:
get_whosaid(channel, messageText[9:])
if ircmsg.find(":!notice") != -1:
get_notice(user, channel)
if ircmsg.find(":!notice") != -1:
get_notice(user, channel)
if ircmsg.find(":!water") != -1:
get_water(user, channel, messageText[7:], botnick)
if ircmsg.find(":!water") != -1:
get_water(user, channel, messageText[7:], botnick)
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
if ircmsg.find(":" + botnick + ":") != -1:
mug_off(channel)
if ircmsg.find(":" + botnick + ":") != -1:
mug_off(channel)
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
sys.stdout.flush()
time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)

View File

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

View File

@ -6,6 +6,7 @@ p = inflect.engine()
dictionary = "/usr/share/dict/american-english-small"
BAD_WORDS_FILE = "badwords.txt"
def get_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
with open(BAD_WORDS_FILE, "r") as fp:
@ -15,20 +16,29 @@ def get_wordlist():
if "'" not in word and word not in bad_words:
yield word.rstrip()
def get_puzzle():
dict_words = list(get_wordlist())
words = random.sample(dict_words, 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)
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)
)
words.sort()
answer = words[key]
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 get_wordlist() if len(word) > 2 and len(word) <= maxlen + 1
]
word = random.choice(dict_words)
while True:
anagram = ''.join(random.sample(word, len(word)))
anagram = "".join(random.sample(word, len(word)))
if anagram != word:
break
puzzle = "Unscramble the following word: '" + anagram + "'"
@ -43,4 +53,5 @@ def get_anagram(maxlen = 6):
return False
# Ok, gotta actually check if it's a word now
return any(guess == item for item in get_wordlist())
return [answer_checker, puzzle]

View File

@ -6,7 +6,14 @@ import sys
__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.
@ -28,22 +35,22 @@ def query(query, useragent='python-duckduckgo '+str(__version__), safesearch=Tru
Any other keyword arguments are passed directly to DuckDuckGo as URL params.
""" % __version__
safesearch = '1' if safesearch else '-1'
html = '0' if html else '1'
meanings = '0' if meanings else '1'
safesearch = "1" if safesearch else "-1"
html = "0" if html else "1"
meanings = "0" if meanings else "1"
params = {
'q': query,
'o': 'json',
'kp': safesearch,
'no_redirect': '1',
'no_html': html,
'd': meanings,
}
"q": query,
"o": "json",
"kp": safesearch,
"no_redirect": "1",
"no_html": html,
"d": meanings,
}
params.update(kwargs)
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 = urllib2.Request(url, headers={"User-Agent": useragent})
response = urllib2.urlopen(request)
json = j.loads(response.read())
response.close()
@ -52,54 +59,56 @@ def query(query, useragent='python-duckduckgo '+str(__version__), safesearch=Tru
class Results(object):
def __init__(self, json):
self.type = {'A': 'answer', 'D': 'disambiguation',
'C': 'category', 'N': 'name',
'E': 'exclusive', '': 'nothing'}.get(json.get('Type',''), '')
self.type = {
"A": "answer",
"D": "disambiguation",
"C": "category",
"N": "name",
"E": "exclusive",
"": "nothing",
}.get(json.get("Type", ""), "")
self.json = json
self.api_version = None # compat
self.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.related = [Result(elem) for elem in
json.get('RelatedTopics',[])]
self.results = [Result(elem) for elem in json.get("Results", [])]
self.related = [Result(elem) for elem in json.get("RelatedTopics", [])]
self.abstract = Abstract(json)
self.redirect = Redirect(json)
self.definition = Definition(json)
self.answer = Answer(json)
self.image = Image({'Result':json.get('Image','')})
self.image = Image({"Result": json.get("Image", "")})
class Abstract(object):
def __init__(self, json):
self.html = json.get('Abstract', '')
self.text = json.get('AbstractText', '')
self.url = json.get('AbstractURL', '')
self.source = json.get('AbstractSource')
self.html = json.get("Abstract", "")
self.text = json.get("AbstractText", "")
self.url = json.get("AbstractURL", "")
self.source = json.get("AbstractSource")
class Redirect(object):
def __init__(self, json):
self.url = json.get('Redirect', '')
self.url = json.get("Redirect", "")
class Result(object):
def __init__(self, json):
self.topics = json.get('Topics', [])
self.topics = json.get("Topics", [])
if self.topics:
self.topics = [Result(t) for t in self.topics]
return
self.html = json.get('Result')
self.text = json.get('Text')
self.url = json.get('FirstURL')
self.html = json.get("Result")
self.text = json.get("Text")
self.url = json.get("FirstURL")
icon_json = json.get('Icon')
icon_json = json.get("Icon")
if icon_json is not None:
self.icon = Image(icon_json)
else:
@ -107,51 +116,61 @@ class Result(object):
class Image(object):
def __init__(self, json):
self.url = json.get('Result')
self.height = json.get('Height', None)
self.width = json.get('Width', None)
self.url = json.get("Result")
self.height = json.get("Height", None)
self.width = json.get("Width", None)
class Answer(object):
def __init__(self, json):
self.text = json.get('Answer')
self.type = json.get('AnswerType', '')
self.text = json.get("Answer")
self.type = json.get("AnswerType", "")
class Definition(object):
def __init__(self, json):
self.text = json.get('Definition','')
self.url = json.get('DefinitionURL')
self.source = json.get('DefinitionSource')
self.text = json.get("Definition", "")
self.url = json.get("DefinitionURL")
self.source = json.get("DefinitionSource")
def get_zci(q, web_fallback=True, priority=['answer', 'abstract', 'related.0', 'definition'], urls=True, **kwargs):
'''A helper method to get a single (and hopefully the best) ZCI result.
def get_zci(
q,
web_fallback=True,
priority=["answer", "abstract", "related.0", "definition"],
urls=True,
**kwargs
):
"""A helper method to get a single (and hopefully the best) ZCI result.
priority=list can be used to set the order in which fields will be checked for answers.
Use web_fallback=True to fall back to grabbing the first web result.
passed to query. This method will fall back to 'Sorry, no results.'
if it cannot find anything.'''
if it cannot find anything."""
ddg = query('\\'+q, **kwargs)
response = ''
ddg = query("\\" + q, **kwargs)
response = ""
for p in priority:
ps = p.split('.')
ps = p.split(".")
type = ps[0]
index = int(ps[1]) if len(ps) > 1 else None
result = getattr(ddg, type)
if index is not None:
if not hasattr(result, '__getitem__'): raise TypeError('%s field is not indexable' % type)
if index is not None:
if not hasattr(result, "__getitem__"):
raise TypeError("%s field is not indexable" % type)
result = result[index] if len(result) > index else None
if not result: continue
if not result:
continue
if result.text: response = result.text
if result.text and hasattr(result,'url') and urls:
if result.url: response += ' (%s)' % result.url
if response: break
if result.text:
response = result.text
if result.text and hasattr(result, "url") and urls:
if result.url:
response += " (%s)" % result.url
if response:
break
# if there still isn't anything, try to get the first web result
if not response and web_fallback:
@ -159,21 +178,24 @@ def get_zci(q, web_fallback=True, priority=['answer', 'abstract', 'related.0', '
response = ddg.redirect.url
# final fallback
if not response:
response = 'Sorry, no results.'
if not response:
response = "Sorry, no results."
return response
def main():
if len(sys.argv) > 1:
q = query(' '.join(sys.argv[1:]))
q = query(" ".join(sys.argv[1:]))
keys = q.json.keys()
keys.sort()
for key in keys:
sys.stdout.write(key)
if type(q.json[key]) in [str,unicode]: print(':', q.json[key])
else:
sys.stdout.write('\n')
for i in q.json[key]: print('\t',i)
if type(q.json[key]) in [str, unicode]:
print(":", q.json[key])
else:
sys.stdout.write("\n")
for i in q.json[key]:
print("\t", i)
else:
print('Usage: %s [query]' % sys.argv[0])
print("Usage: %s [query]" % sys.argv[0])

View File

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

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)

View File

@ -1,5 +1,6 @@
# Return a list of users on this system
def get_users():
# thanks, ~dan!
users = []
@ -8,5 +9,5 @@ def get_users():
if "/bin/bash" in line:
u = line.split(":")[0] # Grab all text before first ':'
users.append(u)
return users
return users

File diff suppressed because it is too large Load Diff

View File

@ -19,25 +19,25 @@ def int2word(n):
if q < -2:
break
else:
if q >= 0:
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
# 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
b2 = (x % 100) // 10
b3 = (x % 1000) // 100
# print b1, b2, b3 # test
if x == 0:
continue # skip
else:
@ -51,15 +51,65 @@ def int2word(n):
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 "]
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 ",
]

View File

@ -8,15 +8,20 @@ import re
p = inflect.engine()
file_pattern = "/home/*/madlibs/*.madlib"
file_regex = re.compile(r'^/home/(.*?)/.*/([^/]*)\.madlib$')
word_regex = re.compile(r'{{(.*?)(#.*?)?(\|.*)?}}')
word_replace_regex = re.compile(r'^(.*)#(\d*)$')
file_regex = re.compile(r"^/home/(.*?)/.*/([^/]*)\.madlib$")
word_regex = re.compile(r"{{(.*?)(#.*?)?(\|.*)?}}")
word_replace_regex = re.compile(r"^(.*)#(\d*)$")
# Take a file path and return a tuple with the title and original path
def munge_story(file_name):
match = re.match(file_regex, 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
def find_stories(limit=999, shuffle=False):
@ -27,25 +32,28 @@ def find_stories(limit=999, shuffle=False):
files = files[:limit]
return map(munge_story, files)
# Count the number of replacable words in the story
def count_words(story):
# words that have a '#' part and match should only be counted once
count = 0
repeats = []
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
elif match.group(1) + match.group(2) not in repeats:
count += 1
repeats.append(match.group(1) + match.group(2))
return count
# Count the number of replacable words in the story when given a file path
def count_words_file(storyPath):
with open(storyPath, "r") as storyFile:
story = storyFile.read()
return count_words(story)
# 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
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))
# Using a query phrase, replace a word and return the entire story body
def replace_word(story, query, word):
rquery = word_regex.search(query)
# '{{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)
story = story.replace(query, munged_word, 1)
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) + ".*?}}"
others = re.findall(r'{{' + rquery.group(1) + rquery.group(2) + '.*?}}', story)
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) + ".*?}}")
others = re.findall(r"{{" + rquery.group(1) + rquery.group(2) + ".*?}}", story)
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
@ -80,17 +96,18 @@ def process_pipes(word, pipes):
for pipe in pipes:
try:
word = {
'upper': lambda word: word.upper(),
'lower': lambda word: word.lower(),
'title': lambda word: word.title(),
'numeric': lambda word: p.number_to_words(word),
'ordinal': lambda word: p.ordinal(word),
collections.defaultdict: lambda word: word
}[pipe](word)
"upper": lambda word: word.upper(),
"lower": lambda word: word.lower(),
"title": lambda word: word.title(),
"numeric": lambda word: p.number_to_words(word),
"ordinal": lambda word: p.ordinal(word),
collections.defaultdict: lambda word: word,
}[pipe](word)
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
# A helper function that will split the story up into chat-printable lengths
def yield_lines(line, max_size):
words = []
@ -101,17 +118,18 @@ def yield_lines(line, max_size):
while len(word) > max_size:
splitsize = max_size - words_length - 1
words.append(word[:splitsize] + "-")
yield ' '.join(words)
yield " ".join(words)
words = []
words_length = 0
word = word[splitsize:]
if words_length + len(word) + 1 > max_size:
yield ' '.join(words)
yield " ".join(words)
words = []
words_length = 0
words.append(word)
words_length += len(word) + 1 # For the space
yield ' '.join(words) # For any words left over
words_length += len(word) + 1 # For the space
yield " ".join(words) # For any words left over
# Open a story file and ask for the parts
def make_story(storyFile):
@ -119,23 +137,24 @@ def make_story(storyFile):
story = storyFile.read()
match = word_regex.search(story)
while match is not None:
word = raw_input('Give me {}: '.format(match.group(1)))
print "Replacing '{}' with '{}'".format(match.group(0), word)
print story
word = raw_input("Give me {}: ".format(match.group(1)))
print("Replacing '{}' with '{}'".format(match.group(0), word))
print(story)
story = re.sub(match.group(0), word, story, 1)
match = word_regex.search(story)
print story
print(story)
def start():
stories = find_stories(20, True)
if len(stories) == 0:
print "Sorry, no stories found. :/"
print("Sorry, no stories found. :/")
return
input = -1
while input < 0 or input >= len(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?: ")
try:
# 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
make_story(stories[input][1])
if __name__ == "__main__":
start()

View File

@ -15,33 +15,56 @@ import operator
from .. import util
import madlib
class State:
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
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
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
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
MAX_LINE = 80 # The maximum number of characters in a line
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
MAX_LINE = 80 # The maximum number of characters in a line
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
# Allow madlbibbot to run multiple simultaneous stories
state = {} # The current state of the bot
stories = {} # The list of stories available to users
story = {} # The madlib story currently being worked on
nextword = {} # The word that the bot is currently expecting data for
state = {} # The current state of the bot
stories = {} # The list of stories available to users
story = {} # The madlib story currently being worked on
nextword = {} # The word that the bot is currently expecting data for
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='#madlibs',
help="the channel to join", metavar="CHANNEL")
parser.add_option("-n", "--nick", dest="nick", default='madlibbot',
help="the nick to use", metavar="NICK")
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="#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()
def resetGlobals(channel=""):
global state
global stories
@ -59,6 +82,7 @@ def resetGlobals(channel=""):
story[channel] = ""
nextword[channel] = {}
def get_stories(channel, botnick):
global state
global stories
@ -73,9 +97,13 @@ def get_stories(channel, botnick):
for idx, story in enumerate(stories[channel]):
sendmsg(channel, "[{}] {} ({} words)".format(idx, story[0], story[2]))
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
# Handle user input when the bot is directly addressed
def handle_bot_msg(channel, msg, botnick):
global state
@ -100,11 +128,13 @@ def handle_bot_msg(channel, msg, botnick):
else:
state[channel] = State.idle
# Handle how to quit the game
def quit_game(channel):
resetGlobals(channel)
sendmsg(channel, "Ok, quitting the current game.")
# Handle user input when we are in story selection mode
def handle_story_selection(channel, msg, botnick):
global stories
@ -115,16 +145,19 @@ def handle_story_selection(channel, msg, botnick):
sendmsg(channel, "Selection out of bounds. Try again!")
return
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:
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)
except ValueError:
sendmsg(channel, "Invalid selection. Try again!")
state[channel] = State.story_selection
# Handle when a story is being started
def story_start(channel, botnick):
global story
@ -132,12 +165,18 @@ def story_start(channel, botnick):
global nextword
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)
time.sleep(0.5 * THROTTLE_FACTOR)
sendmsg(channel, "Give me {}:".format(nextword[channel][1]))
state[channel] = State.word_input
# Handle user input when we have asked the user for input and are expecting a
# response
def handle_story_step(channel, msg):
@ -146,7 +185,7 @@ def handle_story_step(channel, msg):
global nextword
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:
story[channel] = madlib.replace_word(story[channel], nextword[channel][0], msg)
time.sleep(1 * THROTTLE_FACTOR)
@ -155,62 +194,86 @@ def handle_story_step(channel, msg):
if nextword[channel] is None:
finish_story(channel)
return
#else
# else
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
# Finish the story
def finish_story(channel):
global state
global story
sendmsg(channel, "Ok, here's the story...");
sendmsg(channel, '=' * MAX_LINE)
sendmsg(channel, "Ok, here's the story...")
sendmsg(channel, "=" * MAX_LINE)
for line in story[channel].splitlines():
for part in madlib.yield_lines(line, MAX_LINE):
time.sleep(0.6 * THROTTLE_FACTOR)
sendmsg(channel, part)
padlen = (MAX_LINE - 9)/2
padlen = (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] = ""
state[channel] = State.idle
# System things
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
def sendmsg(chan, msg):
ircsock.send("PRIVMSG {} :{}\n".format(chan, msg))
def joinchan(chan):
global state
state[chan] = State.idle
ircsock.send("JOIN {}\n".format(chan))
def rollcall(channel, botnick):
global state
if channel not in state:
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:
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(
"USER {} {} {} :krowbar\n".format(botnick, botnick, botnick)
) # user authentication
ircsock.send("NICK {}\n".format(botnick))
joinchan(channel)
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:
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r')
ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
@ -227,7 +290,10 @@ def listen(botnick):
channel = split[3]
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)
elif message.startswith(botnick) == True:
botmsg = botmsgre.match(message).group(1)
@ -236,6 +302,7 @@ def listen(botnick):
sys.stdout.flush()
time.sleep(1 * THROTTLE_FACTOR)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)
listen(options.nick)

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)

View File

@ -1,7 +1,8 @@
#!/usr/bin/python
import json
names_file='/home/jumblesale/Code/canonical_names/canonical_names.json'
names_file = "/home/jumblesale/Code/canonical_names/canonical_names.json"
def get_name(name):
try:
@ -12,4 +13,4 @@ def get_name(name):
except KeyError:
return name
except IOError:
return name # if we didn't already
return name # if we didn't already

View File

@ -1,42 +1,43 @@
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
from datetime import datetime
if day_diff < 0:
return ''
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:
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"
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"

View File

@ -8,85 +8,176 @@ p = inflect.engine()
primes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
fuzz_amount = 3
def make_puzzle(obfuscate=True):
answer = 0
bonus = 0
puzzle = random.choice(["Prove you're not a robot: ", "Are you a robot?: ", "Anti-bot check: ", "Counter-cnd0rphant measures: ", "Cosn0k countermeasures: ", "Anti-tilde7hief precautions: "])
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)
answer = 0
bonus = 0
puzzle = random.choice(
[
"Prove you're not a robot: ",
"Are you a robot?: ",
"Anti-bot check: ",
"Counter-cnd0rphant measures: ",
"Cosn0k countermeasures: ",
"Anti-tilde7hief precautions: ",
]
)
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:
answer = var1 + var2
puzzle += p.number_to_words(var1) + " " + random.choice(["and", "plus", "sum", "add"]) + " " + p.number_to_words(var2)
if roll == 0:
answer = var1 + var2
puzzle += (
p.number_to_words(var1)
+ " "
+ random.choice(["and", "plus", "sum", "add"])
+ " "
+ p.number_to_words(var2)
)
elif roll == 1:
answer = var1 * var2
puzzle += p.number_to_words(var1) + " " + random.choice(["times", "multiply", "multiplied by", "product"]) + " " + p.number_to_words(var2)
elif roll == 2:
if var2 > var1:
var1,var2 = var2,var1
answer = var1 - var2
puzzle += 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
elif roll == 1:
answer = var1 * var2
puzzle += (
p.number_to_words(var1)
+ " "
+ random.choice(["times", "multiply", "multiplied by", "product"])
+ " "
+ p.number_to_words(var2)
)
elif roll == 2:
if var2 > var1:
var1, var2 = var2, var1
answer = var1 - var2
puzzle += (
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)
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]
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 += "?"
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]

View File

@ -13,106 +13,149 @@ 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='#tildetown',
help="the channel to join", metavar="CHANNEL")
parser.add_option("-n", "--nick", dest="nick", default='quote_bot',
help="the nick to use", metavar="NICK")
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="#tildetown",
help="the channel to join",
metavar="CHANNEL",
)
parser.add_option(
"-n",
"--nick",
dest="nick",
default="quote_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 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")
ircsock.send("JOIN " + chan + "\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
ircsock.send("PRIVMSG " + channel + " :Hello!\n")
def random_quote(channel):
quote = os.popen("/home/frs/quotes/randquote.py").read()
if len(quote) >= 256:
quote = quote[:253] + '...'
ircsock.send("PRIVMSG "+ channel +" :" + quote + "\n")
quote = os.popen("/home/frs/quotes/randquote.py").read()
if len(quote) >= 256:
quote = quote[:253] + "..."
ircsock.send("PRIVMSG " + channel + " :" + quote + "\n")
def haiku(channel):
h = os.popen("haiku").read().replace("\n", " // ")
ircsock.send("PRIVMSG "+ channel +" :" + h + "\n")
h = os.popen("haiku").read().replace("\n", " // ")
ircsock.send("PRIVMSG " + channel + " :" + h + "\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")
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)
joinchan(channel)
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
try:
i1 = msg.index(":") + 1
i2 = msg.index("!")
return msg[i1:i2]
except ValueError:
return ""
def say_mentions(user, message):
nick = get_user_from_message(message)
menschns = os.popen("/home/karlen/bin/mensch -u %s -t 24 -z +0" % (user)).read().replace("\t", ": ").split("\n")
for mention in menschns:
if not "" == mention:
toSend = "PRIVMSG "+ nick + " :" + mention + "\n"
if len(toSend) >= 256:
toSend = toSend[:253] + '...'
ircsock.send(toSend)
nick = get_user_from_message(message)
menschns = (
os.popen("/home/karlen/bin/mensch -u %s -t 24 -z +0" % (user))
.read()
.replace("\t", ": ")
.split("\n")
)
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):
chattyOut = os.popen("/home/karlen/bin/chatty").read().split("\n")
for line in chattyOut:
if line:
ircsock.send("PRIVMSG "+ channel + " :" + line + "\n")
chattyOut = os.popen("/home/karlen/bin/chatty").read().split("\n")
for line in chattyOut:
if line:
ircsock.send("PRIVMSG " + channel + " :" + line + "\n")
def listen():
while 1:
while 1:
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r')
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
formatted = formatter.format_message(ircmsg)
formatted = formatter.format_message(ircmsg)
if "" == formatted:
continue
if "" == formatted:
continue
print formatted
print(formatted)
split = formatted.split("\t")
time = split[0]
user = split[1]
messageText = split[2]
split = formatted.split("\t")
time = split[0]
user = split[1]
messageText = split[2]
if ircmsg.find(":!quote") != -1:
random_quote(options.channel)
if ircmsg.find(":!quote") != -1:
random_quote(options.channel)
if ircmsg.find(":!mentions") != -1:
say_mentions(user, ircmsg)
if ircmsg.find(":!mentions") != -1:
say_mentions(user, ircmsg)
if ircmsg.find(":!chatty") != -1:
say_chatty(options.channel)
if ircmsg.find(":!chatty") != -1:
say_chatty(options.channel)
if ircmsg.find(":!haiku") != -1:
haiku(options.channel)
if ircmsg.find(":!haiku") != -1:
haiku(options.channel)
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
sys.stdout.flush()
time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)

View File

@ -3,10 +3,11 @@ import re
quotefile = "/home/karlen/irc/quotes.txt"
def get_quote():
quotes = open(quotefile, "r").read().split("---")
quote,attr = random.choice(quotes).strip().splitlines()
quote = quote[:200] #get only the first 200 chars
word = random.choice([q for q in quote.split(' ') if len(q) > 1])
quote, attr = random.choice(quotes).strip().splitlines()
quote = quote[:200] # get only the first 200 chars
word = random.choice([q for q in quote.split(" ") if len(q) > 1])
quote = quote.replace(word, re.sub(r"[a-zA-Z]", "_", word))
return [word, "Fill in the blank: \"" + quote + "\" " + attr]
return [word, 'Fill in the blank: "' + quote + '" ' + attr]

View File

@ -1,16 +1,17 @@
import random
def makeRainbow(word):
word = word or "RAINBOW"
output = ""
rb = ["5","7","8","3","12","13","6"]
rb = ["5", "7", "8", "3", "12", "13", "6"]
bg = "01"
idx = random.randrange(0, len(rb))
for l in word:
if l == " ":
output += ' '
output += " "
else:
output += "\x03" + rb[idx % len(rb)] + "," + bg + l
idx += 1

View File

@ -1,25 +1,39 @@
import urllib
#from lxml.html import fromstring
# from lxml.html import fromstring
from bs4 import BeautifulSoup
import random
def getRhymes(word):
words = []
url = 'http://www.rhymer.com/RhymingDictionaryLast/%s.html' % word
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser')
for t in soup.find_all('table', 'table'):
words.append(random.choice([w for w in t.text.split('\n') if w not in [u'', u'\xa0'] and '-' not in w]))
return words
words = []
url = "http://www.rhymer.com/RhymingDictionaryLast/%s.html" % word
soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
for t in soup.find_all("table", "table"):
words.append(
random.choice(
[
w
for w in t.text.split("\n")
if w not in [u"", u"\xa0"] and "-" not in w
]
)
)
return words
def rhymeZone(word):
words = []
url = 'http://rhymezone.com/r/rhyme.cgi?Word=%s&typeofrhyme=perfect&org1=syl&org2=l&org3=y' % word
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser')
url = (
"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()
if w not in [u'', u'\xa0'] and '?' not in t:
words.append(w.encode('ascii', 'ignore'))
if w not in [u"", u"\xa0"] and "?" not in t:
words.append(w.encode("ascii", "ignore"))
random.shuffle(words)
return words[0:5]

View File

@ -13,76 +13,111 @@ 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")
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 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")
ircsock.send("JOIN " + chan + "\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
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")
# 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")
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)
joinchan(channel)
def get_user_from_message(msg):
try:
i1 = msg.index(':') + 1
i2 = msg.index('!')
return msg[i1:i2]
except ValueError:
return ""
try:
i1 = msg.index(":") + 1
i2 = msg.index("!")
return msg[i1:i2]
except ValueError:
return ""
def listen():
while 1:
while 1:
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r')
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
formatted = formatter.format_message(ircmsg)
formatted = formatter.format_message(ircmsg)
if "" == formatted:
continue
if "" == formatted:
continue
print formatted
print(formatted)
split = formatted.split("\t")
time = split[0]
user = split[1]
messageText = split[2]
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.find(":!tilde") != -1:
tilde(options.channel, user, time)
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
sys.stdout.flush()
sys.stdout.flush()
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)

View File

@ -21,12 +21,30 @@ import util
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='tildebot',
help="the nick to use", metavar="NICK")
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="tildebot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args()
@ -37,57 +55,198 @@ JACKPOT_FILE = "tildejackpot.txt"
JACKPOT_MIN = 3
DEBUG = False
def hello():
util.sendmsg(ircsock, channel, "Hello!")
util.sendmsg(ircsock, channel, "Hello!")
def too_recent(time1, time2):
return int(time1) - int(time2) < 60*60
return int(time1) - int(time2) < 60 * 60
def get_positive():
return random.choice(['Yes', 'Yep', 'Yeppers', 'Correct','You got it', 'Yeah', 'Right on', 'Uh-huh', 'Positive', 'Totally right', 'Close enough', 'That\'s it'])
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():
return random.choice(['No', 'Nope', 'Sorry', 'Wrong', 'Nuh-uh', 'Negatory', 'Incorrect', 'Not today', 'Try again', 'Maybe later', 'Probably not', 'Answer hazy', 'Not quite',\
'Not even close'])
return random.choice(
[
"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):
if score > 4:
return random.choice(["super cool", "totally rad", "extraordinary", "dynomite", "#topdrawer", "a #TopLad", "the cat's meow", "a tilde town hero", "my favorite person", "incredibly lucky",\
"unbelievable", "a tilde town hunk", "could bring all the boys to the yard", "worth twice their weight in gold", "the hero we need", "no ordinary townie"]);
return random.choice(
[
"super cool",
"totally rad",
"extraordinary",
"dynomite",
"#topdrawer",
"a #TopLad",
"the cat's meow",
"a tilde town hero",
"my favorite person",
"incredibly lucky",
"unbelievable",
"a tilde town hunk",
"could bring all the boys to the yard",
"worth twice their weight in gold",
"the hero we need",
"no ordinary townie",
]
)
elif score > 2:
return random.choice(["really cool", "pretty neat", "rather nice", "a dynamic doggo", "radical", "intense", "pretty lucky", "knows the territory", "has what it takes", "has mad skillz",\
"going the distance", "a hard worker", "my sunshine", "ready to rumble"]);
return random.choice(
[
"really cool",
"pretty neat",
"rather nice",
"a dynamic doggo",
"radical",
"intense",
"pretty lucky",
"knows the territory",
"has what it takes",
"has mad skillz",
"going the distance",
"a hard worker",
"my sunshine",
"ready to rumble",
]
)
else:
return random.choice(["cool", "nice", "acceptible", "good enough", "a promising pupper", "better than a horse", "swell", "a little lucky", "just credible", "my friend", "probably not a robot",\
"valuable to the team"]);
return random.choice(
[
"cool",
"nice",
"acceptible",
"good enough",
"a promising pupper",
"better than a horse",
"swell",
"a little lucky",
"just credible",
"my friend",
"probably not a robot",
"valuable to the team",
]
)
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",\
"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"]);
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",
"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):
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
if(random.randint(1,10) > 6 - 4 * isHuman): #80% of the time it's a normal prize (40% for not humans)
return [prize, name + ": " + (get_positive() if isHuman else get_negative()) + "! You are " + get_superlative(prize) + " and get " + p.number_to_words(prize) + " tildes!"]
else: #20% of the time its a jackpot situation
if (
random.randint(1, 10) > 6 - 4 * isHuman
): # 80% of the time it's a normal prize (40% for not humans)
return [
prize,
name
+ ": "
+ (get_positive() if isHuman else get_negative())
+ "! You are "
+ get_superlative(prize)
+ " and get "
+ p.number_to_words(prize)
+ " tildes!",
]
else: # 20% of the time its a jackpot situation
with open(JACKPOT_FILE, "r+") as jackpotfile:
jackpot = int(jackpotfile.readline().strip("\n"))
jackpotfile.seek(0)
jackpotfile.truncate()
if(random.randint(1,10) > 1 or not isHuman): #90% of the time it's a non-prize. non-humans never win jackpot
new_jackpot = jackpot+max(1,prize)
jackpotfile.write(str(new_jackpot)) #increase the jackpot by the prize size
return [0, name + " " + get_bad_thing() + " and gets no tildes! (Jackpot is now " + str(new_jackpot) + " tildes)"]
else: #hit jackpot!
if (
random.randint(1, 10) > 1 or not isHuman
): # 90% of the time it's a non-prize. non-humans never win jackpot
new_jackpot = jackpot + max(1, prize)
jackpotfile.write(
str(new_jackpot)
) # increase the jackpot by the prize size
return [
0,
name
+ " "
+ get_bad_thing()
+ " and gets no tildes! (Jackpot is now "
+ str(new_jackpot)
+ " tildes)",
]
else: # hit jackpot!
jackpotfile.write(str(JACKPOT_MIN))
return [jackpot, name + " hit the jackpot and won **" + p.number_to_words(jackpot) + " tildes!**"]
return [
jackpot,
name
+ " hit the jackpot and won **"
+ p.number_to_words(jackpot)
+ " tildes!**",
]
def show_jackpot(channel):
with open(JACKPOT_FILE, "r") as jackpotfile:
jackpot = int(jackpotfile.readline().strip("\n"))
util.sendmsg(ircsock, channel, "The jackpot is currently {} tildes!".format(p.number_to_words(jackpot)))
util.sendmsg(
ircsock,
channel,
"The jackpot is currently {} tildes!".format(p.number_to_words(jackpot)),
)
def give_tilde(channel, user, name, time, human, bonus=0):
found = False
@ -97,117 +256,158 @@ def give_tilde(channel, user, name, time, human, bonus=0):
scorefile.truncate()
for score in scores:
person = score.strip("\n").split("&^%")
if(person[0] == user):
if person[0] == user:
found = True
if(too_recent(time, person[2]) and not DEBUG):
util.sendmsg(ircsock, channel, "{} asked for a tilde too recently and {}. Try again later.".format(name, get_bad_thing()))
if too_recent(time, person[2]) and not DEBUG:
util.sendmsg(
ircsock,
channel,
"{} asked for a tilde too recently and {}. Try again later.".format(
name, get_bad_thing()
),
)
else:
prize = get_prize(name, human, bonus)
score = person[0] + "&^%" + str(int(person[1]) + prize[0]) + "&^%" + time + "\n"
score = (
person[0]
+ "&^%"
+ str(int(person[1]) + prize[0])
+ "&^%"
+ time
+ "\n"
)
util.sendmsg(ircsock, channel, prize[1])
scorefile.write(score)
if(not found):
if not found:
prize = get_prize(name, True, bonus)
util.sendmsg(ircsock, channel, "Welcome to the tilde game! Here's {} free tilde(s) to start you off.".format(p.number_to_words(prize[0]+1)))
scorefile.write(user + "&^%" + str(prize[0]+1) + "&^%" + time + "\n")
util.sendmsg(
ircsock,
channel,
"Welcome to the tilde game! Here's {} free tilde(s) to start you off.".format(
p.number_to_words(prize[0] + 1)
),
)
scorefile.write(user + "&^%" + str(prize[0] + 1) + "&^%" + time + "\n")
def show_tildescore(channel, user, name):
with open(SCORE_FILE, "r") as scorefile:
for idx,score in enumerate(scorefile):
for idx, score in enumerate(scorefile):
person = score.strip("\n").split("&^%")
if(person[0] == user):
util.sendmsg(ircsock, channel, "{} has {} tildes!".format(name, p.number_to_words(person[1])))
if person[0] == user:
util.sendmsg(
ircsock,
channel,
"{} has {} tildes!".format(name, p.number_to_words(person[1])),
)
return
#person has not played yet
# person has not played yet
util.sendmsg(ircsock, channel, "{} has no tildes yet!".format(name))
def challenge(channel, user, name, time):
if(channel != "#bots" and not DEBUG):
util.sendmsg(ircsock, channel, "{} is a meanie and gets no tildes. **Tildebot now only gives out tildes in the #bots channel.**".format(name))
if channel != "#bots" and not DEBUG:
util.sendmsg(
ircsock,
channel,
"{} is a meanie and gets no tildes. **Tildebot now only gives out tildes in the #bots channel.**".format(
name
),
)
return
global challenges;
challenge = puzzle.make_puzzle();
challenges[user] = challenge[1:]; #challenges[USER] = [ANSWER, BONUS]
global challenges
challenge = puzzle.make_puzzle()
challenges[user] = challenge[1:]
# challenges[USER] = [ANSWER, BONUS]
util.sendmsg(ircsock, channel, "{}: {}".format(name, challenge[1]))
def challenge_response(channel, user, name, time, msg):
global challenges
print(msg);
if(challenges.has_key(user)):
print(msg)
if challenges.has_key(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))):
give_tilde(channel, user, name, time, True, bonus);
if (callable(answer) and answer(msg.lower())) or (
msg.lower() == str(answer).lower() or msg == p.number_to_words(answer)
):
give_tilde(channel, user, name, time, True, bonus)
else:
give_tilde(channel, user, name, time, False, 0);
del challenges[user]; #delete the user from challenges either way
give_tilde(channel, user, name, time, False, 0)
del challenges[user]
# delete the user from challenges either way
def rollcall(channel):
util.sendmsg(ircsock, channel, "tildebot reporting! I respond to !tilde !tildescore")
util.sendmsg(
ircsock, channel, "tildebot reporting! I respond to !tilde !tildescore"
)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER {0} {0} {0} :krowbar\r\n".format(botnick)) # user authentication
ircsock.send("NICK {}\r\n".format(botnick))
ircsock.send("MODE +B {}\r\n".format(botnick))
ircsock.connect((server, 6667))
ircsock.send("USER {0} {0} {0} :krowbar\r\n".format(botnick)) # user authentication
ircsock.send("NICK {}\r\n".format(botnick))
ircsock.send("MODE +B {}\r\n".format(botnick))
joinchan(channel)
if not DEBUG:
joinchan("#bots")
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 ""
try:
i1 = msg.index(":") + 1
i2 = msg.index("!")
return msg[i1:i2]
except ValueError:
return ""
def listen():
while 1:
while 1:
ircmsg = ircsock.recv(2048)
for msg in ircmsg.split('\n'):
msg = msg.strip('\n\r')
ircmsg = ircsock.recv(2048)
for msg in ircmsg.split("\n"):
msg = msg.strip("\n\r")
if msg[:4] == "PING":
util.ping(ircsock, msg)
if msg[:4] == "PING":
util.ping(ircsock, msg)
formatted = formatter.format_message(msg)
formatted = formatter.format_message(msg)
if "" == formatted:
continue
if "" == formatted:
continue
# print formatted
# print formatted
split = formatted.split("\t")
iTime = split[0]
user = split[1]
name = names.get_name(user)
command = split[2]
channel = split[3]
messageText = split[4]
split = formatted.split("\t")
iTime = split[0]
user = split[1]
name = names.get_name(user)
command = split[2]
channel = split[3]
messageText = split[4]
if msg.find(":!tildescore") != -1:
show_tildescore(channel, user, name)
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(":!tildescore") != -1:
show_tildescore(channel, user, name)
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:
show_jackpot(channel)
if msg.find(":!jackpot") != -1:
show_jackpot(channel)
if msg.find(":!rollcall") != -1:
rollcall(channel)
if msg.find(":!rollcall") != -1:
rollcall(channel)
if msg[:4] == "PING":
util.ping(ircsock, msg)
if msg[:4] == "PING":
util.ping(ircsock, msg)
sys.stdout.flush()
time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)

View File

@ -19,179 +19,255 @@ import names
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='topicbot',
help="the nick to use", metavar="NICK")
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="topicbot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args()
p = inflect.engine()
def ping(pong):
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
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")
ircsock.send("JOIN " + chan + "\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
ircsock.send("PRIVMSG " + channel + " :Hello!\n")
def get_topic(channel, user, time):
#topic scores are saved as <USER>&^%<GETS SCORE>&^%<SETS SCORE>
with open("topicscores.txt", "r") as scorefile:
scores = scorefile.readlines()
userscore = 1
found = False
with open("topicscores.txt", "w") as scorefile:
for idx,score in enumerate(scores):
data = score.strip("\n").split("&^%")
if(data[0] == user):
found = True
userscore = int(data[1])+1
scores[idx] = data[0] + "&^%" + str(userscore) + "&^%" + data[2] + "\n"
scorefile.writelines(scores)
if(not found):
scorefile.write(user + "&^%1&^%0\n")
# topic scores are saved as <USER>&^%<GETS SCORE>&^%<SETS SCORE>
with open("topicscores.txt", "r") as scorefile:
scores = scorefile.readlines()
userscore = 1
found = False
with open("topicscores.txt", "w") as scorefile:
for idx, score in enumerate(scores):
data = score.strip("\n").split("&^%")
if data[0] == user:
found = True
userscore = int(data[1]) + 1
scores[idx] = data[0] + "&^%" + str(userscore) + "&^%" + data[2] + "\n"
scorefile.writelines(scores)
if not found:
scorefile.write(user + "&^%1&^%0\n")
with open("topics_" + channel + ".txt", "r") as topics:
topic = topics.readlines()[-1].strip("\n").split("&^%", 3)
byuser = 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"
)
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):
with open("topics_" + channel + ".txt", "a") as topics:
topics.write(time + "&^%" + user + "&^%" + msg + "\n")
with open("topicscores.txt", "r") as scorefile:
scores = scorefile.readlines()
userscore = 1
found = False
with open("topicscores.txt", "w") as scorefile:
for idx,score in enumerate(scores):
data = score.strip("\n").split("&^%")
if(data[0] == user):
found = True
userscore = int(data[2])+1
scores[idx] = data[0] + "&^%" + data[1] + "&^%" + str(userscore) + "\n"
scorefile.writelines(scores)
if(not found):
scorefile.write(user + "&^%0&^%1")
ircsock.send("PRIVMSG "+ channel +" :" + user + " has changed the topic " + p.number_to_words(userscore) + " times!\n")
with open("topics_" + channel + ".txt", "a") as topics:
topics.write(time + "&^%" + user + "&^%" + msg + "\n")
with open("topicscores.txt", "r") as scorefile:
scores = scorefile.readlines()
userscore = 1
found = False
with open("topicscores.txt", "w") as scorefile:
for idx, score in enumerate(scores):
data = score.strip("\n").split("&^%")
if data[0] == user:
found = True
userscore = int(data[2]) + 1
scores[idx] = data[0] + "&^%" + data[1] + "&^%" + str(userscore) + "\n"
scorefile.writelines(scores)
if not found:
scorefile.write(user + "&^%0&^%1")
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ " has changed the topic "
+ p.number_to_words(userscore)
+ " times!\n"
)
def set_topic(channel, user, time, msg):
ircsock.send("TOPIC "+ channel +" :" + msg + "\n")
count_topic(channel, user, time, msg)
ircsock.send("TOPIC " + channel + " :" + msg + "\n")
count_topic(channel, user, time, msg)
def random_topic(channel, user, time, setTopic=False):
with open("randomtopics.txt") as rtopics:
msg = random.choice(rtopics.readlines()).strip("\n")
if(setTopic):
set_topic(channel, user, time, msg)
else:
ircsock.send("PRIVMSG "+channel +" :Suggested Topic: " + msg + "\n")
msg = random.choice(rtopics.readlines()).strip("\n")
if setTopic:
set_topic(channel, user, time, msg)
else:
ircsock.send("PRIVMSG " + channel + " :Suggested Topic: " + msg + "\n")
def rollcall(channel):
ircsock.send("PRIVMSG "+ channel +" :topicbot reporting! I respond to !topic !settopic !suggesttopic !thistory\n")
ircsock.send(
"PRIVMSG "
+ channel
+ " :topicbot reporting! I respond to !topic !settopic !suggesttopic !thistory\n"
)
def topic_score(channel):
ircsock.send("PRIVMSG "+ channel +" :Not implemented yet")
ircsock.send("PRIVMSG " + channel + " :Not implemented yet")
def topic_scores(channel):
ircsock.send("PRIVMSG "+ channel +" :Not implemented yet")
ircsock.send("PRIVMSG " + channel + " :Not implemented yet")
def topic_history(channel, user, count):
try:
iCount = int(count.split()[1])
except (ValueError, IndexError) as e:
iCount = 3
if(iCount > 10):
iCount = 10
if(iCount < 1):
iCount = 3
with open("topics_" + channel + ".txt", "r") as topicsfile:
#topics = topicsfile.readlines()[-iCount:].reverse()
ircsock.send("PRIVMSG "+ channel +" :Ok, here were the last " + p.number_to_words(iCount) + " topics\n")
for idx,topic in enumerate(reversed(topicsfile.readlines()[-iCount:])):
topic = topic.strip("\n").split("&^%", 3)
byuser = names.get_name(topic[1])
ircsock.send("PRIVMSG "+ channel +" :" + str(idx+1) + ": \"" + topic[2] + "\" (Set by " + byuser + " " + pretty_date.pretty_date(int(topic[0])) + ")\n")
try:
iCount = int(count.split()[1])
except (ValueError, IndexError) as e:
iCount = 3
if iCount > 10:
iCount = 10
if iCount < 1:
iCount = 3
with open("topics_" + channel + ".txt", "r") as topicsfile:
# topics = topicsfile.readlines()[-iCount:].reverse()
ircsock.send(
"PRIVMSG "
+ channel
+ " :Ok, here were the last "
+ p.number_to_words(iCount)
+ " topics\n"
)
for idx, topic in enumerate(reversed(topicsfile.readlines()[-iCount:])):
topic = topic.strip("\n").split("&^%", 3)
byuser = names.get_name(topic[1])
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ str(idx + 1)
+ ': "'
+ topic[2]
+ '" (Set by '
+ byuser
+ " "
+ pretty_date.pretty_date(int(topic[0]))
+ ")\n"
)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :krowbar\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
ircsock.connect((server, 6667))
ircsock.send(
"USER " + botnick + " " + botnick + " " + botnick + " :krowbar\n"
) # user authentication
ircsock.send("NICK " + botnick + "\n")
joinchan(channel)
joinchan("#bots")
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 ""
try:
i1 = msg.index(":") + 1
i2 = msg.index("!")
return msg[i1:i2]
except ValueError:
return ""
def listen():
while 1:
while 1:
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r')
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
formatted = formatter.format_message(ircmsg)
formatted = formatter.format_message(ircmsg)
if "" == formatted:
continue
if "" == formatted:
continue
# print formatted
# print formatted
split = formatted.split("\t")
msgtime = split[0]
user = split[1]
command = split[2]
channel = split[3]
messageText = split[4]
split = 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):
count_topic(channel,user, msgtime, messageText)
if command == "TOPIC" and user != options.nick:
count_topic(channel, user, msgtime, messageText)
if ircmsg.find(":!topic") != -1:
get_topic(channel, user, msgtime)
if ircmsg.find(":!topic") != -1:
get_topic(channel, user, msgtime)
if ircmsg.find(":!settopic") != -1:
set_topic(channel, user, msgtime, messageText[10:])
if ircmsg.find(":!settopic") != -1:
set_topic(channel, user, msgtime, messageText[10:])
if ircmsg.find(":!tscores") != -1:
topic_scores(channel)
elif ircmsg.find(":!tscores") != -1:
topic_score(channel)
if ircmsg.find(":!tscores") != -1:
topic_scores(channel)
elif ircmsg.find(":!tscores") != -1:
topic_score(channel)
if ircmsg.find(":!randomtopic") != -1:
random_topic(channel, user, msgtime, True)
if ircmsg.find(":!suggesttopic") != -1:
random_topic(channel,user,msgtime, False)
if ircmsg.find(":!randomtopic") != -1:
random_topic(channel, user, msgtime, True)
if ircmsg.find(":!suggesttopic") != -1:
random_topic(channel, user, msgtime, False)
if ircmsg.find(":!thistory") != -1:
topic_history(channel, user, messageText)
if ircmsg.find(":!thistory") != -1:
topic_history(channel, user, messageText)
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
sys.stdout.flush()
time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)

View File

@ -2,30 +2,48 @@ import urllib
from bs4 import BeautifulSoup
import random
import re
def tumble(url):
#Find the max pages
soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser')
pages = soup.findAll('span', 'page-numbers')[0].text.split('/')[1] #this could totally fail several ways
tries = 3
while True:
try:
page = random.randrange(1, int(pages)+1)
# Find the max pages
soup = BeautifulSoup(urllib.urlopen(url).read(), "html.parser")
pages = soup.findAll("span", "page-numbers")[0].text.split("/")[
1
] # this could totally fail several ways
tries = 3
while True:
try:
page = random.randrange(1, int(pages) + 1)
#Parse a page
soup = BeautifulSoup(urllib.urlopen(url + '/page/' + str(page)).read(), 'html.parser')
article = random.choice(soup.findAll('article'))
quote = article.find('blockquote').text.replace('\n','');
if len(article.find('footer').findAll('ul')) > 1:
quote += re.sub('\n+', ' ', article.find('footer').findAll('ul')[0].text); #the hash tags
quote += '(' + re.sub('\n+', ' ', article.find('footer').findAll('ul')[1].text) + ')'; #and the date and notes
else:
quote += '(' + re.sub('\n+', ' ', article.find('footer').findAll('ul')[0].text) + ')'; #just the date and notes
# Parse a page
soup = BeautifulSoup(
urllib.urlopen(url + "/page/" + str(page)).read(), "html.parser"
)
article = random.choice(soup.findAll("article"))
quote = article.find("blockquote").text.replace("\n", "")
if len(article.find("footer").findAll("ul")) > 1:
quote += re.sub(
"\n+", " ", article.find("footer").findAll("ul")[0].text
)
# the hash tags
quote += (
"("
+ re.sub("\n+", " ", article.find("footer").findAll("ul")[1].text)
+ ")"
)
# and the date and notes
else:
quote += (
"("
+ re.sub("\n+", " ", article.find("footer").findAll("ul")[0].text)
+ ")"
)
# just the date and notes
return quote.encode('ascii', 'ignore')
except: #sometimes we fail. let's retry a few times
if tries == 0:
return ''
else:
tries -= 1
break
return quote.encode("ascii", "ignore")
except: # sometimes we fail. let's retry a few times
if tries == 0:
return ""
else:
tries -= 1
break

View File

@ -5,12 +5,15 @@ import re
def ping(pong):
ircsock.send("PONG {}\n".format(pong.split(" ")[1]))
def sendmsg(ircsock, chan , msg):
def sendmsg(ircsock, chan, msg):
ircsock.send("PRIVMSG {} :{}\r\n".format(chan, msg))
def joinchan(ircsock, chan):
ircsock.send("JOIN {}\n".format(chan))
# integer number to english word conversion
# can be used for numbers as large as 999 vigintillion
# (vigintillion --> 10 to the power 60)
@ -32,7 +35,7 @@ def int2word(n):
if q < -2:
break
else:
if q >= 0:
if q >= 0:
n3.append(int(r[:3]))
elif q >= -1:
n3.append(int(r[:2]))
@ -40,7 +43,7 @@ def int2word(n):
n3.append(int(r[:1]))
r1 = r
#print n3 # test
# print n3 # test
# break each group of 3 digits into
# ones, tens/twenties, hundreds
@ -48,9 +51,9 @@ def int2word(n):
nw = ""
for i, x in enumerate(n3):
b1 = x % 10
b2 = (x % 100)//10
b3 = (x % 1000)//100
#print b1, b2, b3 # test
b2 = (x % 100) // 10
b3 = (x % 1000) // 100
# print b1, b2, b3 # test
if x == 0:
continue # skip
else:
@ -64,33 +67,85 @@ def int2word(n):
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 "]
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'^:.*\!~(.*)@.* (.*) (.*) :(.*)'
pattern = r"^:.*\!~(.*)@.* (.*) (.*) :(.*)"
now = int(time.time())
matches = re.match(pattern, message)
if not matches:
return ''
return ""
nick = matches.group(1).strip()
command = matches.group(2).strip()
channel = matches.group(3).strip()
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 = []
@ -102,46 +157,47 @@ def get_users():
return users
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
from datetime import datetime
if day_diff < 0:
return ''
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:
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"
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"

View File

@ -20,12 +20,30 @@ import inflect
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='numberwang_bot',
help="the nick to use", metavar="NICK")
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="numberwang_bot",
help="the nick to use",
metavar="NICK",
)
(options, args) = parser.parse_args()
@ -43,116 +61,194 @@ guesses = 0
lastGuesser = ""
currentScores = {}
def resetGlobals():
global roundsLeft
global bonusRound
global guesses
global lastGuesser
global currentScores
roundsLeft = 0
bonusRound = 0
guesses = 0
lastGuesser = ""
currentScores.clear()
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))
ircsock.send("PONG {}\n".format(pong))
def sendmsg(chan, msg):
ircsock.send("PRIVMSG " + chan + " :" + msg + "\n")
def sendmsg(chan , msg):
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan):
ircsock.send("JOIN "+ chan +"\n")
ircsock.send("JOIN " + chan + "\n")
def hello():
ircsock.send("PRIVMSG "+ channel +" :Hello!\n")
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")
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"
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
+ " :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 bonusRound
roundsLeft = random.randint(MIN_ROUNDS,MAX_ROUNDS)
bonusRound = random.randint(2,roundsLeft-1)
print "There will be " + str(roundsLeft) + " rounds with the bonus on round " + str(roundsLeft - bonusRound + 1)
roundsLeft = random.randint(MIN_ROUNDS, MAX_ROUNDS)
bonusRound = random.randint(2, roundsLeft - 1)
print(
"There will be "
+ str(roundsLeft)
+ " rounds with the bonus on round "
+ str(roundsLeft - bonusRound + 1)
)
def print_scores(channel):
scoreStrs = []
first = True
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(
name
+ " is "
+ ("also " if not first and random.randint(1, 3) == 3 else "")
+ "on "
+ str(currentScores[name])
)
first = False
ircsock.send("PRIVMSG " + channel + " :" + p.join(scoreStrs) + "!\n")
def guess_numberwang(channel, user, messageText):
global guesses
global lastGuesser
global currentScores
global roundsLeft
print user + " guessed '" + messageText + "'"
guess = re.sub('[^0-9]','',messageText.split()[0]) #must have a number in the first 'word'
if(guess):
if(LIMIT_GUESSING and user == lastGuesser):
ircsock.send("PRIVMSG " + channel + " :" + user + ", you just guessed! Give another player a try!\n")
print(user + " guessed '" + messageText + "'")
guess = re.sub(
"[^0-9]", "", messageText.split()[0]
) # must have a number in the first 'word'
if guess:
if LIMIT_GUESSING and user == lastGuesser:
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ", you just guessed! Give another player a try!\n"
)
else:
guesses += 1
lastGuesser = user
###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
lastGuesser = ""
ircsock.send("PRIVMSG " + channel + " :" + user + ": THAT'S NUMBERWANG!\n")
points = random.randint(2,10) * (random.randint(2,4) if roundsLeft == bonusRound else 1)
ircsock.send(
"PRIVMSG " + channel + " :" + user + ": THAT'S NUMBERWANG!\n"
)
points = random.randint(2, 10) * (
random.randint(2, 4) if roundsLeft == bonusRound else 1
)
if user in currentScores.keys():
currentScores[user] += points
else:
currentScores[user] = points
roundsLeft -= 1
time.sleep(2)
if(roundsLeft == 0):
ircsock.send("PRIVMSG " + channel + " :Numberwang is now over. Thank you for playing!\n")
if roundsLeft == 0:
ircsock.send(
"PRIVMSG "
+ channel
+ " :Numberwang is now over. Thank you for playing!\n"
)
ircsock.send("PRIVMSG " + channel + " :Final scores:\n")
print_scores(channel)
save_scores()
else:
print_scores(channel)
newRoundStr = ""
if(roundsLeft == 1):
if roundsLeft == 1:
newRoundStr += "The last round is Wangernumb!"
elif(roundsLeft == bonusRound):
elif roundsLeft == bonusRound:
newRoundStr += "**Bonus Round!**"
else:
newRoundStr += "New Round!"
if(random.randint(1,10) > 8):
if random.randint(1, 10) > 8:
newRoundStr += " Let's rotate the board!"
ircsock.send("PRIVMSG " + channel + " :" + newRoundStr + " Start guessing!\n")
ircsock.send(
"PRIVMSG " + channel + " :" + newRoundStr + " Start guessing!\n"
)
###INCORRECT GUESS###
else:
ircsock.send("PRIVMSG " + channel + " :" + 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"])\
+ " Numberwang!\n")
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ 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",
]
)
+ " Numberwang!\n"
)
def stop_numberwang(channel, user):
print user + " stopped a game"
print(user + " stopped a game")
resetGlobals()
ircsock.send("PRIVMSG " + channel + " :Numberwang has been stopped. No points have been awarded. " + user + " is such a party pooper!\n")
ircsock.send(
"PRIVMSG "
+ channel
+ " :Numberwang has been stopped. No points have been awarded. "
+ user
+ " is such a party pooper!\n"
)
def save_scores():
with open(SCORE_FILE, "r+") as scorefile:
@ -162,16 +258,22 @@ def save_scores():
for line in scores:
for name in currentScores:
score = line.strip("\n").split("&^%")
if(score[0] == name):
line = score[0] + "&^%" + str(int(score[1]) + currentScores[name]) + "\n"
if score[0] == name:
line = (
score[0]
+ "&^%"
+ str(int(score[1]) + currentScores[name])
+ "\n"
)
del currentScores[name]
break
scorefile.write(line)
for name in currentScores: #new wangers
for name in currentScores: # new wangers
line = name + "&^%" + str(currentScores[name]) + "\n"
scorefile.write(line)
def show_highscores(channel):
with open(SCORE_FILE, "r") as scorefile:
scores = []
@ -182,83 +284,116 @@ def show_highscores(channel):
ircsock.send("PRIVMSG " + channel + " : ====TOP WANGERS====\n")
for score in scores:
ircsock.send("PRIVMSG " + channel + " :== ~" + score[1] + " (" + str(score[0]) + " points!) ==\n")
ircsock.send(
"PRIVMSG "
+ channel
+ " :== ~"
+ score[1]
+ " ("
+ str(score[0])
+ " points!) ==\n"
)
def show_user_score(channel, user):
with open(SCORE_FILE, "r") as scorefile:
for line in scorefile.readlines():
score = line.strip("\n").split("&^%")
if(user == score[0]):
ircsock.send("PRIVMSG " + channel + " :" + user + ": Your global numberwang score is " + str(score[1]) + "!\n")
if user == score[0]:
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": Your global numberwang score is "
+ str(score[1])
+ "!\n"
)
return
#if we don't find a score line
ircsock.send("PRIVMSG " + channel + " :" + user + ": You haven't scored any points yet!\n")
# if we don't find a score line
ircsock.send(
"PRIVMSG "
+ channel
+ " :"
+ user
+ ": You haven't scored any points yet!\n"
)
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")
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"
)
def connect(server, channel, botnick):
ircsock.connect((server, 6667))
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :krowbar\n") # user authentication
ircsock.send("NICK "+ botnick +"\n")
ircsock.connect((server, 6667))
ircsock.send(
"USER " + botnick + " " + botnick + " " + botnick + " :krowbar\n"
) # user authentication
ircsock.send("NICK " + botnick + "\n")
joinchan(channel)
joinchan(GOOD_CHAN)
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 ""
try:
i1 = msg.index(":") + 1
i2 = msg.index("!")
return msg[i1:i2]
except ValueError:
return ""
def listen():
while 1:
while 1:
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip('\n\r')
ircmsg = ircsock.recv(2048)
ircmsg = ircmsg.strip("\n\r")
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
formatted = formatter.format_message(ircmsg)
formatted = formatter.format_message(ircmsg)
if "" == formatted:
continue
if "" == formatted:
continue
# print formatted
# print formatted
split = formatted.split("\t")
time = split[0]
user = split[1]
command = split[2]
channel = split[3]
messageText = split[4]
split = 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:
start_numberwang(channel, user)
if ircmsg.find(":!numberwang") != -1 and roundsLeft == 0:
start_numberwang(channel, user)
if channel == GOOD_CHAN:
if ircmsg.find(":!wangernumb") != -1 and roundsLeft > 0:
stop_numberwang(channel, user)
if roundsLeft > 0:
guess_numberwang(channel, user, messageText)
if channel == GOOD_CHAN:
if ircmsg.find(":!wangernumb") != -1 and roundsLeft > 0:
stop_numberwang(channel, user)
if roundsLeft > 0:
guess_numberwang(channel, user, messageText)
if ircmsg.find(":!topwangers") != -1:
show_highscores(channel)
if ircmsg.find(":!myscore") != -1:
show_user_score(channel, user)
if ircmsg.find(":!topwangers") != -1:
show_highscores(channel)
if ircmsg.find(":!myscore") != -1:
show_user_score(channel, user)
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
if ircmsg.find(":!rollcall") != -1:
rollcall(channel)
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
if ircmsg[:4] == "PING":
ping(ircmsg.split(" ")[1])
sys.stdout.flush()
time.sleep(1)
sys.stdout.flush()
time.sleep(1)
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect(options.server, options.channel, options.nick)

View File

@ -1,6 +1,10 @@
import random
def get_thing():
file = "/home/krowbar/logs/welchdata.txt"
thing = ""
return "Thing Mr. Welch can no longer do in a RPG #" + random.choice(list(open(file))).rstrip()
return (
"Thing Mr. Welch can no longer do in a RPG #"
+ random.choice(list(open(file))).rstrip()
)

View File

@ -8,20 +8,22 @@ import operator
MAX_NODES = 5
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 = {
'jumblesal': 'jumblesale',
'hardmath1': 'kc',
'hardmath123': 'kc',
'bendorphan': 'endorphant',
'endorphan': 'endorphant',
'synergian': 'synergiance'
}
"jumblesal": "jumblesale",
"hardmath1": "kc",
"hardmath123": "kc",
"bendorphan": "endorphant",
"endorphan": "endorphant",
"synergian": "synergiance",
}
def whoSaid(word):
word = word.lower()
userData = {} #hash keyed by "user" that contains a hash of mentioned other users with count
#Get a list of all user names by checking the logs for people who have said things
userData = {} # hash keyed by "user" that contains a hash of mentioned other users with count
# Get a list of all user names by checking the logs for people who have said things
with open(logfile, "r") as log:
for line in log:
try:
@ -32,12 +34,12 @@ def whoSaid(word):
else:
user = user.lower()
except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse
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:
userData[user] += 1
else:
userData[user] = 1
userData = sorted(userData.items(), key=operator.itemgetter(1), reverse=True)
return {'timecutoff': timeCutoff, 'data': userData}
return {"timecutoff": timeCutoff, "data": userData}

View File

@ -1,50 +1,79 @@
import urllib
from bs4 import BeautifulSoup
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:
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
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 get_philosophy(word, max_steps=20):
step_words = [word]
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
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):
return 1 in [c in str for c in set]
def get_philosophy_lower(word, max_steps=20):
step_words = [word]
steps = 0
url = 'https://en.wikipedia.org/wiki/%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
step_words = [word]
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

View File

@ -2,17 +2,19 @@ import duckduckgo
import urllib
from bs4 import BeautifulSoup
def xkcd(query):
res = duckduckgo.get_zci('site:xkcd.com ' + query);
title = "";
try: #ddg returns a url for these searches. i want a title as well
title = BeautifulSoup(urllib.urlopen(res).read(), 'html.parser').title.text
res = duckduckgo.get_zci("site:xkcd.com " + query)
title = ""
try: # ddg returns a url for these searches. i want a title as well
title = BeautifulSoup(urllib.urlopen(res).read(), "html.parser").title.text
except:
pass #just swallow the error. maybe the result wasn't a url or something else bad happened
return [(((title + ' - ') if title else '') + res).encode('ascii', 'ignore')]
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")]
# never mind, blocked by ddg
#def xkcd_links(query):
# def xkcd_links(query):
# url = "https://duckduckgo.com/html/?q=site%3Axkcd.com+" + query.replace(' ', '+')
# soup = BeautifulSoup(urllib.urlopen(url).read(), 'html.parser')
# items = soup.find_all("a", class_="result__a")

View File

@ -11,29 +11,29 @@ import operator
MAX_NODES = 4
logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log"
# logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/chatBesties.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
userData = {} # hash keyed by "user" that contains a hash of mentioned other users with count
nameFix = {
'jumblesal': 'jumblesale',
'hardmath1': 'kc',
'hardmath123': 'kc',
'bendorphan': 'endorphant',
'endorphan': 'endorphant',
'synergian': 'synergiance'
}
"jumblesal": "jumblesale",
"hardmath1": "kc",
"hardmath123": "kc",
"bendorphan": "endorphant",
"endorphan": "endorphant",
"synergian": "synergiance",
}
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:
for line in log:
try:
time, user, message = line.split("\t", 3)
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):
user = nameFix[user]
else:
@ -42,73 +42,105 @@ with open(logfile, "r") as log:
if user not in users:
users.append(user)
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['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:
for line in log:
try:
time, user, message = line.split("\t", 3)
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):
user = nameFix[user]
else:
user = user.lower()
except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse
for word in message.split(' '):
word = re.sub('[^A-Za-z0-9]+', '', word)
if word in users: #SOMEONE MENTIONED SOMEONE
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
userData[user]['data'][word] += 1
else: #This user never mentioned this person before
userData[user]['data'][word] = 1
#give both the target and mentioner a point
else: #This user was never set up
userData[user] = {} #make it a dictionary!
userData[user]['data'] = {}
userData[user]['data'][word] = 1
userData[user]['score'] = 0
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
continue # There are some bad lines in the log file that we'll ignore if we can't parse
for word in message.split(" "):
word = re.sub("[^A-Za-z0-9]+", "", word)
if word in users: # SOMEONE MENTIONED SOMEONE
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
userData[user]["data"][word] += 1
else: # This user never mentioned this person before
userData[user]["data"][word] = 1
# give both the target and mentioner a point
else: # This user was never set up
userData[user] = {} # make it a dictionary!
userData[user]["data"] = {}
userData[user]["data"][word] = 1
userData[user]["score"] = 0
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]['data'] = {}
userData[word]['score'] = 0
userData[word]['id'] = len(d3data['nodes'])
d3data['nodes'].append({"name": word, "group": 1})
userData[user]['score'] += 1
userData[word]['score'] += 1
userData[word]["data"] = {}
userData[word]["score"] = 0
userData[word]["id"] = len(d3data["nodes"])
d3data["nodes"].append({"name": word, "group": 1})
userData[user]["score"] += 1
userData[word]["score"] += 1
d3data['links'] = []
#Now connect all the pople to their stuff
d3data["links"] = []
# Now connect all the pople to their stuff
for user, values in userData.iteritems():
#give the user a 'group' based on their total 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
# give the user a 'group' based on their total 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
for target, score in besties:
try:
print "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 })
print(
"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:
print "! Error when trying to link " + user + " to " + target
print("! Error when trying to link " + user + " to " + target)
continue
if len(values['data']) > MAX_NODES:
print " ...ignoring " + str(len(values['data']) - MAX_NODES) + " more connections from " + user
if len(values["data"]) > MAX_NODES:
print(
" ...ignoring "
+ str(len(values["data"]) - MAX_NODES)
+ " more connections from "
+ user
)
d3Circle = {}
d3Circle['names'] = [''] * len(userData)
d3Circle['matrix'] = [[0] * len(userData)] * len(userData)
d3Circle["names"] = [""] * len(userData)
d3Circle["matrix"] = [[0] * len(userData)] * len(userData)
for user, values in userData.iteritems():
d3Circle['names'][values['id']] = user
for name, score in values['data'].iteritems():
d3Circle['matrix'][values['id']][userData[name]['id']] = score if score > 1 else 0
d3Circle["names"][values["id"]] = user
for name, score in values["data"].iteritems():
d3Circle["matrix"][values["id"]][userData[name]["id"]] = (
score if score > 1 else 0
)
with open(outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(d3data))

View File

@ -6,10 +6,10 @@ import calendar
import shutil
logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log"
# logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/userData.json"
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
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
oneWeek = 7 * 24 * 60 * 60
fiveMinutes = 5 * 60
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 = int(time)
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:
#standardize all times into a single "week"
#time %= oneWeek
#if the user already exists in the list
# standardize all times into a single "week"
# time %= oneWeek
# if the user already exists in the list
if user in userData:
if time < userData[user][-1] + fiveMinutes:
continue #only record times that are at least five minutes apart
userData[user].append(time) #append the new time
else: #if they are new
userData[user] = [time] #create a new list
continue # only record times that are at least five minutes apart
userData[user].append(time) # append the new time
else: # if they are new
userData[user] = [time] # create a new list
with open(outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(userData))
shutil.move(outfile + ".tmp", outfile)

View File

@ -7,22 +7,27 @@ import re
import shutil
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_2016_10.json"
# outfile = "/home/krowbar/logs/chatcloud_2016_10.json"
bannedUsersFile = "/home/krowbar/Code/python/bannedUsers"
bannedWordsFile = "/home/krowbar/Code/python/bannedWords"
wordData = {} # keyed by "word" that contains a count
#we only care about recent chats, let's say for the past sixteen hours
wordData = {} # keyed by "word" that contains a count
# we only care about recent chats, let's say for the past sixteen hours
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 = calendar.timegm(time.strptime("1 Oct 16", "%d %b %y"))
print "Generating word cloud based off words from " + 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
# timeCutoff = calendar.timegm(time.strptime("1 Oct 16", "%d %b %y"))
print(
"Generating word cloud based off words from "
+ 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()
bannedUsers = open(bannedUsersFile).read().splitlines()
@ -32,24 +37,28 @@ with open(logfile, "r") as log:
time, user, message = line.split("\t", 3)
time = int(time)
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:
continue #We don't care what they say
continue # We don't care what they say
if time >= timeCutoff and time <= timeTo:
#print "Processing line from " + user + " at " + str(time)
for word in re.sub('[\'\"\`\/\\;:,.?!*&^\-()<>\{\}|_\[\]0-9]', ' ', message).lower().split():
#changing symbols into spaces instead of stripping them avoids compounded words
# print "Processing line from " + user + " at " + str(time)
for word in (
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:
#print "Rejecting " + word
# print "Rejecting " + word
continue
#if the word already exists in the list
# if the word already exists in the list
if word in wordData:
wordData[word] += 1
else: #if they are new
else: # if they are new
wordData[word] = 1
#print "Added word: " + word
wordData = {i:wordData[i] for i in wordData if wordData[i] >= minOccurance }
if(len(wordData) == 0):
# print "Added word: " + word
wordData = {i: wordData[i] for i in wordData if wordData[i] >= minOccurance}
if len(wordData) == 0:
wordData = {"NOTHING": 1, "INTERESTING": 1, "TODAY": 1}
with open(outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(wordData))

View File

@ -10,27 +10,66 @@ import logging, sys
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
parser = argparse.ArgumentParser(description='Generate word cloud data based off of irc chat logs')
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 = argparse.ArgumentParser(
description="Generate word cloud data based off of irc chat logs"
)
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('-timestart', type=int, help='start time of the word cloud (in epoch time)', default=-1)
parser.add_argument(
"-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('-bannedWordsFile', help='file containing list of banned words', default='/home/krowbar/Code/python/bannedWords')
parser.add_argument(
"-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('-minOccurrence', type=int, help='the minimum occurence of a word to include it in the cloud', default=3)
parser.add_argument(
"-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()
wordData = {} # keyed by "word" that contains a count
#we only care about recent chats, let's say for the past sixteen hours
wordData = {} # keyed by "word" that contains a count
# 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)
#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))
args.timestart = (
args.timestart if args.timestart != -1 else args.timeend - (16 * 60 * 60)
)
# 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()
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 = int(time)
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:
continue #We don't care what they say
continue # We don't care what they say
if time >= args.timestart and time <= args.timeend:
#print "Processing line from " + user + " at " + str(time)
for word in re.sub('[\'\"\`\/\\;:,.?!*&^\-()<>\{\}|_\[\]0-9]', ' ', message).lower().split():
#changing symbols into spaces instead of stripping them avoids compounded words
# print "Processing line from " + user + " at " + str(time)
for word in (
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:
#print "Rejecting " + word
# print "Rejecting " + word
continue
#if the word already exists in the list
# if the word already exists in the list
if word in wordData:
wordData[word] += 1
else: #if they are new
else: # if they are new
wordData[word] = 1
#print "Added word: " + word
wordData = {i:wordData[i] for i in wordData if wordData[i] >= args.minOccurrence }
# print "Added word: " + word
wordData = {i: wordData[i] for i in wordData if wordData[i] >= args.minOccurrence}
if len(wordData) == 0:
wordData = {"NOTHING": 1, "INTERESTING": 1, "TODAY": 1}
if args.outfile == '':
print json.dumps(wordData)
if args.outfile == "":
print(json.dumps(wordData))
else:
with open(args.outfile + ".tmp", "w") as tmpFile:
tmpFile.write(json.dumps(wordData))

View File

@ -6,10 +6,13 @@ import calendar
import shutil
logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log"
# logfile = "/home/jumblesale/Code/irc/log"
outfile = "/home/krowbar/logs/chatStack.json"
chatData = { '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
chatData = {
"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
oneWeek = 7 * 24 * 60 * 60
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
def getAllRegions():
return ['unknown']
return ["unknown"]
# this will provide a way to look up what region a user is from
def getRegion(user):
return 'unknown'
return "unknown"
# populate the hours array with time 1 hour away from each other
startTime = timeCutoff
while startTime < timeNow:
chatData['hours'].append(startTime)
chatData["hours"].append(startTime)
startTime += oneHour
# populate the regions array with blank data for each region
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:
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:
try:
time, user, message = line.split("\t", 3)
time = int(time)
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:
region = getRegion(user)
while time > chatData['hours'][hourIdx] + oneHour: # we are past the current hour idx, move ahead until we find the right idx
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!
while (
time > chatData["hours"][hourIdx] + oneHour
): # we are past the current hour idx, move ahead until we find the right idx
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
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:
tmpFile.write(json.dumps(chatData))

View File

@ -7,25 +7,25 @@ import shutil
import re
logfile = "/home/archangelic/irc/log"
#logfile = "/home/jumblesale/Code/irc/log"
# logfile = "/home/jumblesale/Code/irc/log"
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
#also now happy emotes and sad emotes
userData = {} # 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
rejectRegexp = "http[s]?://|[0-9]{2}[;:][0-9]{2}"
happyRegexp = ":[-]?[])}]"
sadRegexp = ":[-]?[[({]"
nameFix = {
'archangel': 'archangelic',
'jumblesal': 'jumblesale',
'hardmath1': 'kc',
'hardmath123': 'kc',
'bendorphan': 'endorphant',
'endorphan': 'endorphant',
'synergian': 'synergiance'
}
"archangel": "archangelic",
"jumblesal": "jumblesale",
"hardmath1": "kc",
"hardmath123": "kc",
"bendorphan": "endorphant",
"endorphan": "endorphant",
"synergian": "synergiance",
}
with open(logfile, "r") as log:
lastUser = "";
lastUser = ""
currentStreak = 1
for line in log:
try:
@ -36,66 +36,70 @@ with open(logfile, "r") as log:
else:
user = user.lower()
except ValueError:
continue #There are some bad lines in the log file that we'll ignore if we can't parse
continue # There are some bad lines in the log file that we'll ignore if we can't parse
if user in userData:
day = time / 86400 #seconds in a day
if userData[user]['startTime'] == 0:
userData[user]['startTime'] = time
if userData[user]['lastDay'] != day:
userData[user]['daysActive'] += 1
userData[user]['lastDay'] = day
day = time / 86400 # seconds in a day
if userData[user]["startTime"] == 0:
userData[user]["startTime"] = time
if userData[user]["lastDay"] != day:
userData[user]["daysActive"] += 1
userData[user]["lastDay"] = day
if lastUser == user:
currentStreak += 1
if currentStreak > userData[user]['streak']:
userData[user]['streak'] = currentStreak
if currentStreak > userData[user]["streak"]:
userData[user]["streak"] = currentStreak
else:
currentStreak = 1
if 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]['lastMention'] = 0
if 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]["lastMention"] = 0
userData[user]['endTime'] = time
#userData[user]['lastSaid'] = message
userData[user]['lineCount'] += 1
userData[user]['wordCount'] += len(message.split())
userData[user]['charCount'] += len(message)
else: #if they are new
userData[user]["endTime"] = time
# userData[user]['lastSaid'] = message
userData[user]["lineCount"] += 1
userData[user]["wordCount"] += len(message.split())
userData[user]["charCount"] += len(message)
else: # if they are new
userData[user] = {}
userData[user]['startTime'] = time
userData[user]['endTime'] = time
#userData[user]['lastSaid'] = message
userData[user]['lineCount'] = 1
userData[user]['wordCount'] = len(message.split())
userData[user]['charCount'] = len(message)
userData[user]['daysActive'] = 1
userData[user]['lastDay'] = time / 86400
userData[user]['streak'] = 1
userData[user]['mentions'] = 0
userData[user]['lastMention'] = 0
userData[user]['responseTime'] = 0
userData[user]['botUse'] = 0
userData[user]['happyEmotes'] = 0
userData[user]['sadEmotes'] = 0
userData[user]["startTime"] = time
userData[user]["endTime"] = time
# userData[user]['lastSaid'] = message
userData[user]["lineCount"] = 1
userData[user]["wordCount"] = len(message.split())
userData[user]["charCount"] = len(message)
userData[user]["daysActive"] = 1
userData[user]["lastDay"] = time / 86400
userData[user]["streak"] = 1
userData[user]["mentions"] = 0
userData[user]["lastMention"] = 0
userData[user]["responseTime"] = 0
userData[user]["botUse"] = 0
userData[user]["happyEmotes"] = 0
userData[user]["sadEmotes"] = 0
lastUser = user;
if message.rstrip() and message[0] == '!':
userData[user]['botUse'] += 1
lastUser = user
if message.rstrip() and message[0] == "!":
userData[user]["botUse"] += 1
if not re.search(rejectRegexp, message):
if re.search(happyRegexp, message):
userData[user]['happyEmotes'] += 1
userData[user]["happyEmotes"] += 1
if re.search(sadRegexp, message):
userData[user]['sadEmotes'] += 1
userData[user]["sadEmotes"] += 1
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]
if user != name and userData.has_key(name):
userData[name]['mentions'] += 1
if not userData[name]['lastMention']:
userData[name]['lastMention'] = time
userData[name]["mentions"] += 1
if not userData[name]["lastMention"]:
userData[name]["lastMention"] = time
except IndexError:
print '##' + message + '##'
print("##" + message + "##")
continue

View File

@ -1,4 +1,6 @@
import urllib
from bs4 import BeautifulSoup
def get_track():
pass

View File

@ -4,26 +4,45 @@ import random
import sys
import argparse
parser = argparse.ArgumentParser(description='Print some random dictionary words.')
parser.add_argument('-d', dest='dictionary', metavar='DICT',
help='supply a dictionary', default='/usr/share/dict/american-english-large')
parser.add_argument('-c', 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')
parser = argparse.ArgumentParser(description="Print some random dictionary words.")
parser.add_argument(
"-d",
dest="dictionary",
metavar="DICT",
help="supply a dictionary",
default="/usr/share/dict/american-english-large",
)
parser.add_argument(
"-c",
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()
#print args
# print args
with open(args.dictionary, "r") as wordsfile:
words = wordsfile.readlines()
if(args.no_appos):
words[:] = [word for word in words if word.find('\'') == -1]
if(args.no_proper):
if args.no_appos:
words[:] = [word for word in words if word.find("'") == -1]
if args.no_proper:
words[:] = [word for word in words if not word[0].isupper()]
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)]))