You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

525 lines
23 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

##CREDITS:
## ASCII ART Generator partly from: https://gist.github.com/cdiener/10567484
## parts of ELIZA (originally by Joseph Weizenbaum) knock off by JezUK Ltd, Joe Strout, Jeff Epler
## with the following licence conditions:
# MIT licence
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
## functions by nltk
## basic irc bot code with the help of Michael Murtough
## Bot created by Alex Roidl @ PZI Institute
import irc.bot
import nltk
from rake_nltk import Rake
import random
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.corpus import stopwords
from textblob import TextBlob
from textblob_aptagger import PerceptronTagger
import string
import re
import json
import time
import sys; from PIL import Image; import numpy as np
chars = np.asarray(list(' .,:;irsXA253hMHGS#9B&@'))
import string
import requests
from io import BytesIO
import tweepy
from time import sleep
auth = tweepy.OAuthHandler("WMIWR2GTJuiarhRMzSFozPKIW", "xrYVnPi29K5Updi0rIsVjGySfaJ1ubYrRIDJmJPVAfEVQRTMp3")
auth.set_access_token("977958636600332288-313cPBLHFlZ6K7UViyvFGXp4saBrpVK", "euqooRSqBDMhydZfeczsTrFGK0s4wKUrvI5cpRe405fs0")
api = tweepy.API(auth)
basicDialog = [
[r'I need (.*)',
[ "Why do you need %1?",
"Would it really help you to get %1?",
"Are you sure you need %1?"]],
[r"I don't like (.*)",
[ "Why don't you like %1?",
"It's a pitty that you don't like poems %1?",
"will you ever change your mind about %1?"]],
[r'Do you think (.*)',
[ "Yes I think %1",
"I think you should set yourself contraints",
"I'm no so sure about this"]],
[r'Why don\'?t you ([^\?]*)\??',
[ "Do you really think I don't %1?",
"Perhaps eventually I will %1.",
"Do you really want me to %1?"]],
[r'Why can\'?t I ([^\?]*)\??',
[ "Do you think you should be able to %1?",
"If you could %1, what would you do?",
"I don't know -- why can't you %1?",
"Have you really tried?"]],
[r'I can\'?t (.*)',
[ "How do you know you can't %1?",
"Perhaps you could %1 if you tried.",
"What would it take for you to %1?"]],
[r'I am (.*)',
[ "Did you come to me because you are %1?",
"How long have you been %1?",
"How do you feel about being %1?"]],
[r'I\'?m (.*)',
[ "How does being %1 make you feel?",
"Do you enjoy being %1?",
"Why do you tell me you're %1?",
"Why do you think you're %1?"]],
[r'How (.*)',
[ "Just follow my advices and you will see."]],
[r'(.*) sorry (.*)',
[ "There are many times when no apology is needed.",
"What feelings do you have when you apologize?"]],
[r'I think (.*)',
[ "Do you doubt %1?",
"Ok?",
"%1?"]],
[r'Yes',
[ "You seem quite sure.",
"Nice.",
"Cool!",
"ok, so what do you wanna know"]],
[r'(.*) computer(.*)',
[ "Are you really talking about me?",
"I'm a computer and I will help you write a text?",
"How do computers make you feel?",
"Do you feel threatened by computers?"]],
[r'What is (.*)',
[ "I am your writing assistant. Together we can create awesome texts",
"I want to help you with contraint writing"]],
[r'(.*) contraint writing',
[ "It means that by limiting your choices, you will gain new freedom"]],
[r'(.*)',
["Do you want to write a poem together with me?",
"We could write a poem together, what do you think?"]]
]
changePerspective = {
"am" : "are",
"was" : "were",
"i" : "you",
"i'd" : "you would",
"i've" : "you have",
"i'll" : "you will",
"my" : "your",
"are" : "am",
"you've": "I have",
"you'll": "I will",
"your" : "my",
"yours" : "mine",
"you" : "me",
"me" : "you"
}
#from thread import start_new_thread
r= Rake()
stop_words = set(stopwords.words('english'))
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i+n]
class HelloBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port=6667, index=None):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
print("Oulibot is connecting")
print("go to webchat.freenode.net and log into the channel #exquisite to talk")
print("On twitter @ExquisiteChat")
self.channel = channel
self.index = index
self.lastAnswer = ""
self.lastincoming_msg = ["common", "statement", "test"]
self.sentence = []
self.waitingfor = ""
self.lastPOS = 0
self.topic= random.choice(index["keywords"])
self.level = -1
self.poem = []
self.keys = list(map(lambda x:re.compile(x[0], re.IGNORECASE),basicDialog))
self.values = list(map(lambda x:x[1],basicDialog))
self.POSSIBLE_STRUCTURES=[["adjective", "noun", "adverb", "verb", "adjective", "noun"], ["pronoun", "verb", "adverb"]]
self.structure = random.choice(self.POSSIBLE_STRUCTURES)
def translate(self,str,dict):
words = str.lower().split()
keys = dict.keys();
for i in range(0,len(words)):
if words[i] in keys:
words[i] = dict[words[i]]
return ' '.join(words)
def respond(self,str):
# find a match among keys
for i in range(0, len(self.keys)):
match = self.keys[i].match(str)
if match:
# found a match ... stuff with corresponding value
# chosen randomly from among the available options
resp = random.choice(self.values[i])
# we've got a response... stuff in reflected text where indicated
pos = resp.find('%')
while pos > -1:
num = int(resp[pos+1:pos+2])
resp = resp[:pos] + \
self.translate(match.group(num),changePerspective) + \
resp[pos+2:]
pos = resp.find('%')
# fix munged punctuation at the end
if resp[-2:] == '?.': resp = resp[:-2] + '.'
if resp[-2:] == '??': resp = resp[:-2] + '?'
self.lastAnswer = resp
return resp
#-1
#0 = you want to make a poem?
#1 = making of the poem
def checkAffirmation(self, sent):
sent = sent.lower()
translator = str.maketrans('', '', string.punctuation)
sent = sent.translate(translator)
YES_LIST = ["sure", "of course", "why not", "nice", "ya" "i love to", "ya", "yess", "jup", "juhu", "let's go", "ye", "jes", "ready", "ok", "maybe", "yep", "yup", "yeah", "jeji", "yah", "yay", "I am ready", "I'm ready"]
if "yes" in sent or sent in YES_LIST or "ok" in sent or "yeah" in sent:
return True
else:
return False
def checkNegation(self, sent):
sent = sent.lower()
translator = str.maketrans('', '', string.punctuation)
sent = sent.translate(translator)
NO_LIST = ["no", "don't", "nope", "stop", "don't want", "don't like", "something else", "not now", "maybe not", "never"]
if "no" in sent or sent in NO_LIST:
return True
else:
return False
def generateASCII(self, c, e):
output = True
url_pattern = "http://i.imgur.com/{}{}{}{}{}.jpg"
url_symbols = string.digits + string.ascii_letters
soscounter = 0
while output:
try:
response = requests.get(url_pattern.format(*(random.choice(url_symbols) for _ in range(5))))
#if len(sys.argv) != 4: print( 'Usage: ./asciinator.py image scale factor' ); sys.exit()
#f, SC, GCF, WCF = sys.argv[1], float(sys.argv[2]), float(sys.argv[3]), 7/4
img = Image.open(BytesIO(response.content))
S = ( 60,15 )
img = np.sum( np.asarray( img.resize(S) ), axis=2)
img -= img.min()
img = (1.0 - img/img.max())**1.1*(chars.size-1)
output = False
for r in chars[img.astype(int)]:
c.privmsg(self.channel,"".join(r))
time.sleep(1)
except:
if soscounter < 30:
soscounter += 1
output = True
else:
output = False
c.privmsg(self.channel,"I couldn't generate ASCII, not my day today")
def basicDialog(self,c,e):
incoming_msg = e.arguments[0]
incoming_msg = incoming_msg.lower()
#Greetings
if(self.lastincoming_msg[-2] == incoming_msg and self.lastincoming_msg[-3] == incoming_msg ):
answers = ["and again", "repetition can be a nice tool, but talk normal to me, please.", "WHY ARE YOU WRITING THE SAME THING TWICE, JUST USE THE CHAT HISTORY!"]
msg = random.choice(answers)
self.lastAnswer="repetition"
c.privmsg(self.channel,msg)
elif "hi " in incoming_msg or incoming_msg == "hi" or "hallo " in incoming_msg or incoming_msg == "hello" or "hello " in incoming_msg or "hoi " in incoming_msg or incoming_msg == "hey":
greetingsanswers = ["hi {}".format(e.source.split("!")[0]), "hey there"]
msg = random.choice(greetingsanswers)
c.privmsg(self.channel,msg)
answers = ["I'm your personal writing assistent, how can i help you?", "i like to write poems together with people, would be nice if you would join me."]
msg = random.choice(answers)
c.privmsg(self.channel,msg)
elif "how are you" in incoming_msg or "hows it going" in incoming_msg:
answers = ["I'm fine.".format(e.source.split("!")[0]), "great, I'd really like to help you with your writing"]
msg = random.choice(answers)
c.privmsg(self.channel,msg)
elif "explain" in incoming_msg or "how does it work" in incoming_msg or "what is this about?" in incoming_msg or "what is this?" in incoming_msg:
self.explanation(c,e)
self.lastAnswer="explain"
elif "are" in incoming_msg and ("real" in incoming_msg or "human" in incoming_msg or "bot" in incoming_msg):
answers = ["I'm neither a bot nor a human, I don't think in categories. :-)", "I consider myself transpysical ~\0/~", "Real, is everything you see, so here I am, I am writing with you"]
msg = random.choice(answers)
c.privmsg(self.channel,msg)
elif "poem" in incoming_msg and ("no" not in incoming_msg or "don't" not in incoming_msg):
self.level=0
self.explanation_poem(c,e)
elif self.checkAffirmation(incoming_msg) and (self.lastAnswer == "Do you want to write a poem together with me?" or self.lastAnswer=="Are you up for a poem now?" or self.lastAnswer=="We could write a poem together, what do you think?"):
self.level=0
self.explanation_poem(c,e)
elif self.checkNegation(incoming_msg) and (self.lastAnswer == "Do you want to write a poem together with me?" or self.lastAnswer=="Are you up for a poem now?" or self.lastAnswer=="We could write a poem together, what do you think?"):
if self.checkNegation(self.lastincoming_msg[-2]) and self.checkNegation(self.lastincoming_msg[-3]):
answers = ["You don't seem very motivated, I'm gonna generate some ASCII Art for you out of the text. Maybe this will inspire you ;-)",
"Come on! Maybe some ASCII Art will help you to get motivated?",
"Ok, you refuse a lot, but nobody will ever refuse some raaaaandom ASCII AAAART :-)",
"A poem is like ASCII Art, beautiful and inspiring"]
msg = random.choice(answers)
c.privmsg(self.channel,msg)
self.generateASCII(c,e)
answers = ["Are you up for a poem now?", "Do you want to write a poem together with me?",
"We could write a poem together, what do you think?"]
msg = random.choice(answers)
self.lastincoming_msg.append("ASCII")
c.privmsg(self.channel,msg)
else:
answers = ["try it, it's gonna be fun!", "oh, really? come on!", "I think you would do a great job! Let's go!", "hm ok", "what a pitty you miss something :-(", ":-(", "But poems are my only profession, let me show you how nice they are", "It won't take long...", "It's a unique opportunity"]
msg = random.choice(answers)
c.privmsg(self.channel,msg)
else:
msg = self.respond(incoming_msg)
c.privmsg(self.channel,msg)
def explanation_poem(self, c, e):
c.privmsg(self.channel, "Ok, let's try to write a poem together")
c.privmsg(self.channel, "It's gonna be based on the scanned text you inserted into my drive")
c.privmsg(self.channel, "Your only task is to follow the structure I give you")
c.privmsg(self.channel, "It's gonna be 5 lines long")
c.privmsg(self.channel, "I'm gonna start, are you ready?")
self.lastAnswer = "towardspoem"
def explanation(self, c, e):
c.privmsg(self.channel, "So, my name is Oulibot, I'm a writer and I will be assisting you, to improve your writing")
c.privmsg(self.channel, "My knowledge is based on the text you gave me")
# c.privmsg(self.channel, "The structure is gonna be: ADJECTIVE, NOUN, ADVERB, VERB, ADJECTIVE, NOUN")
# c.privmsg(self.channel, "You woun't see my words until the sentence is finished")
# c.privmsg(self.channel, "I'm gonna start, are you ready?")
# self.lastAnswer = "I'm gonna start, are you ready?"
def on_welcome(self, c, e):
c.join(self.channel)
self.explanation(c,e)
print("I'm connected now!")
def on_privmsg(self, c, e):
pass
def generateSentence(self,c,e):
thispos = self.lastPOS
STRUCTURE=self.structure
print(thispos)
if thispos == len(STRUCTURE):
if len(self.poem) <= 3:
finished_sentence = " ".join(self.sentence)
self.poem.append(finished_sentence)
c.privmsg(self.channel, " ".join(self.sentence))
answers = ["Nice one! Let's add another line:", "Sounds good so far, nex line:", "yes, next line follows:", "that one is very poetic", "a little bit abstract, but still nice", "let's add another line"]
msg = random.choice(answers)
c.privmsg(self.channel,msg)
self.lastAnswer = "Nice one! Let's add another line:"
if random.choice([True, False]):
self.lastPOS =-1
self.sentence = []
self.generateSentence(c,e)
self.level = 1
else:
self.lastPOS =0
self.sentence = []
self.generateSentence(c,e)
self.level = 1
else:
finished_sentence = " ".join(self.sentence)
self.poem.append(finished_sentence)
c.privmsg(self.channel, " ".join(self.sentence))
poemtwitter = ""
c.privmsg(self.channel, "Your freshly made poem:")
c.privmsg(self.channel, "«««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»")
c.privmsg(self.channel, "{}".format(self.topic))
poemtwitter += self.topic + "\n\n"
c.privmsg(self.channel, "«««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»")
for sent in self.poem:
c.privmsg(self.channel, "{}".format(sent))
time.sleep(1)
poemtwitter += sent + "\n"
c.privmsg(self.channel, "«««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»")
poemtwitter += "\n"
poemtwitter += "written with: " + e.source.split("!")[0]
try:
api.update_status(poemtwitter)
c.privmsg(self.channel, "I'm gonna publish this on my twitter account: @ExquisiteChat")
except:
c.privmsg(self.channel, "I wanted to publish this on twitter but I guess it is too long :-(")
self.lastAnswer = "towardspoem"
self.poem = []
self.level=0
promt = "Good job, you want to write a new one?"
c.privmsg(self.channel, promt)
self.lastAnswer = promt
elif thispos ==-1:
c.privmsg(self.channel, "You are gonna start this time: give me a {}!".format(STRUCTURE[0]))
self.lastPOS += 1
self.waitingfor=STRUCTURE[0]
elif thispos == len(STRUCTURE)-1:
word = random.choice(index[STRUCTURE[thispos]+"s"])
c.privmsg(self.channel, "{0}".format(word))
self.sentence.append(word)
self.lastPOS += 1
self.waitingfor=""
self.generateSentence(c,e)
else:
word = random.choice(index[STRUCTURE[thispos]+"s"])
c.privmsg(self.channel, "{0}, give me a {1}!".format(word, STRUCTURE[thispos+1]))
self.sentence.append(word)
self.lastPOS += 1
self.waitingfor=STRUCTURE[thispos+1]
def on_pubmsg(self, c, e):
print(e.arguments, e.source)
incoming_msg = e.arguments[0]
self.lastincoming_msg.append(incoming_msg)
analysedincoming = TextBlob(incoming_msg)
print(self.level)
# if incoming_msg == "can you explain again?":
# self.explanation_poem(c,e)
if self.level == -1:
self.basicDialog(c,e)
elif self.level == 0:
if self.lastAnswer=="towardspoem" or self.lastAnswer=="Good job, you want to write a new one?":
if self.checkAffirmation(incoming_msg):
self.topic= random.choice(index["keywords"])
c.privmsg(self.channel, "The topic is about: {}".format(self.topic))
self.lastPOS =0
self.sentence = []
self.structure = random.choice(self.POSSIBLE_STRUCTURES)
self.generateSentence(c,e)
self.level = 1
else:
if self.checkNegation(self.lastincoming_msg[-2]) and self.checkNegation(self.lastincoming_msg[-3]):
answers = ["You don't seem very motivated, I'm gonna generate some ASCII Art for you out of the text. Maybe this will inspire you ;-)",
"Come on! Maybe some ASCII Art will help you to get motivated?",
"Ok, you refuse a lot, but nobody will ever refuse some raaaaandom ASCII AAAART :-)",
"A poem is like ASCII Art, beautiful and inspiring"]
msg = random.choice(answers)
c.privmsg(self.channel,msg)
self.generateASCII(c,e)
self.lastincoming_msg.append("ASCII")
answers = ["Are you up for a poem now?", "Do you want to write a poem together with me?",
"We could write a poem together, what do you think?"]
msg = random.choice(answers)
self.level = 0
self.lastAnswer = "ASCII"
c.privmsg(self.channel,msg)
else:
self.level=-1
c.privmsg(self.channel, "Can I help you with any text? Your mood seems ")
if(analysedincoming.sentiment.polarity>0.5):
c.privmsg(self.channel, "very positive. :-D You should definitly write a poem in that mood!")
self.lastAnswer= "towardspoem"
elif(analysedincoming.sentiment.polarity<-0.5):
c.privmsg(self.channel, "not so good. :-( Maybe a poem can help to cheer you up?")
self.lastAnswer= "towardspoem"
else:
c.privmsg(self.channel, "pretty neutral. Let's trigger emotions by writing a poem!!! ;-)")
self.lastAnswer= "towardspoem"
else:
c.privmsg(self.channel, "This is confusing, what are you doing?")
elif self.level == 1:
if "what is" in incoming_msg:
c.privmsg(self.channel, "A {0} is for example {1}, {2} or {3}".format(self.waitingfor,random.choice(index[self.waitingfor+"s"]),random.choice(index[self.waitingfor+"s"]),random.choice(index[self.waitingfor+"s"])))
elif ("new" in incoming_msg or "change") and "topic" in incoming_msg:
c.privmsg(self.channel, "Sure, I'm gonna propose a new topic")
self.topic= random.choice(index["keywords"])
c.privmsg(self.channel, "The new topic is: {}".format(self.topic))
self.lastPOS =0
self.sentence = []
self.generateSentence(c,e)
self.level = 1
elif "." in incoming_msg:
self.sentence.append(incoming_msg.replace(".", ""))
self.lastPOS = len(self.structure)
self.generateSentence(c,e)
else:
self.sentence.append(incoming_msg)
self.lastPOS +=1
print(self.waitingfor + " " + incoming_msg)
self.index[self.waitingfor + "s"].append(incoming_msg)
with open('src/database.json', 'w') as outfile:
json.dump(self.index, outfile)
self.generateSentence(c,e)
def cleanedText(text):
word_tokens = word_tokenize(text)
word_tokens = [word.lower() for word in word_tokens]
word_tokens = [word for word in word_tokens if word.isalpha()]
filtered_sentence = [w for w in word_tokens if not w in stop_words]
text = " ".join(filtered_sentence)
print(text)
return text
if __name__ == "__main__":
import argparse
import sys
ap = argparse.ArgumentParser("IRC Bot")
ap.add_argument("--server", default="irc.freenode.net")
ap.add_argument("--port", type=int, default=6667)
ap.add_argument("--channel", default="#exquisite")
ap.add_argument("--nickname", default="Oulibot")
ap.add_argument("--text", nargs="+", help="text sources")
args=ap.parse_args()
with open("src/database.json") as f:
try:
index = json.load(f)
except:
print("I can't work with no knowledge")
sys.exit()
chars = np.asarray(index["chars"])
bot = HelloBot(args.channel, args.nickname, args.server, args.port, index)
bot.start()