##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 "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 "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()