def compare_image(self, com, userin, user_prefix): """Method to dragonfire's command structures of Searching on Browser ability. Args: com (str): User's command. userin: :class:`dragonfire.utilities.TextToAction` instance. Keyword Args: user_prefix: user's preferred titles. """ doc = nlp(com) h = Helper(doc) if (h.check_lemma("search") or h.check_lemma("find")) and ( h.check_lemma("google") or h.check_lemma("web") or h.check_lemma("internet")) and h.check_lemma("image"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "google" or token.lemma_ == "web" or token.lemma_ == "internet" or token.lemma_ == "image" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: tab_url = "http://google.com/?#q=" + search_query + "&tbm=isch" return userin.execute(["sensible-browser", tab_url], search_query, True) return None
def compare(self, com, args, testing, userin, user_prefix): """Method to dragonfire's command structures of searching in youtube ability. Args: com (str): User's command. userin: :class:`dragonfire.utilities.TextToAction` instance. args: Command-line arguments. Keyword Args: user_prefix: user's preferred titles. """ self.testing = testing doc = nlp(com) h = Helper(doc) if (h.check_lemma("search") or h.check_lemma("find")) and h.check_lemma("youtube"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "youtube" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: info = youtube_dl.YoutubeDL({}).extract_info( 'ytsearch:' + search_query, download=False, ie_key='YoutubeSearch') if len(info['entries']) > 0: youtube_title = info['entries'][0]['title'] youtube_url = "https://www.youtube.com/watch?v=%s" % ( info['entries'][0]['id']) userin.execute(["sensible-browser", youtube_url], youtube_title) youtube_title = "".join([ i if ord(i) < 128 else ' ' for i in youtube_title ]) response = userin.say( youtube_title, ["sensible-browser", youtube_url]) else: youtube_title = "No video found, " + user_prefix + "." response = userin.say(youtube_title) k = PyKeyboard() if not args["server"] and not self.testing: time.sleep(5) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key('f') return response return None
def press_browser_history_nav(self, direction): """Presses the keys according to the navigation browser in history intent. Args: direction (str): 'back' or 'forward'. Returns: str: 'back' or 'forward'. """ with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: if direction == "back": k.press_keys([k.alt_l_key, k.left_key]) elif direction == "forward": k.press_keys([k.alt_l_key, k.right_key]) else: pass return direction
def command(self, com): """Function that serves as the entry point for each one of the user commands. This function goes through these steps for each one of user's commands, respectively: - Search across the built-in commands via a simple if-else control flow. - Try to get a response from :func:`dragonfire.arithmetic.arithmetic_parse` function. - Try to get a response from :func:`dragonfire.learn.Learner.respond` method. - Try to get a answer from :func:`dragonfire.odqa.ODQA.respond` method. - Try to get a response from :func:`dragonfire.deepconv.DeepConversation.respond` method. Args: com (str): User's command. Returns: str: Response. """ if not self.args["server"]: global config_file global e if (e.is_set()): # System Tray Icon exit must trigger this exit(0) args = self.args userin = self.userin user_full_name = self.user_full_name user_prefix = self.user_prefix if self.testing: config_file = self.config_file if isinstance(com, str) and com: com = com.strip() else: return False print("You: " + com.upper()) doc = nlp(com) h = Helper(doc) self.h = h if args["verbose"]: userin.pretty_print_nlp_parsing_results(doc) # Input: DRAGONFIRE | WAKE UP | HEY if self.inactive and not self.check_wake_up_intent: return "" # User is answering to Dragonfire if user_answering['status']: if com.startswith("FIRST") or com.startswith( "THE FIRST") or com.startswith("SECOND") or com.startswith( "THE SECOND") or com.startswith( "THIRD") or com.startswith("THE THIRD"): user_answering['status'] = False selection = None if com.startswith("FIRST") or com.startswith("THE FIRST"): selection = 0 elif com.startswith("SECOND") or com.startswith("THE SECOND"): selection = 1 elif com.startswith("THIRD") or com.startswith("THE THIRD"): selection = 2 if user_answering['for'] == 'wikipedia': with nostderr(): search_query = user_answering['options'][selection] try: return self.wikisearch(search_query) except requests.exceptions.ConnectionError: return self.wikipedia_connection_error() except WikipediaNoResultsFoundError: return self.wikipedia_no_results_found_error( search_query) except Exception: return False # Input: DRAGONFIRE | WAKE UP | HEY if self.check_wake_up_intent(): self.inactive = False return userin.say( choice([ "Yes, " + user_prefix + ".", "Yes. I'm waiting.", "What is your order?", "Ready for the orders!", user_prefix.capitalize() + ", tell me your wish." ])) # Input: GO TO SLEEP if (h.check_verb_lemma("go") and h.check_noun_lemma("sleep")) or ( h.check_verb_lemma("stop") and h.check_verb_lemma("listen")): self.inactive = True userin.execute([ "echo" ], "Dragonfire deactivated. To reactivate say 'Dragonfire!' or 'Wake Up!'" ) return userin.say("I'm going to sleep") # Input: ENOUGH | SHUT UP if h.directly_equal(["enough"]) or (h.check_verb_lemma("shut") and h.check_nth_lemma(-1, "up")): tts_kill() msg = "Dragonfire quiets." print(msg) return msg # Input: WHAT IS YOUR NAME if h.check_wh_lemma("what") and h.check_deps_contains("your name"): return userin.execute([" "], "My name is Dragonfire.", True) # Input: WHAT IS YOUR GENDER if h.check_wh_lemma("what") and h.check_deps_contains("your gender"): return userin.say( "I have a female voice but I don't have a gender identity. I'm a computer program, " + user_prefix + ".") # Input: WHO AM I | SAY MY NAME if (h.check_wh_lemma("who") and h.check_text("I")) or (h.check_verb_lemma("say") and h.check_text("my") and h.check_lemma("name")): userin.execute([" "], user_full_name) return userin.say("Your name is " + user_full_name + ", " + user_prefix + ".") # Input: OPEN [CAMERA, CALENDAR, CALCULATOR, STEAM, BLENDER, WRITER, MATH, IMPRESS, DRAW, TERMINAL] if h.check_verb_lemma("open") or h.check_adj_lemma( "open") or h.check_verb_lemma("run") or h.check_verb_lemma( "start") or h.check_verb_lemma("show"): if h.check_text("blender"): userin.execute(["blender"], "Blender") return userin.say("Blender 3D computer graphics software") if h.check_text("draw"): userin.execute(["libreoffice", "--draw"], "LibreOffice Draw") return userin.say("Opening LibreOffice Draw") if h.check_text("impress"): userin.execute(["libreoffice", "--impress"], "LibreOffice Impress") return userin.say("Opening LibreOffice Impress") if h.check_text("math"): userin.execute(["libreoffice", "--math"], "LibreOffice Math") return userin.say("Opening LibreOffice Math") if h.check_text("writer"): userin.execute(["libreoffice", "--writer"], "LibreOffice Writer") return userin.say("Opening LibreOffice Writer") if h.check_noun_lemma("browser") or h.check_text( "chrome") or h.check_text("firefox"): userin.execute(["sensible-browser"], "Web Browser") return userin.say("Web browser") if h.check_text("steam"): userin.execute(["steam"], "Steam") return userin.say("Opening Steam Game Store") if h.check_text("files"): return self.start_file_manager() if h.check_noun_lemma("camera"): userin.execute(["kamoso"], "Camera") # KDE neon userin.execute(["snap-photobooth"], "Camera") # elementary OS userin.execute(["cheese"], "Camera") # Ubuntu return userin.say("Camera") if h.check_noun_lemma("calendar"): userin.execute(["korganizer"], "Calendar") # KDE neon userin.execute(["maya-calendar"], "Calendar") # elementary OS userin.execute(["orage"], "Calendar") # Ubuntu return userin.say("Calendar") if h.check_noun_lemma("calculator"): userin.execute(["kcalc"], "Calculator") # KDE neon userin.execute(["pantheon-calculator"], "Calculator") # elementary OS userin.execute(["gnome-calculator"], "Calculator") # Ubuntu return userin.say("Calculator") if h.check_noun_lemma("console") or h.check_noun_lemma("terminal"): userin.execute(["konsole"], "Terminal") # KDE neon userin.execute(["gnome-terminal"], "Terminal") # elementary OS & Ubuntu userin.execute(["guake"], "Terminal") # Guake return userin.say("Terminal") # Input FILE MANAGER | FILE EXPLORER if h.check_noun_lemma("file") and (h.check_noun_lemma("manager") or h.check_noun_lemma("explorer")): return self.start_file_manager() # Input: SOFTWARE CENTER if h.check_noun_lemma("software") and h.check_text("center"): userin.execute(["plasma-discover"], "Software Center") # KDE neon userin.execute(["software-center"], "Software Center") # elementary OS & Ubuntu return userin.say("Software Center") # Input: OFFICE SUITE if h.check_noun_lemma("office") and h.check_noun_lemma("suite"): userin.execute(["libreoffice"], "LibreOffice") return userin.say("Opening LibreOffice") # Input: GIMP | PHOTOSHOP | PHOTO EDITOR if h.check_text("gimp") or (h.check_noun_lemma("photo") and (h.check_noun_lemma("editor") or h.check_noun_lemma("shop"))): userin.execute(["gimp"], "GIMP") return userin.say("Opening the photo editor software.") # Input: INKSCAPE | VECTOR GRAPHICS if h.check_text("inkscape") or (h.check_noun_lemma("vector") and h.check_noun_lemma("graphic")) or ( h.check_text("vectorial") and h.check_text("drawing")): userin.execute(["inkscape"], "Inkscape") return userin.say("Opening the vectorial drawing software.") # Input: Kdenlive | VIDEO EDITOR if h.check_text("kdenlive") or (h.check_noun_lemma("video") and h.check_noun_lemma("editor")): userin.execute(["kdenlive"], "Kdenlive") return userin.say("Opening the video editor software.") # Input: MY TITLE IS LADY | I'M A LADY | I'M A WOMAN | I'M A GIRL if h.check_lemma("be") and h.check_lemma( "-PRON-") and h.check_gender_lemmas('female'): return self.gender_update('female') # Input: MY TITLE IS SIR | I'M A MAN | I'M A BOY if h.check_lemma("be") and h.check_lemma( "-PRON-") and h.check_gender_lemmas('male'): return self.gender_update('male') # Input: CALL ME * if h.check_lemma("call") and h.check_lemma("-PRON-"): title = "" for token in doc: if token.pos_ == "NOUN": title += ' ' + token.text title = title.strip() if not args["server"]: callme_config = config_file.search( Query().datatype == 'callme') if callme_config: config_file.update({'title': title}, Query().datatype == 'callme') else: config_file.insert({'datatype': 'callme', 'title': title}) self.user_prefix = title user_prefix = self.user_prefix return userin.say("OK, " + user_prefix + ".") # Input: WHAT'S THE TEMPERATURE IN * if h.is_wh_question() and h.check_lemma("temperature"): city = "" for ent in doc.ents: if ent.label_ == "GPE": city += ' ' + ent.text city = city.strip() if city: owm = pyowm.OWM("16d66c84e82424f0f8e62c3e3b27b574") reg = owm.city_id_registry() try: weather = owm.weather_at_id( reg.ids_for(city)[0][0]).get_weather() fmt = "The temperature in {} is {} degrees celsius" msg = fmt.format( city, weather.get_temperature('celsius')['temp']) userin.execute([" "], msg) return userin.say(msg) except IndexError: msg = "Sorry, " + user_prefix + " but I couldn't find a city named " + city + " on the internet." userin.execute([" "], msg) return userin.say(msg) # Input: WHAT TIME IS IT if h.check_wh_lemma("what") and h.check_noun_lemma( "time") and h.check_verb_lemma("be") and h.check_text("it"): return userin.say("It's " + datetime.datetime.now().strftime("%I:%M %p") + choice([", " + user_prefix + ".", "."])) # Input: KEYBOARD * if (h.check_nth_lemma(0, "keyboard") or h.check_nth_lemma(0, "type")) and not args["server"]: n = len(doc[0].text) + 1 with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: for character in com[n:]: k.tap_key(character) k.tap_key(" ") return "keyboard" # Input: ENTER | NEW TAB | SWITCH TAB | CLOSE | GO BACK | GO FORWARD if (h.directly_equal(["enter"]) or (h.check_adj_lemma("new") and h.check_noun_lemma("line"))) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(k.enter_key) return "enter" if h.check_adj_lemma("new") and h.check_noun_lemma( "tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 't']) return "new tab" if h.check_verb_lemma("switch") and h.check_noun_lemma( "tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, k.tab_key]) return "switch tab" if h.directly_equal(["CLOSE", "ESCAPE"]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 'w']) k.tap_key(k.escape_key) return "close" if self.check_browser_history_nav_intent("back"): return self.press_browser_history_nav("back") if self.check_browser_history_nav_intent("forward"): return self.press_browser_history_nav("forward") # Input: SCROLL LEFT | SCROLL RIGHT | SCROLL UP | SCROLL DOWN if (h.check_text("swipe") or h.check_text("scroll")) and not args["server"]: if h.check_text("left"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, -5) return "swipe left" if h.check_text("right"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, 5) return "swipe right" if h.check_text("up"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(5, 0) return "swipe up" if h.check_text("down"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(-5, 0) return "swipe down" # Input: PLAY | PAUSE | SPACEBAR if h.directly_equal(["PLAY", "PAUSE", "SPACEBAR" ]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(" ") return "play" # Input: SHUT DOWN THE COMPUTER if ((h.check_text("shut") and h.check_text("down")) or (h.check_text("power") and h.check_text("off")) ) and h.check_text("computer") and not args["server"]: return userin.execute(["sudo", "poweroff"], "Shutting down", True, 3) # Input: GOODBYE | BYE BYE | SEE YOU LATER if h.check_nth_lemma(0, "goodbye") or h.check_nth_lemma( 0, "bye") or (h.check_verb_lemma("see") and h.check_text("you") and h.check_adv_lemma("later")): response = userin.say("Goodbye, " + user_prefix) if not args["server"] and not self.testing: # raise KeyboardInterrupt thread.interrupt_main() return response # Input: (SEARCH|FIND) * (IN|ON|AT|USING) WIKIPEDIA if (h.check_lemma("search") or h.check_lemma("find")) and h.check_lemma("Wikipedia"): with nostderr(): search_query = self.strip_the_search_query_by_intent( doc, "Wikipedia") if search_query: try: return self.wikisearch(search_query) except requests.exceptions.ConnectionError: return self.wikipedia_connection_error() except wikipedia.exceptions.DisambiguationError as disambiguation: user_answering['status'] = True user_answering['for'] = 'wikipedia' user_answering['reason'] = 'disambiguation' user_answering['options'] = disambiguation.options[:3] notify = "Wikipedia disambiguation. Which one of these you meant?:\n - " + disambiguation.options[ 0] msg = user_prefix + ", there is a disambiguation. Which one of these you meant? " + disambiguation.options[ 0] for option in disambiguation.options[1:3]: msg += ", or " + option notify += "\n - " + option notify += '\nSay, for example: "THE FIRST ONE" to choose.' userin.execute([" "], notify) return userin.say(msg) except WikipediaNoResultsFoundError: return self.wikipedia_no_results_found_error( search_query) except Exception: pass # Input: (SEARCH|FIND) * (IN|ON|AT|USING) YOUTUBE if (h.check_lemma("search") or h.check_lemma("find")) and h.check_lemma("YouTube"): with nostdout(): with nostderr(): search_query = self.strip_the_search_query_by_intent( doc, "YouTube") if search_query: info = youtube_dl.YoutubeDL({}).extract_info( 'ytsearch:' + search_query, download=False, ie_key='YoutubeSearch') if len(info['entries']) > 0: youtube_title = info['entries'][0]['title'] youtube_url = "https://www.youtube.com/watch?v=%s" % ( info['entries'][0]['id']) userin.execute(["sensible-browser", youtube_url], youtube_title) youtube_title = TextToAction.fix_the_encoding_in_text_for_tts( youtube_title) response = userin.say( youtube_title, ["sensible-browser", youtube_url]) else: youtube_title = "No video found, " + user_prefix + "." response = userin.say(youtube_title) k = PyKeyboard() if not args["server"] and not self.testing: time.sleep(5) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key('f') return response # Input: (SEARCH|FIND) * (IN|ON|AT|USING) (GOOGLE|WEB) if (h.check_lemma("search") or h.check_lemma("find")) and ( h.check_lemma("Google") or h.check_lemma("web") or h.check_lemma("internet")) and not h.check_lemma("image"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "Google" or token.lemma_ == "web" or token.lemma_ == "internet" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: tab_url = "http://google.com/?#q=" + search_query return userin.execute(["sensible-browser", tab_url], search_query, True) # Input: (SEARCH IMAGES OF|FIND IMAGES OF|SEARCH|FIND) * (IN|ON|AT|USING) (GOOGLE|WEB|GOOGLE IMAGES|WEB IMAGES) if (h.check_lemma("search") or h.check_lemma("find")) and ( h.check_lemma("Google") or h.check_lemma("web") or h.check_lemma("internet")) and h.check_lemma("image"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "Google" or token.lemma_ == "web" or token.lemma_ == "internet" or token.lemma_ == "image" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: tab_url = "http://google.com/?#q=" + search_query + "&tbm=isch" return userin.execute(["sensible-browser", tab_url], search_query, True) original_com = com com = coref.resolve(com) if args["verbose"]: print("After Coref Resolution: " + com) arithmetic_response = arithmetic_parse(com) if arithmetic_response: return userin.say(arithmetic_response) else: learner_response = learner.respond(com) if learner_response: return userin.say(learner_response) else: odqa_response = odqa.respond(com, not args["silent"], userin, user_prefix, args["server"]) if odqa_response: return userin.say(odqa_response) else: dc_response = dc.respond(original_com, user_prefix) if dc_response: return userin.say(dc_response)
def command(self, com): """Function that serves as the entry point for each one of the user commands. This function goes through these steps for each one of user's commands, respectively: - Search across the built-in commands via a simple if-else control flow. - Try to get a response from :func:`dragonfire.arithmetic.arithmetic_parse` function. - Try to get a response from :func:`dragonfire.learn.Learner.respond` method. - Try to get a answer from :func:`dragonfire.omniscient.Omniscient.respond` method. - Try to get a response from :func:`dragonfire.deepconv.DeepConversation.respond` method. Args: com (str): User's command. Returns: str: Response. """ if not self.args["server"]: global config_file global e if (e.is_set()): # System Tray Icon exit must trigger this exit(0) args = self.args userin = self.userin user_full_name = self.user_full_name user_prefix = self.user_prefix if self.testing: config_file = self.config_file if isinstance(com, str) and com: com = com.strip() else: return False print("You: " + com.upper()) doc = nlp(com) h = Helper(doc) if args["verbose"]: userin.pretty_print_nlp_parsing_results(doc) if self.inactive and not ( h.directly_equal(["dragonfire", "hey"]) or (h.check_verb_lemma("wake") and h.check_nth_lemma(-1, "up")) or (h.check_nth_lemma(0, "dragon") and h.check_nth_lemma(1, "fire") and h.max_word_count(2))): return "" if USER_ANSWERING['status']: if com.startswith("FIRST") or com.startswith( "THE FIRST") or com.startswith("SECOND") or com.startswith( "THE SECOND") or com.startswith( "THIRD") or com.startswith("THE THIRD"): USER_ANSWERING['status'] = False selection = None if com.startswith("FIRST") or com.startswith("THE FIRST"): selection = 0 elif com.startswith("SECOND") or com.startswith("THE SECOND"): selection = 1 elif com.startswith("THIRD") or com.startswith("THE THIRD"): selection = 2 if USER_ANSWERING['for'] == 'wikipedia': with nostderr(): search_query = USER_ANSWERING['options'][selection] try: wikiresult = wikipedia.search(search_query) if len(wikiresult) == 0: userin.say( "Sorry, " + user_prefix + ". But I couldn't find anything about " + search_query + " in Wikipedia.") return True wikipage = wikipedia.page(wikiresult[0]) wikicontent = "".join([ i if ord(i) < 128 else ' ' for i in wikipage.content ]) wikicontent = re.sub(r'\([^)]*\)', '', wikicontent) userin.execute(["sensible-browser", wikipage.url], search_query) return userin.say( wikicontent, cmd=["sensible-browser", wikipage.url]) except requests.exceptions.ConnectionError: userin.execute([" "], "Wikipedia connection error.") return userin.say( "Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers." ) except Exception: return False if h.directly_equal([ "dragonfire", "hey" ]) or (h.check_verb_lemma("wake") and h.check_nth_lemma(-1, "up")) or ( h.check_nth_lemma(0, "dragon") and h.check_nth_lemma(1, "fire") and h.max_word_count(2)): self.inactive = False return userin.say( choice([ "Yes, " + user_prefix + ".", "Yes. I'm waiting.", "What is your order?", "Ready for the orders!", user_prefix.capitalize() + ", tell me your wish." ])) if (h.check_verb_lemma("go") and h.check_noun_lemma("sleep")) or ( h.check_verb_lemma("stop") and h.check_verb_lemma("listen")): self.inactive = True userin.execute([ "echo" ], "Dragonfire deactivated. To reactivate say 'Dragonfire!' or 'Wake Up!'" ) return userin.say("I'm going to sleep") if h.directly_equal(["enough"]) or (h.check_verb_lemma("shut") and h.check_nth_lemma(-1, "up")): tts_kill() msg = "Dragonfire quiets." print(msg) return msg if h.check_wh_lemma("what") and h.check_deps_contains("your name"): return userin.execute([" "], "My name is Dragonfire.", True) if h.check_wh_lemma("what") and h.check_deps_contains("your gender"): return userin.say( "I have a female voice but I don't have a gender identity. I'm a computer program, " + user_prefix + ".") if (h.check_wh_lemma("who") and h.check_text("I")) or (h.check_verb_lemma("say") and h.check_text("my") and h.check_lemma("name")): userin.execute([" "], user_full_name) return userin.say("Your name is " + user_full_name + ", " + user_prefix + ".") if h.check_verb_lemma("open") or h.check_adj_lemma( "open") or h.check_verb_lemma("run") or h.check_verb_lemma( "start") or h.check_verb_lemma("show"): if h.check_text("blender"): userin.execute(["blender"], "Blender") return userin.say("Blender 3D computer graphics software") if h.check_text("draw"): userin.execute(["libreoffice", "--draw"], "LibreOffice Draw") return userin.say("Opening LibreOffice Draw") if h.check_text("impress"): userin.execute(["libreoffice", "--impress"], "LibreOffice Impress") return userin.say("Opening LibreOffice Impress") if h.check_text("math"): userin.execute(["libreoffice", "--math"], "LibreOffice Math") return userin.say("Opening LibreOffice Math") if h.check_text("writer"): userin.execute(["libreoffice", "--writer"], "LibreOffice Writer") return userin.say("Opening LibreOffice Writer") if h.check_text("gimp") or (h.check_noun_lemma("photo") and (h.check_noun_lemma("editor") or h.check_noun_lemma("shop"))): userin.execute(["gimp"], "GIMP") return userin.say("Opening the photo editor software.") if h.check_text("inkscape") or (h.check_noun_lemma("vector") and h.check_noun_lemma("graphic") ) or (h.check_text("vectorial") and h.check_text("drawing")): userin.execute(["inkscape"], "Inkscape") return userin.say("Opening the vectorial drawing software.") if h.check_noun_lemma("office") and h.check_noun_lemma("suite"): userin.execute(["libreoffice"], "LibreOffice") return userin.say("Opening LibreOffice") if h.check_text("kdenlive") or (h.check_noun_lemma("video") and h.check_noun_lemma("editor")): userin.execute(["kdenlive"], "Kdenlive") return userin.say("Opening the video editor software.") if h.check_noun_lemma("browser") or h.check_text( "chrome") or h.check_text("firefox"): userin.execute(["sensible-browser"], "Web Browser") return userin.say("Web browser") if h.check_text("steam"): userin.execute(["steam"], "Steam") return userin.say("Opening Steam Game Store") if h.check_text("files") or (h.check_noun_lemma("file") and h.check_noun_lemma("manager")): userin.execute(["dolphin"], "File Manager") # KDE neon userin.execute(["pantheon-files"], "File Manager") # elementary OS userin.execute(["nautilus", "--browser"], "File Manager") # Ubuntu return userin.say("File Manager") if h.check_noun_lemma("camera"): userin.execute(["kamoso"], "Camera") # KDE neon userin.execute(["snap-photobooth"], "Camera") # elementary OS userin.execute(["cheese"], "Camera") # Ubuntu return userin.say("Camera") if h.check_noun_lemma("calendar"): userin.execute(["korganizer"], "Calendar") # KDE neon userin.execute(["maya-calendar"], "Calendar") # elementary OS userin.execute(["orage"], "Calendar") # Ubuntu return userin.say("Calendar") if h.check_noun_lemma("calculator"): userin.execute(["kcalc"], "Calculator") # KDE neon userin.execute(["pantheon-calculator"], "Calculator") # elementary OS userin.execute(["gnome-calculator"], "Calculator") # Ubuntu return userin.say("Calculator") if h.check_noun_lemma("software") and h.check_text("center"): userin.execute(["plasma-discover"], "Software Center") # KDE neon userin.execute(["software-center"], "Software Center") # elementary OS & Ubuntu return userin.say("Software Center") if h.check_lemma("be") and h.check_lemma("-PRON-") and ( h.check_lemma("lady") or h.check_lemma("woman") or h.check_lemma("girl")): config_file.update({'gender': 'female'}, Query().datatype == 'gender') config_file.remove(Query().datatype == 'callme') user_prefix = "my lady" return userin.say("Pardon, " + user_prefix + ".") if h.check_lemma("be") and h.check_lemma("-PRON-") and ( h.check_lemma("sir") or h.check_lemma("man") or h.check_lemma("boy")): config_file.update({'gender': 'male'}, Query().datatype == 'gender') config_file.remove(Query().datatype == 'callme') user_prefix = "sir" return userin.say("Pardon, " + user_prefix + ".") if h.check_lemma("call") and h.check_lemma("-PRON-"): title = "" for token in doc: if token.pos_ == "NOUN": title += ' ' + token.text title = title.strip() if not args["server"]: callme_config = config_file.search( Query().datatype == 'callme') if callme_config: config_file.update({'title': title}, Query().datatype == 'callme') else: config_file.insert({'datatype': 'callme', 'title': title}) user_prefix = title return userin.say("OK, " + user_prefix + ".") if h.is_wh_question() and h.check_lemma("temperature"): city = "" for ent in doc.ents: if ent.label_ == "GPE": city += ' ' + ent.text city = city.strip() if city: owm = pyowm.OWM("16d66c84e82424f0f8e62c3e3b27b574") reg = owm.city_id_registry() try: weather = owm.weather_at_id( reg.ids_for(city)[0][0]).get_weather() fmt = "The temperature in {} is {} degrees celsius" msg = fmt.format( city, weather.get_temperature('celsius')['temp']) userin.execute([" "], msg) return userin.say(msg) except IndexError: msg = "Sorry, " + user_prefix + " but I couldn't find a city named " + city + " on the internet." userin.execute([" "], msg) return userin.say(msg) if (h.check_nth_lemma(0, "keyboard") or h.check_nth_lemma(0, "type")) and not args["server"]: n = len(doc[0].text) + 1 with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: for character in com[n:]: k.tap_key(character) k.tap_key(" ") return "keyboard" if (h.directly_equal(["enter"]) or (h.check_adj_lemma("new") and h.check_noun_lemma("line"))) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(k.enter_key) return "enter" if h.check_adj_lemma("new") and h.check_noun_lemma( "tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 't']) return "new tab" if h.check_verb_lemma("switch") and h.check_noun_lemma( "tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, k.tab_key]) return "switch tab" if h.directly_equal(["CLOSE", "ESCAPE"]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 'w']) k.tap_key(k.escape_key) return "close" if h.check_lemma("back") and h.max_word_count( 4) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.alt_l_key, k.left_key]) return "back" if h.check_lemma("forward") and h.max_word_count( 4) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.alt_l_key, k.right_key]) return "forward" if (h.check_text("swipe") or h.check_text("scroll")) and not args["server"]: if h.check_text("left"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, -5) return "swipe left" if h.check_text("right"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, 5) return "swipe right" if h.check_text("up"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(5, 0) return "swipe up" if h.check_text("down"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(-5, 0) return "swipe down" if h.directly_equal(["PLAY", "PAUSE", "SPACEBAR" ]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(" ") return "play" if ((h.check_text("shut") and h.check_text("down")) or (h.check_text("power") and h.check_text("off")) ) and h.check_text("computer") and not args["server"]: return userin.execute(["sudo", "poweroff"], "Shutting down", True, 3) if h.check_nth_lemma(0, "goodbye") or h.check_nth_lemma( 0, "bye") or (h.check_verb_lemma("see") and h.check_text("you") and h.check_adv_lemma("later")): response = userin.say("Goodbye, " + user_prefix) if not args["server"] and not self.testing: # raise KeyboardInterrupt thread.interrupt_main() return response if (h.check_lemma("search") or h.check_lemma("find")) and h.check_lemma("wikipedia"): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "wikipedia" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: try: wikiresult = wikipedia.search(search_query) if len(wikiresult) == 0: userin.say( "Sorry, " + user_prefix + ". But I couldn't find anything about " + search_query + " in Wikipedia.") return True wikipage = wikipedia.page(wikiresult[0]) wikicontent = "".join([ i if ord(i) < 128 else ' ' for i in wikipage.content ]) wikicontent = re.sub(r'\([^)]*\)', '', wikicontent) userin.execute(["sensible-browser", wikipage.url], search_query) return userin.say( wikicontent, cmd=["sensible-browser", wikipage.url]) except requests.exceptions.ConnectionError: userin.execute([" "], "Wikipedia connection error.") return userin.say( "Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers." ) except wikipedia.exceptions.DisambiguationError as disambiguation: USER_ANSWERING['status'] = True USER_ANSWERING['for'] = 'wikipedia' USER_ANSWERING['reason'] = 'disambiguation' USER_ANSWERING['options'] = disambiguation.options[:3] notify = "Wikipedia disambiguation. Which one of these you meant?:\n - " + disambiguation.options[ 0] msg = user_prefix + ", there is a disambiguation. Which one of these you meant? " + disambiguation.options[ 0] for option in disambiguation.options[1:3]: msg += ", or " + option notify += "\n - " + option notify += '\nSay, for example: "THE FIRST ONE" to choose.' userin.execute([" "], notify) return userin.say(msg) except BaseException: pass if (h.check_lemma("search") or h.check_lemma("find")) and h.check_lemma("youtube"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "youtube" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: info = youtube_dl.YoutubeDL({}).extract_info( 'ytsearch:' + search_query, download=False, ie_key='YoutubeSearch') if len(info['entries']) > 0: youtube_title = info['entries'][0]['title'] youtube_url = "https://www.youtube.com/watch?v=%s" % ( info['entries'][0]['id']) userin.execute(["sensible-browser", youtube_url], youtube_title) youtube_title = "".join([ i if ord(i) < 128 else ' ' for i in youtube_title ]) response = userin.say( youtube_title, ["sensible-browser", youtube_url]) else: youtube_title = "No video found, " + user_prefix + "." response = userin.say(youtube_title) k = PyKeyboard() if not args["server"] and not self.testing: time.sleep(5) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key('f') return response if (h.check_lemma("search") or h.check_lemma("find")) and ( h.check_lemma("google") or h.check_lemma("web") or h.check_lemma("internet")) and not h.check_lemma("image"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "google" or token.lemma_ == "web" or token.lemma_ == "internet" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: tab_url = "http://google.com/?#q=" + search_query return userin.execute(["sensible-browser", tab_url], search_query, True) if (h.check_lemma("search") or h.check_lemma("find")) and ( h.check_lemma("google") or h.check_lemma("web") or h.check_lemma("internet")) and h.check_lemma("image"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "google" or token.lemma_ == "web" or token.lemma_ == "internet" or token.lemma_ == "image" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: tab_url = "http://google.com/?#q=" + search_query + "&tbm=isch" return userin.execute(["sensible-browser", tab_url], search_query, True) original_com = com com = coref.resolve(com) if args["verbose"]: print("After Coref Resolution: " + com) arithmetic_response = arithmetic_parse(com) if arithmetic_response: return userin.say(arithmetic_response) else: learner_response = learner.respond(com) if learner_response: return userin.say(learner_response) else: omniscient_response = omniscient.respond( com, not args["silent"], userin, user_prefix, args["server"]) if omniscient_response: return omniscient_response else: dc_response = dc.respond(original_com, user_prefix) if dc_response: return userin.say(dc_response)
def respond(self, com, tts_output=False, userin=None, user_prefix=None, is_server=False): """Method to respond the user's input/command using factoid question answering ability. Args: com (str): User's command. Keyword Args: tts_output (bool): Is text-to-speech output enabled? userin: :class:`dragonfire.utilities.TextToAction` instance. user_prefix (str): Prefix to address/call user when answering. is_server (bool): Is Dragonfire running as an API server? Returns: str: Response. .. note:: Entry function for :class:`Omniscient` class. Dragonfire calls only this function. Unlike :func:`Learner.respond`, it executes TTS because of its late reponse nature. """ result = None subject, subjects, focus, subject_with_objects = self.semantic_extractor( com) # Extract the subject, focus, objects etc. if not subject: return False doc = self.nlp( com) # spaCy does all kinds of NLP analysis in one function query = subject # Wikipedia search query (same as the subject) # This is where the real search begins if query: # If there is a Wikipedia query determined if not tts_output and not is_server: print("Please wait...") if tts_output and not is_server: userin.say( "Please wait...", True, False) # Gain a few more seconds by saying Please wait... wh_question = [] for word in doc: # Iterate over the words in the command(user's speech) if word.tag_ in ['WDT', 'WP', 'WP$', 'WRB']: # if there is a wh word then wh_question.append(word.text.upper( )) # append it by converting to uppercase if not wh_question: return False with nostderr(): try: wikiresult = wikipedia.search( query) # run a Wikipedia search with the query if len(wikiresult) == 0: # if there are no results result = "Sorry, " + user_prefix + ". But I couldn't find anything about " + query + " in Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result wikipedia.page(wikiresult[0]) except requests.exceptions.ConnectionError: # if there is a connection error result = "Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers." if not is_server: userin.execute([" "], "Wikipedia connection error.") if not tts_output: print(result) if tts_output: userin.say(result) return result except wikipedia.exceptions.DisambiguationError as disambiguation: # if there is a disambiguation wikiresult = wikipedia.search( disambiguation.options[0] ) # run Wikipedia search again with the most common option except: result = "Sorry, " + user_prefix + ". But something went horribly wrong while I'm searching Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result findings = [] # empty findings list for scoring nth_page = 0 # nth Wikipedia page/article while not findings: # while there are no any findings if not len(wikiresult) >= (nth_page + 1): # prevent index error break with nostderr(): try: wikipage = wikipedia.page( wikiresult[nth_page] ) # Get the next Wikipedia page/article from the search results (this line also handles the search at the same time) except requests.exceptions.ConnectionError: # if there is a connection error result = "Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers." if not is_server: userin.execute([" "], "Wikipedia connection error.") if not tts_output: print(result) if tts_output: userin.say(result) return result except: result = "Sorry, " + user_prefix + ". But something went horribly wrong while I'm searching Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result nth_page += 1 # increase the visited page/article count if nth_page > 5: break # if script searched more than 5 Wikipedia pages/articles then give up wikidoc = self.nlp( wikipage.content ) # parse the Wikipedia page/article content using spaCy NLP library sentences = [ sent.string.strip() for sent in wikidoc.sents ] # each individual sentence in the current Wikipedia page/article # return [' '.join(subjects),' '.join(pobjects)] all_entities = [] # all entities, useful or not all of them mention = {} # sentences with focus mentioned subject_entities_by_wordnet = None # target entities according to the subject if 'WHAT' in wh_question: # if it's a WHAT question then subject_entities_by_wordnet = self.wordnet_entity_determiner( subject_with_objects, tts_output, is_server, userin, user_prefix) # result of wordnet_entity_determiner() if not subject_entities_by_wordnet: return True for sentence in reversed( sentences ): # iterate over the sentences (in reversed order) sentence = self.nlp( sentence) # parse the sentence using spaCy NLP library for ent in sentence.ents: # iterate over the all entities in the sentence (has been found by spaCy) all_entities.append( ent.text) # append the entity to all_entities mention[ ent. text] = 0.0 # the value if focus not even defined or the focus is NOT even mentioned for wh in wh_question: # iterate over the all wh questions have been found in the Command(user's speech) if wh.upper( ) in self.entity_map: # if the wh question is defined in entity_map (on top) then target_entities = self.entity_map[wh.upper( )] # get the target entities from the entity_map if wh.upper( ) == 'WHAT': # if the question is WHAT then target_entities = [ ] # empty the target entities because we will replace them with the result of wordnet_entity_determiner() for subject_entity_by_wordnet in subject_entities_by_wordnet: # for each entity in subject_entities_by_wordnet target_entities.append( subject_entity_by_wordnet ) # append the entity to target entities if ent.label_ in target_entities: # if entity label is in target entities listed then findings.append( ent.text ) # WE FOUND! a possible entity so append the text to findings if focus: # if focus is defined then if focus in sentence.text: # if focus is in the sentence then mention[ ent. text] += 1.0 * sentence.text.count( focus ) # assign the how many times the entity mentioned in the sentence if findings: # if there is a finding or there are findings then frequency = collections.Counter( findings ) # count the occurrences of the exacty same finding and return a unique dictionary. High frequency means high score max_freq = max(frequency.values()) # max occurrence for key, value in frequency.items( ): # iterate over the unique dictionary frequency[key] = float( value ) / max_freq # divide the occurence by max occurence to find the real frequency value precedence = { } # precedence according to the location of the finding in the Wikipedia article. Closer to the top, greater the score is unique = list(set(findings)) # unique the findings list for i in range(len(unique)): # iterate over that unqiue list precedence[unique[i]] = float(len(unique) - i) / len( unique) # calculate the score proximity = { } # proximity to the subject. Closer to the subject (in terms of location), greater the score is subject_indices = [] # index values of subject occurrences for i in range( len(all_entities)): # iterate over the all entities for subject in subjects: # iterate over the all subjects for word in subject.split( ): # iterate over the each word in the subject if word in all_entities[ i]: # if the word is in all entities then subject_indices.append(i) # append the index for i in range(len( all_entities)): # iterate over the all entities, again for index in subject_indices: # for each index inverse_distance = float( (len(all_entities) - 1) - abs(i - index) ) / ( len(all_entities) - 1 ) # calculate the proximity of the entity to the subject if all_entities[ i] in proximity: # if the entity is already appended then proximity[all_entities[i]] = ( proximity[all_entities[i]] + inverse_distance ) / 2 # assign the proximity by calculating the average else: proximity[all_entities[ i]] = inverse_distance # otherwise assign the proximity directly if all_entities[ i] not in proximity: # if it's somehow not appended then proximity[all_entities[i]] = 0 # give it a zero score ranked = {} # the eventual ranking/scoring for key, value in frequency.items( ): # iterate over the all findings (frequency, precedence, proximity, mention all of them holds all findings) if key not in query: # eliminate the findings that already inside of the Wikipedia query ranked[key] = ( value * self.coefficient['frequency'] + precedence[key] * self.coefficient['precedence'] + proximity[key] * self.coefficient['proximity'] + mention[key] * self.coefficient['mention'] ) # calculate the absolute score result = sorted(ranked.items(), key=lambda x: x[1])[::-1][0][0] if not tts_output and not is_server: print( sorted(ranked.items(), key=lambda x: x[1])[::-1] [:5]) # if not tts_output print the best 5 result if tts_output and not is_server: userin.say( result, True, True ) # if tts_output say the best result (via TTS obviously) return result # also return the best result else: # if no any findings return False # in case of no any findings return False
def command(self, com): """Function that serves as the entry point for each one of the user commands. This function goes through these steps for each one of user's commands, respectively: - Search across the built-in commands via a simple if-else control flow. - Try to get a response from :func:`dragonfire.arithmetic.arithmetic_parse` function. - Try to get a response from :func:`dragonfire.learn.Learner.respond` method. - Try to get a answer from :func:`dragonfire.omniscient.Omniscient.respond` method. - Try to get a response from :func:`dragonfire.deepconv.DeepConversation.respond` method. Args: com (str): User's command. Returns: str: Response. """ if not self.args["server"]: global config_file global e if (e.is_set()): # System Tray Icon exit must trigger this exit(0) args = self.args userin = self.userin user_full_name = self.user_full_name user_prefix = self.user_prefix if self.testing: config_file = self.config_file if isinstance(com, str) and com: com = com.strip() else: return False print("You: " + com.upper()) doc = nlp(com) h = Helper(doc) if args["verbose"]: userin.pretty_print_nlp_parsing_results(doc) if self.inactive and not (h.directly_equal(["dragonfire", "hey"]) or (h.check_verb_lemma("wake") and h.check_nth_lemma(-1, "up")) or (h.check_nth_lemma(0, "dragon") and h.check_nth_lemma(1, "fire") and h.max_word_count(2))): return "" if USER_ANSWERING['status']: if com.startswith("FIRST") or com.startswith("THE FIRST") or com.startswith("SECOND") or com.startswith("THE SECOND") or com.startswith("THIRD") or com.startswith("THE THIRD"): USER_ANSWERING['status'] = False selection = None if com.startswith("FIRST") or com.startswith("THE FIRST"): selection = 0 elif com.startswith("SECOND") or com.startswith("THE SECOND"): selection = 1 elif com.startswith("THIRD") or com.startswith("THE THIRD"): selection = 2 if USER_ANSWERING['for'] == 'wikipedia': with nostderr(): search_query = USER_ANSWERING['options'][selection] try: wikiresult = wikipedia.search(search_query) if len(wikiresult) == 0: userin.say("Sorry, " + user_prefix + ". But I couldn't find anything about " + search_query + " in Wikipedia.") return True wikipage = wikipedia.page(wikiresult[0]) wikicontent = "".join([i if ord(i) < 128 else ' ' for i in wikipage.content]) wikicontent = re.sub(r'\([^)]*\)', '', wikicontent) userin.execute(["sensible-browser", wikipage.url], search_query) return userin.say(wikicontent, cmd=["sensible-browser", wikipage.url]) except requests.exceptions.ConnectionError: userin.execute([" "], "Wikipedia connection error.") return userin.say("Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers.") except Exception: return False if h.directly_equal(["dragonfire", "hey"]) or (h.check_verb_lemma("wake") and h.check_nth_lemma(-1, "up")) or (h.check_nth_lemma(0, "dragon") and h.check_nth_lemma(1, "fire") and h.max_word_count(2)): self.inactive = False return userin.say(choice([ "Yes, " + user_prefix + ".", "Yes. I'm waiting.", "What is your order?", "Ready for the orders!", user_prefix.capitalize() + ", tell me your wish." ])) if (h.check_verb_lemma("go") and h.check_noun_lemma("sleep")) or (h.check_verb_lemma("stop") and h.check_verb_lemma("listen")): self.inactive = True userin.execute(["echo"], "Dragonfire deactivated. To reactivate say 'Dragonfire!' or 'Wake Up!'") return userin.say("I'm going to sleep") if h.directly_equal(["enough"]) or (h.check_verb_lemma("shut") and h.check_nth_lemma(-1, "up")): tts_kill() msg = "Dragonfire quiets." print(msg) return msg if h.check_wh_lemma("what") and h.check_deps_contains("your name"): return userin.execute([" "], "My name is Dragonfire.", True) if h.check_wh_lemma("what") and h.check_deps_contains("your gender"): return userin.say("I have a female voice but I don't have a gender identity. I'm a computer program, " + user_prefix + ".") if (h.check_wh_lemma("who") and h.check_text("I")) or (h.check_verb_lemma("say") and h.check_text("my") and h.check_lemma("name")): userin.execute([" "], user_full_name) return userin.say("Your name is " + user_full_name + ", " + user_prefix + ".") if h.check_verb_lemma("open") or h.check_adj_lemma("open") or h.check_verb_lemma("run") or h.check_verb_lemma("start") or h.check_verb_lemma("show"): if h.check_text("blender"): userin.execute(["blender"], "Blender") return userin.say("Blender 3D computer graphics software") if h.check_text("draw"): userin.execute(["libreoffice", "--draw"], "LibreOffice Draw") return userin.say("Opening LibreOffice Draw") if h.check_text("impress"): userin.execute(["libreoffice", "--impress"], "LibreOffice Impress") return userin.say("Opening LibreOffice Impress") if h.check_text("math"): userin.execute(["libreoffice", "--math"], "LibreOffice Math") return userin.say("Opening LibreOffice Math") if h.check_text("writer"): userin.execute(["libreoffice", "--writer"], "LibreOffice Writer") return userin.say("Opening LibreOffice Writer") if h.check_text("gimp") or (h.check_noun_lemma("photo") and (h.check_noun_lemma("editor") or h.check_noun_lemma("shop"))): userin.execute(["gimp"], "GIMP") return userin.say("Opening the photo editor software.") if h.check_text("inkscape") or (h.check_noun_lemma("vector") and h.check_noun_lemma("graphic")) or (h.check_text("vectorial") and h.check_text("drawing")): userin.execute(["inkscape"], "Inkscape") return userin.say("Opening the vectorial drawing software.") if h.check_noun_lemma("office") and h.check_noun_lemma("suite"): userin.execute(["libreoffice"], "LibreOffice") return userin.say("Opening LibreOffice") if h.check_text("kdenlive") or (h.check_noun_lemma("video") and h.check_noun_lemma("editor")): userin.execute(["kdenlive"], "Kdenlive") return userin.say("Opening the video editor software.") if h.check_noun_lemma("browser") or h.check_text("chrome") or h.check_text("firefox"): userin.execute(["sensible-browser"], "Web Browser") return userin.say("Web browser") if h.check_text("steam"): userin.execute(["steam"], "Steam") return userin.say("Opening Steam Game Store") if h.check_text("files") or (h.check_noun_lemma("file") and h.check_noun_lemma("manager")): userin.execute(["dolphin"], "File Manager") # KDE neon userin.execute(["pantheon-files"], "File Manager") # elementary OS userin.execute(["nautilus", "--browser"], "File Manager") # Ubuntu return userin.say("File Manager") if h.check_noun_lemma("camera"): userin.execute(["kamoso"], "Camera") # KDE neon userin.execute(["snap-photobooth"], "Camera") # elementary OS userin.execute(["cheese"], "Camera") # Ubuntu return userin.say("Camera") if h.check_noun_lemma("calendar"): userin.execute(["korganizer"], "Calendar") # KDE neon userin.execute(["maya-calendar"], "Calendar") # elementary OS userin.execute(["orage"], "Calendar") # Ubuntu return userin.say("Calendar") if h.check_noun_lemma("calculator"): userin.execute(["kcalc"], "Calculator") # KDE neon userin.execute(["pantheon-calculator"], "Calculator") # elementary OS userin.execute(["gnome-calculator"], "Calculator") # Ubuntu return userin.say("Calculator") if h.check_noun_lemma("software") and h.check_text("center"): userin.execute(["plasma-discover"], "Software Center") # KDE neon userin.execute(["software-center"], "Software Center") # elementary OS & Ubuntu return userin.say("Software Center") if h.check_lemma("be") and h.check_lemma("-PRON-") and (h.check_lemma("lady") or h.check_lemma("woman") or h.check_lemma("girl")): config_file.update({'gender': 'female'}, Query().datatype == 'gender') config_file.remove(Query().datatype == 'callme') user_prefix = "my lady" return userin.say("Pardon, " + user_prefix + ".") if h.check_lemma("be") and h.check_lemma("-PRON-") and (h.check_lemma("sir") or h.check_lemma("man") or h.check_lemma("boy")): config_file.update({'gender': 'male'}, Query().datatype == 'gender') config_file.remove(Query().datatype == 'callme') user_prefix = "sir" return userin.say("Pardon, " + user_prefix + ".") if h.check_lemma("call") and h.check_lemma("-PRON-"): title = "" for token in doc: if token.pos_ == "NOUN": title += ' ' + token.text title = title.strip() if not args["server"]: callme_config = config_file.search(Query().datatype == 'callme') if callme_config: config_file.update({'title': title}, Query().datatype == 'callme') else: config_file.insert({'datatype': 'callme', 'title': title}) user_prefix = title return userin.say("OK, " + user_prefix + ".") if h.is_wh_question() and h.check_lemma("temperature"): city = "" for ent in doc.ents: if ent.label_ == "GPE": city += ' ' + ent.text city = city.strip() if city: owm = pyowm.OWM("16d66c84e82424f0f8e62c3e3b27b574") reg = owm.city_id_registry() try: weather = owm.weather_at_id(reg.ids_for(city)[0][0]).get_weather() fmt = "The temperature in {} is {} degrees celsius" msg = fmt.format(city, weather.get_temperature('celsius')['temp']) userin.execute([" "], msg) return userin.say(msg) except IndexError: msg = "Sorry, " + user_prefix + " but I couldn't find a city named " + city + " on the internet." userin.execute([" "], msg) return userin.say(msg) if (h.check_nth_lemma(0, "keyboard") or h.check_nth_lemma(0, "type")) and not args["server"]: n = len(doc[0].text) + 1 with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: for character in com[n:]: k.tap_key(character) k.tap_key(" ") return "keyboard" if (h.directly_equal(["enter"]) or (h.check_adj_lemma("new") and h.check_noun_lemma("line"))) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(k.enter_key) return "enter" if h.check_adj_lemma("new") and h.check_noun_lemma("tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 't']) return "new tab" if h.check_verb_lemma("switch") and h.check_noun_lemma("tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, k.tab_key]) return "switch tab" if h.directly_equal(["CLOSE", "ESCAPE"]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 'w']) k.tap_key(k.escape_key) return "close" if h.check_lemma("back") and h.max_word_count(4) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.alt_l_key, k.left_key]) return "back" if h.check_lemma("forward") and h.max_word_count(4) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.alt_l_key, k.right_key]) return "forward" if (h.check_text("swipe") or h.check_text("scroll")) and not args["server"]: if h.check_text("left"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, -5) return "swipe left" if h.check_text("right"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, 5) return "swipe right" if h.check_text("up"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(5, 0) return "swipe up" if h.check_text("down"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(-5, 0) return "swipe down" if h.directly_equal(["PLAY", "PAUSE", "SPACEBAR"]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(" ") return "play" if ((h.check_text("shut") and h.check_text("down")) or (h.check_text("power") and h.check_text("off"))) and h.check_text("computer") and not args["server"]: return userin.execute(["sudo", "poweroff"], "Shutting down", True, 3) if h.check_nth_lemma(0, "goodbye") or h.check_nth_lemma(0, "bye") or (h.check_verb_lemma("see") and h.check_text("you") and h.check_adv_lemma("later")): response = userin.say("Goodbye, " + user_prefix) if not args["server"] and not self.testing: # raise KeyboardInterrupt thread.interrupt_main() return response if (h.check_lemma("search") or h.check_lemma("find")) and h.check_lemma("wikipedia"): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "wikipedia" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: try: wikiresult = wikipedia.search(search_query) if len(wikiresult) == 0: userin.say("Sorry, " + user_prefix + ". But I couldn't find anything about " + search_query + " in Wikipedia.") return True wikipage = wikipedia.page(wikiresult[0]) wikicontent = "".join([i if ord(i) < 128 else ' ' for i in wikipage.content]) wikicontent = re.sub(r'\([^)]*\)', '', wikicontent) userin.execute(["sensible-browser", wikipage.url], search_query) return userin.say(wikicontent, cmd=["sensible-browser", wikipage.url]) except requests.exceptions.ConnectionError: userin.execute([" "], "Wikipedia connection error.") return userin.say("Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers.") except wikipedia.exceptions.DisambiguationError as disambiguation: USER_ANSWERING['status'] = True USER_ANSWERING['for'] = 'wikipedia' USER_ANSWERING['reason'] = 'disambiguation' USER_ANSWERING['options'] = disambiguation.options[:3] notify = "Wikipedia disambiguation. Which one of these you meant?:\n - " + disambiguation.options[0] msg = user_prefix + ", there is a disambiguation. Which one of these you meant? " + disambiguation.options[0] for option in disambiguation.options[1:3]: msg += ", or " + option notify += "\n - " + option notify += '\nSay, for example: "THE FIRST ONE" to choose.' userin.execute([" "], notify) return userin.say(msg) except BaseException: pass if (h.check_lemma("search") or h.check_lemma("find")) and h.check_lemma("youtube"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "youtube" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: info = youtube_dl.YoutubeDL({}).extract_info('ytsearch:' + search_query, download=False, ie_key='YoutubeSearch') if len(info['entries']) > 0: youtube_title = info['entries'][0]['title'] youtube_url = "https://www.youtube.com/watch?v=%s" % (info['entries'][0]['id']) userin.execute(["sensible-browser", youtube_url], youtube_title) youtube_title = "".join([i if ord(i) < 128 else ' ' for i in youtube_title]) response = userin.say(youtube_title, ["sensible-browser", youtube_url]) else: youtube_title = "No video found, " + user_prefix + "." response = userin.say(youtube_title) k = PyKeyboard() if not args["server"] and not self.testing: time.sleep(5) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key(k.tab_key) k.tap_key('f') return response if (h.check_lemma("search") or h.check_lemma("find")) and (h.check_lemma("google") or h.check_lemma("web") or h.check_lemma("internet")) and not h.check_lemma("image"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "google" or token.lemma_ == "web" or token.lemma_ == "internet" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: tab_url = "http://google.com/?#q=" + search_query return userin.execute(["sensible-browser", tab_url], search_query, True) if (h.check_lemma("search") or h.check_lemma("find")) and (h.check_lemma("google") or h.check_lemma("web") or h.check_lemma("internet")) and h.check_lemma("image"): with nostdout(): with nostderr(): search_query = "" for token in doc: if not (token.lemma_ == "search" or token.lemma_ == "find" or token.lemma_ == "google" or token.lemma_ == "web" or token.lemma_ == "internet" or token.lemma_ == "image" or token.is_stop): search_query += ' ' + token.text search_query = search_query.strip() if search_query: tab_url = "http://google.com/?#q=" + search_query + "&tbm=isch" return userin.execute(["sensible-browser", tab_url], search_query, True) original_com = com com = coref.resolve(com) if args["verbose"]: print("After Coref Resolution: " + com) arithmetic_response = arithmetic_parse(com) if arithmetic_response: return userin.say(arithmetic_response) else: learner_response = learner.respond(com) if learner_response: return userin.say(learner_response) else: omniscient_response = omniscient.respond(com, not args["silent"], userin, user_prefix, args["server"]) if omniscient_response: return omniscient_response else: dc_response = dc.respond(original_com, user_prefix) if dc_response: return userin.say(dc_response)
def compare(self, com, args, testing): """Method to dragonfire's command structures of keyboard keys ability. Args: com (str): User's command. args: Command-line arguments. """ self.testing = testing doc = nlp(com) h = Helper(doc) if (h.check_nth_lemma(0, "keyboard") or h.check_nth_lemma(0, "type")) and not args["server"]: n = len(doc[0].text) + 1 with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: for character in com[n:]: k.tap_key(character) k.tap_key(" ") return "keyboard" if (h.directly_equal(["enter"]) or (h.check_adj_lemma("new") and h.check_noun_lemma("line"))) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(k.enter_key) return "enter" if h.check_adj_lemma("new") and h.check_noun_lemma( "tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 't']) return "new tab" if h.check_verb_lemma("switch") and h.check_noun_lemma( "tab") and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, k.tab_key]) return "switch tab" if h.directly_equal(["CLOSE", "ESCAPE"]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.control_l_key, 'w']) k.tap_key(k.escape_key) return "close" if h.check_lemma("back") and h.max_word_count( 4) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.alt_l_key, k.left_key]) return "back" if h.check_lemma("forward") and h.max_word_count( 4) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.press_keys([k.alt_l_key, k.right_key]) return "forward" if (h.check_text("swipe") or h.check_text("scroll")) and not args["server"]: if h.check_text("left"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, -5) return "swipe left" if h.check_text("right"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(0, 5) return "swipe right" if h.check_text("up"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(5, 0) return "swipe up" if h.check_text("down"): with nostdout(): with nostderr(): m = PyMouse() if not self.testing: m.scroll(-5, 0) return "swipe down" if h.directly_equal(["PLAY", "PAUSE", "SPACEBAR" ]) and not args["server"]: with nostdout(): with nostderr(): k = PyKeyboard() if not self.testing: k.tap_key(" ") return "play" return None
def respond(self, com, tts_output=False, userin=None, user_prefix=None, is_server=False): """Method to respond the user's input/command using factoid question answering ability. Args: com (str): User's command. Keyword Args: tts_output (bool): Is text-to-speech output enabled? userin: :class:`dragonfire.utilities.TextToAction` instance. user_prefix (str): Prefix to address/call user when answering. is_server (bool): Is Dragonfire running as an API server? Returns: str: Response. .. note:: Entry function for :class:`Omniscient` class. Dragonfire calls only this function. Unlike :func:`Learner.respond`, it executes TTS because of its late reponse nature. """ result = None subject, subjects, focus, subject_with_objects = self.semantic_extractor(com) # Extract the subject, focus, objects etc. if not subject: return False doc = self.nlp(com) # spaCy does all kinds of NLP analysis in one function query = subject # Wikipedia search query (same as the subject) # This is where the real search begins if query: # If there is a Wikipedia query determined if not tts_output and not is_server: print("Please wait...") if tts_output and not is_server: userin.say("Please wait...", True, False) # Gain a few more seconds by saying Please wait... wh_question = [] for word in doc: # Iterate over the words in the command(user's speech) if word.tag_ in ['WDT', 'WP', 'WP$', 'WRB']: # if there is a wh word then wh_question.append(word.text.upper()) # append it by converting to uppercase if not wh_question: return False with nostderr(): try: wikiresult = wikipedia.search(query) # run a Wikipedia search with the query if len(wikiresult) == 0: # if there are no results result = "Sorry, " + user_prefix + ". But I couldn't find anything about " + query + " in Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result wikipedia.page(wikiresult[0]) except requests.exceptions.ConnectionError: # if there is a connection error result = "Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers." if not is_server: userin.execute([" "], "Wikipedia connection error.") if not tts_output: print(result) if tts_output: userin.say(result) return result except wikipedia.exceptions.DisambiguationError as disambiguation: # if there is a disambiguation wikiresult = wikipedia.search(disambiguation.options[0]) # run Wikipedia search again with the most common option except: result = "Sorry, " + user_prefix + ". But something went horribly wrong while I'm searching Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result findings = [] # empty findings list for scoring nth_page = 0 # nth Wikipedia page/article while not findings: # while there are no any findings if not len(wikiresult) >= (nth_page + 1): # prevent index error break with nostderr(): try: wikipage = wikipedia.page(wikiresult[nth_page]) # Get the next Wikipedia page/article from the search results (this line also handles the search at the same time) except requests.exceptions.ConnectionError: # if there is a connection error result = "Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers." if not is_server: userin.execute([" "], "Wikipedia connection error.") if not tts_output: print(result) if tts_output: userin.say(result) return result except: result = "Sorry, " + user_prefix + ". But something went horribly wrong while I'm searching Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result nth_page += 1 # increase the visited page/article count if nth_page > 5: break # if script searched more than 5 Wikipedia pages/articles then give up wikidoc = self.nlp(wikipage.content) # parse the Wikipedia page/article content using spaCy NLP library sentences = [sent.string.strip() for sent in wikidoc.sents] # each individual sentence in the current Wikipedia page/article # return [' '.join(subjects),' '.join(pobjects)] all_entities = [] # all entities, useful or not all of them mention = {} # sentences with focus mentioned subject_entities_by_wordnet = None # target entities according to the subject if 'WHAT' in wh_question: # if it's a WHAT question then subject_entities_by_wordnet = self.wordnet_entity_determiner(subject_with_objects, tts_output, is_server, userin, user_prefix) # result of wordnet_entity_determiner() if not subject_entities_by_wordnet: return True for sentence in reversed(sentences): # iterate over the sentences (in reversed order) sentence = self.nlp(sentence) # parse the sentence using spaCy NLP library for ent in sentence.ents: # iterate over the all entities in the sentence (has been found by spaCy) all_entities.append(ent.text) # append the entity to all_entities mention[ent.text] = 0.0 # the value if focus not even defined or the focus is NOT even mentioned for wh in wh_question: # iterate over the all wh questions have been found in the Command(user's speech) if wh.upper() in self.entity_map: # if the wh question is defined in entity_map (on top) then target_entities = self.entity_map[wh.upper()] # get the target entities from the entity_map if wh.upper() == 'WHAT': # if the question is WHAT then target_entities = [] # empty the target entities because we will replace them with the result of wordnet_entity_determiner() for subject_entity_by_wordnet in subject_entities_by_wordnet: # for each entity in subject_entities_by_wordnet target_entities.append(subject_entity_by_wordnet) # append the entity to target entities if ent.label_ in target_entities: # if entity label is in target entities listed then findings.append(ent.text) # WE FOUND! a possible entity so append the text to findings if focus: # if focus is defined then if focus in sentence.text: # if focus is in the sentence then mention[ent.text] += 1.0 * sentence.text.count(focus) # assign the how many times the entity mentioned in the sentence if findings: # if there is a finding or there are findings then frequency = collections.Counter(findings) # count the occurrences of the exacty same finding and return a unique dictionary. High frequency means high score max_freq = max(frequency.values()) # max occurrence for key, value in frequency.items(): # iterate over the unique dictionary frequency[key] = float(value) / max_freq # divide the occurence by max occurence to find the real frequency value precedence = {} # precedence according to the location of the finding in the Wikipedia article. Closer to the top, greater the score is unique = list(set(findings)) # unique the findings list for i in range(len(unique)): # iterate over that unqiue list precedence[unique[i]] = float(len(unique) - i) / len(unique) # calculate the score proximity = {} # proximity to the subject. Closer to the subject (in terms of location), greater the score is subject_indices = [] # index values of subject occurrences for i in range(len(all_entities)): # iterate over the all entities for subject in subjects: # iterate over the all subjects for word in subject.split(): # iterate over the each word in the subject if word in all_entities[i]: # if the word is in all entities then subject_indices.append(i) # append the index for i in range(len(all_entities)): # iterate over the all entities, again for index in subject_indices: # for each index inverse_distance = float((len(all_entities) - 1) - abs(i - index)) / (len(all_entities) - 1) # calculate the proximity of the entity to the subject if all_entities[i] in proximity: # if the entity is already appended then proximity[all_entities[i]] = (proximity[all_entities[i]] + inverse_distance) / 2 # assign the proximity by calculating the average else: proximity[all_entities[i]] = inverse_distance # otherwise assign the proximity directly if all_entities[i] not in proximity: # if it's somehow not appended then proximity[all_entities[i]] = 0 # give it a zero score ranked = {} # the eventual ranking/scoring for key, value in frequency.items(): # iterate over the all findings (frequency, precedence, proximity, mention all of them holds all findings) if key not in query: # eliminate the findings that already inside of the Wikipedia query ranked[key] = (value * self.coefficient['frequency'] + precedence[key] * self.coefficient['precedence'] + proximity[key] * self.coefficient['proximity'] + mention[key] * self.coefficient['mention']) # calculate the absolute score result = sorted(ranked.items(), key=lambda x: x[1])[::-1][0][0] if not tts_output and not is_server: print(sorted(ranked.items(), key=lambda x: x[1])[::-1][:5]) # if not tts_output print the best 5 result if tts_output and not is_server: userin.say(result, True, True) # if tts_output say the best result (via TTS obviously) return result # also return the best result else: # if no any findings return False # in case of no any findings return False
def respond(self, com, tts_output=False, userin=None, user_prefix=None, is_server=False): """Method to respond the user's input/command using factoid question answering ability. Args: com (str): User's command. Keyword Args: tts_output (bool): Is text-to-speech output enabled? userin: :class:`dragonfire.utilities.TextToAction` instance. user_prefix (str): Prefix to address/call user when answering. is_server (bool): Is Dragonfire running as an API server? Returns: str: Response. .. note:: Entry function for :class:`ODQA` class. Dragonfire calls only this function. Unlike :func:`Learner.respond`, it executes TTS because of its late reponse nature. """ result = None subject, subjects, focus, subject_with_objects = self.semantic_extractor( com) # Extract the subject, focus, objects etc. if not subject: return False doc = self.nlp( com) # spaCy does all kinds of NLP analysis in one function query = subject # Wikipedia search query (same as the subject) # This is where the real search begins if query: # If there is a Wikipedia query determined if not tts_output and not is_server: print("Please wait...") if tts_output and not is_server: userin.say( "Please wait...", True, False) # Gain a few more seconds by saying Please wait... wh_question = [] for word in doc: # Iterate over the words in the command(user's speech) if word.tag_ in ['WDT', 'WP', 'WP$', 'WRB']: # if there is a wh word then wh_question.append(word.text.upper( )) # append it by converting to uppercase if not wh_question: return False with nostderr(): try: wikiresult = wikipedia.search( query) # run a Wikipedia search with the query if len(wikiresult) == 0: # if there are no results result = "Sorry, " + user_prefix + ". But I couldn't find anything about " + query + " in Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result wikipage = wikipedia.page(wikiresult[0]) return self.model([wikipage.content], [com])[0][0] except requests.exceptions.ConnectionError: # if there is a connection error result = "Sorry, " + user_prefix + ". But I'm unable to connect to Wikipedia servers." if not is_server: userin.execute([" "], "Wikipedia connection error.") if not tts_output: print(result) if tts_output: userin.say(result) return result except wikipedia.exceptions.DisambiguationError as disambiguation: # if there is a disambiguation wikiresult = wikipedia.search( disambiguation.options[0] ) # run Wikipedia search again with the most common option except: result = "Sorry, " + user_prefix + ". But something went horribly wrong while I'm searching Wikipedia." if not tts_output and not is_server: print(result) if tts_output and not is_server: userin.say(result) return result