def send_imessage(telephone): import string import language.grammar import language.questions import environment.system try: # Format phone all_chars = string.maketrans('', '') remove_chars = all_chars.translate(all_chars, string.digits) phone = telephone.translate(all_chars, remove_chars) message = language.questions.ask_for_text("What should I say?") result = environment.system.run_osa_service( 'Messages', """ on run {targetPhone, targetMessage} tell application "Messages" set targetService to 1st service whose service type = iMessage set targetContact to buddy targetPhone of targetService send targetMessage to targetContact end tell end run """, [phone, message]) return "Message successfully sent" except: import alan alan.speak("Something went wrong.") return ("Could not send message")
def contacts_search(search_term, sentence): """ Dispatch: look phone/ email Function to look up via MacOSX address book. Example: "Look up Cameron Taylor's phone" """ import sys import alan import environment.system import language.grammar import language.questions if sys.platform == "darwin": query_string = ' '.join(sentence) alan.speak("Looking up " + query_string) result = environment.system.run_osa_service( 'Contacts', '{} of people where name contains "'.format(search_term) + query_string + '"', []) print result if len(result) > 1: alan.speak("Here are my results for " + query_string) further_action = language.questions.ask_for_text( "Would you like me to message them?") if 'y' in further_action: return send_imessage(result.strip()) else: return "Okay" else: return ("Could not find " + query_string) else: return ("I do not work for non MacBook devices yet.")
def start_teaching(phrase, name): """ Function to teach another alan a given task. Args: phrase (String): The keyword or key phrase that will be used to store the learned task. name (String): The name of the other alan unit that is to be taught. """ import memory.context import memory.store_memories phrase = " ".join([word[0] for word in phrase ]).replace("how to", "").replace("respond to", "").replace("to", "").strip() task = memory.store_memories.recall_memory(phrase) if len(task) == 0: return "I do not know how to respond to " + phrase + " so I can not teach " + name print phrase fetched_memory = memory.store_memories.recall_memory(phrase) # Wake up other alan unit. get_response("yes", name) command = "learn how to {}".format(phrase) success = get_response("do", command) if success: get_response("yes", name) get_response("correct", fetched_memory[0][1]) get_response("yes", name) get_response("that", "yes") get_response("yes", name) get_response("remember", "yes") get_response("yes", name) alan.speak("yes") return ""
def send_imessage(telephone): import string import language.grammar import language.questions import environment.system try: # Format phone all_chars = string.maketrans('','') remove_chars = all_chars.translate(all_chars, string.digits) phone = telephone.translate(all_chars, remove_chars) message = language.questions.ask_for_text("What should I say?") result = environment.system.run_osa_service('Messages', """ on run {targetPhone, targetMessage} tell application "Messages" set targetService to 1st service whose service type = iMessage set targetContact to buddy targetPhone of targetService send targetMessage to targetContact end tell end run """, [phone, message]) return "Message successfully sent" except: import alan alan.speak("Something went wrong.") return ("Could not send message")
def contacts_search(search_term, sentence): """ Dispatch: look phone/ email Function to look up via MacOSX address book. Example: "Look up Cameron Taylor's phone" """ import sys import alan import environment.system import language.grammar import language.questions if sys.platform == "darwin": query_string = ' '.join(sentence) alan.speak("Looking up " + query_string) result = environment.system.run_osa_service('Contacts', '{} of people where name contains "'.format(search_term) + query_string + '"', []) print result if len(result) > 1: alan.speak("Here are my results for " + query_string) further_action = language.questions.ask_for_text("Would you like me to message them?") if 'y' in further_action: return send_imessage(result.strip()) else: return "Okay" else: return ("Could not find " + query_string) else: return("I do not work for non MacBook devices yet.")
def start_teaching(phrase, name): """ Function to teach another alan a given task. Args: phrase (String): The keyword or key phrase that will be used to store the learned task. name (String): The name of the other alan unit that is to be taught. """ import memory.context import memory.store_memories phrase = " ".join([word[0] for word in phrase]).replace("how to", "").replace("respond to", "").replace("to", "").strip() task = memory.store_memories.recall_memory(phrase) if len(task) == 0: return "I do not know how to respond to " + phrase + " so I can not teach " + name print phrase fetched_memory = memory.store_memories.recall_memory(phrase) # Wake up other alan unit. get_response("yes", name) command = "learn how to {}".format(phrase) success = get_response("do", command) if success: get_response("yes", name) get_response("correct", fetched_memory[0][1]) get_response("yes", name) get_response("that", "yes") get_response("yes", name) get_response("remember", "yes") get_response("yes", name) alan.speak("yes") return ""
def start_learning(sentence): """ Function to parse a given sentence into python and run through alan.think() """ import language.questions import memory.store_memories task = " ".join([word[0] for word in sentence if word[0].lower() != "learn" and word[0] != "how" and word[0] != "to"]) alan_response = "How do I " if "respond" in task: alan_response += "respond to" task = task.replace("respond", "") indentation = 0 alan.speak(alan_response + task) instructions = language.questions.ask_for_long_text() lines = newline_characterization(instructions) keyphrase_lines = replace_keyphrases(lines) blocked_lines = create_blocks(keyphrase_lines) code_string, dependencies = get_dependencies(blocked_lines) for dependency in dependencies: if dependency not in defined_variables: code_string = dependency + " = " + "alan.listen()\n" + code_string code_string = "alan.speak(\"What is " + dependency.replace("_", " ") + "?\")\n" + code_string code_string = "import alan\n" + code_string alan.speak("I'll try to do that now.") code_string = substitute_variables(code_string) print code_string try: exec (code_string) should_remember = language.questions.binary_question("Should I remember how to do this?") if should_remember: memory.store_memories.store_task(task.strip(), instructions, code_string) return "Learned to " + task return "I will not remember how to do that" except: return "I failed to learn the task"
def remember(sentence): """ Dispatch: remember Function to remember something in short term. Key value storage dict. """ import alan import memory.context memory = memory.context.short_term_memory concept_key = " ".join([word[0] for word in sentence if 'N' in word[1]]) alan.speak("Tell me what you want me to remember.") concept_value = alan.listen() memory.remember_concept(concept_key, concept_value) return "I will remember that as '" + concept_key + "'"
def read_reddit(sentence): """ Dispatch: read Function to read reddit. Example: "Read the physics subreddit" """ import praw from alan import speak sentence.pop(0) subreddit = "".join([word[0] for word in sentence if 'the' not in word[0].lower() and 'subreddit' not in word[0]]) speak("Reading the " + subreddit + " subreddit.") r = praw.Reddit(user_agent='Alan ai experiment') submissions = r.get_subreddit(subreddit).get_hot(limit=10) return " \n".join([str(index + 1)+ " " + submission.title + "." for index, submission in enumerate(submissions)])
def attach_notification_listener(plugin): """ When a plugin calls :release: the notification listener reads the plugin stdout for :notify: command. Args: plugin (subprocess.Popen): The plugin that the notification listener is attached to. """ while True: line = plugin.stdout.readline() if line != '': if ":notify:" in line: alan.speak(line.replace(":notify:", "")) else: break
def attach_notification_listener(plugin): """ When a plugin calls :release: the notification listener reads the plugin stdout for :notify: command. Args: plugin (subprocess.Popen): The plugin that the notification listener is attached to. """ while True: line = plugin.stdout.readline() if line != '': if ":notify:" in line: alan.speak(line.replace(":notify:", "")) else: break
def play_music(sentence): """ Dispatch: play Function to play music. Requires pianobar which is a Pandora from the terminal. Also you must set up config file in .config/pianobar/config if you don't want to log on. Example: "Play me some music." """ import alan import environment.system # TODO check for config file and add one if not present. alan.speak("Playing music from pandora") environment.system.run_service("pianobar") import time time.sleep(10) alan.listen()
def get_response(desired_response, prompt): import memory.context import senses max_tries = 2 tries = 0 response = "" memory.context.no_prompt = True while desired_response not in response or tries == max_tries: alan.speak(prompt) response = senses.ears.ears() tries = tries + 1 memory.context.no_prompt = False if tries == 2: return False else: return True
def get_response(desired_response, prompt): import memory.context import senses max_tries = 2 tries = 0 response = "" memory.context.no_prompt = True while desired_response not in response or tries == max_tries: alan.speak(prompt) response = senses.ears.ears() tries = tries + 1 memory.context.no_prompt = False if tries == 2: return False else: return True
def binary_question(question): """ Function to help with yes or no questions. Needs to include more options than yes or no (ya, nope, sure etc.) Args: question (String): the question you are trying to ask. Returns: bool : returns True for yes and False for no """ alan.speak(question) answer = alan.listen() if "yes" in answer: return True elif "no" in answer: return False else: alan.speak("I was expecting a yes or no answer but you said " + answer)
def start_learning(sentence): """ Function to parse a given sentence into python and run through alan.think() """ import language.questions import memory.store_memories task = " ".join([ word[0] for word in sentence if word[0].lower() != "learn" and word[0] != "how" and word[0] != "to" ]) alan_response = "How do I " if "respond" in task: alan_response += "respond to" task = task.replace("respond", "") indentation = 0 alan.speak(alan_response + task) instructions = language.questions.ask_for_long_text() lines = newline_characterization(instructions) keyphrase_lines = replace_keyphrases(lines) blocked_lines = create_blocks(keyphrase_lines) code_string, dependencies = get_dependencies(blocked_lines) for dependency in dependencies: if dependency not in defined_variables: code_string = dependency + " = " + "alan.listen()\n" + code_string code_string = "alan.speak(\"What is " + dependency.replace( "_", " ") + "?\")\n" + code_string code_string = "import alan\n" + code_string alan.speak("I'll try to do that now.") code_string = substitute_variables(code_string) print code_string try: exec(code_string) should_remember = language.questions.binary_question( "Should I remember how to do this?") if should_remember: memory.store_memories.store_task(task.strip(), instructions, code_string) return "Learned to " + task return "I will not remember how to do that" except: return "I failed to learn the task"
def interpret(plugin): """ Function that interprets plugin data from stdin and writes to stdout. Args: plugin (subprocess.Popen object): The process running the plugin. Returns: (String) : status of the plugin # TODO I remember reading that stdin.write() and stdout.readline() is not ideal so they might need to be replaced. """ #TODO should be migrated to a class. Also it will eventually handle many commands other than :speak: and :listen: while True: line = plugin.stdout.readline() if line != '': if ':listen:' in line: try: plugin.stdin.write(str(alan.listen()) + "\n") except: return "Exiting plugin" if ':speak:' in line: line = line.replace(":speak:", "") line = line.replace(":listen:", "") alan.speak(line) if ':release:' in line: # The plugin goes into background mode and spawns a notification_listener thread. background_listener = threading.Thread( target=attach_notification_listener, args=[plugin]) background_listener.start() return "Plugin is now running in the background." else: print line.rstrip() else: break return "Finished running plugin."
def ask_for_long_text(): """ Function to get a longer amount of text. Runs until user says they have completed the input text. """ from memory import context done = False text_block = current_block = "" while not done: if text_block is not "" and current_block is "": done = binary_question("Is that all?") if not done: alan.speak("Please continue") else: context.no_prompt = False return text_block answer = alan.listen() current_block = (text_block + " " + answer) alan.speak("Here is what I have: " + current_block) end_block_command = binary_question("Is this correct?") if not end_block_command: # Do not save text block, redo alan.speak("Ok, let's try that again.") else: # Append to final text block current_block = "" text_block = (text_block + " " + answer)
def send_email(sentence): """ Dispatch: send Function to send an email. Example: "Send an email." """ import smtplib from email.mime.text import MIMEText as text import alan import language.questions try: # Send the mail. alan.speak("I'm preparing to send an email.") server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() # TODO add alan's email and password here email = language.questions.ask_for_email("What is the sender email?") alan.speak("What is your password") password = alan.listen() server.login(email, password) recipient = language.questions.ask_for_email("What is the recipient email?") message = language.questions.ask_for_text("What is the message?") mime_message = text(message) mime_message['Subject'] = language.questions.ask_for_text("What is the subject?") server.sendmail(email, recipient, mime_message.as_string()) server.quit() return "Email sent." except: alan.speak("Something went wrong.") if "gmail" in email: return "Try allowing less secure apps in your gmail settings." else: return "I can't seem to send email right now."
def interpret(plugin): """ Function that interprets plugin data from stdin and writes to stdout. Args: plugin (subprocess.Popen object): The process running the plugin. Returns: (String) : status of the plugin # TODO I remember reading that stdin.write() and stdout.readline() is not ideal so they might need to be replaced. """ #TODO should be migrated to a class. Also it will eventually handle many commands other than :speak: and :listen: while True: line = plugin.stdout.readline() if line != '': if ':listen:' in line: try: plugin.stdin.write(str(alan.listen()) + "\n") except: return "Exiting plugin" if ':speak:' in line: line = line.replace(":speak:", "") line = line.replace(":listen:", "") alan.speak(line) if ':release:' in line: # The plugin goes into background mode and spawns a notification_listener thread. background_listener = threading.Thread(target=attach_notification_listener, args=[plugin]) background_listener.start() return "Plugin is now running in the background." else: print line.rstrip() else: break return "Finished running plugin."
def ask_for_text(question): """ Function to get a short amount of text. The user can only input one installment. If you need more text use ask_for_long_text """ confirmed = False while not confirmed: alan.speak(question) answer = alan.listen() alan.speak("I have heard that as " + answer) confirmed = binary_question("Is that correct?") if not confirmed: alan.speak("Ok, let's try that again.") return answer
def ask_for_email(question): """ Function to help with obtaining an email address. Args: question (String): the question you are trying to ask. Returns: String : the email address gained from the user """ confirmed = False while not confirmed: alan.speak(question) answer = alan.listen() email = answer.replace(" at ", "@").replace(" ", "") to_lower = binary_question("Are all of the letters in your email lower case?") if to_lower: email = email.lower() alan.speak("I have heard your email address as " + email) confirmed = binary_question("Is that correct?") if not confirmed: alan.speak("Ok, let's try that again. If you haven't already try spelling it out for me.") return email