예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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
예제 #7
0
    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)
예제 #8
0
    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
예제 #9
0
    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
예제 #10
0
    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