From 15297f6c9d57e155a0f40080dc5aee76c3945574 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 26 Mar 2018 23:13:22 +0200 Subject: [PATCH] added credits --- src/oulibot.py | 558 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 558 insertions(+) create mode 100644 src/oulibot.py diff --git a/src/oulibot.py b/src/oulibot.py new file mode 100644 index 0000000..b0ba69f --- /dev/null +++ b/src/oulibot.py @@ -0,0 +1,558 @@ +##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 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'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) + self.channel = channel + self.index = index + self.lastAnswer = "" + self.lastincoming_msg = ["common", "statement"] + 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", "noun"]] + 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): + 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) + 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) + c.privmsg(self.channel,"I'm your personal writing assistent, how can i help you?") + elif "how are you" in incoming_msg or "how’s 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 "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: + 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]): + 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) + 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!"] + 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, "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) + + 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)) + c.privmsg(self.channel, "Nice one! Let's add another line:") + 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 = "Finished poem" + 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[1] + 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) + +# 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]): + 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?"] + msg = random.choice(answers) + c.privmsg(self.channel,msg) + level=-1 + else: + 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 + 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() + + # build the index + index = {} + + nouns = [] + verbs = [] + adverbs = [] + pronouns = ["I", "you", "we", "they"] + adjectives = [] + keywords = [] + keywordspersentence = {} + alltext = "" + allcharacters = [] + + n = "ocr/output.txt" + text = open(n).read() + rawtext = text.replace("\n", " ") + #get pos + for letter in list(rawtext): + if letter not in allcharacters and not letter.isalpha(): + allcharacters.append(letter) + + alltext += rawtext + text = cleanedText(text) + thistext = TextBlob(text) + words = word_tokenize(text) + listWithPos = nltk.pos_tag(words) + print(thistext.tags) + for key, tag in thistext.tags: + if(tag == "VBP"): + verbs.append(key) + if(tag == "NN" or tag == "NNS"): + nouns.append(key) + if(tag == "RB"): + adverbs.append(key) + if(tag == "JJ"): + adjectives.append(key) + + print("Verbs: {}".format(verbs)) + print("Nouns: {}".format(nouns)) + print("Adverbs: {}".format(adverbs)) + print("Adjectives: {}".format(adjectives)) + #keywords + r.extract_keywords_from_text(rawtext) + phrases = r.get_ranked_phrases_with_scores() + for key, phrase in phrases: + if key > 2: + keywords.append(phrase) + + print("Keywords: {}".format(keywords)) + + # keywordsofsentences + sentences = sent_tokenize(text) + for sentence in sentences: + + r.extract_keywords_from_text(sentence) + keys = r.get_ranked_phrases() + for key in keys: + if key not in keywordspersentence: + keywordspersentence[key] = [] + keywordspersentence[key].append({'filename': n, 'sentence': sentence, 'key': key}) + + print(allcharacters) + index["nouns"]=nouns + index["verbs"]=verbs + index["pronouns"]=pronouns + index["adverbs"]=adverbs + index["adjectives"]=adjectives + index["keywords"]=keywords + index["keywordspersentence"]=keywordspersentence + index["rawtext"]=alltext + chars = np.asarray(allcharacters) + + bot = HelloBot(args.channel, args.nickname, args.server, args.port, index) + bot.start()