PageRenderTime 34ms CodeModel.GetById 1ms app.highlight 26ms RepoModel.GetById 3ms app.codeStats 0ms

/__init__.py

https://bitbucket.org/khagesh93/search-skill
Python | 178 lines | 144 code | 8 blank | 26 comment | 0 complexity | 2f12d0f9205e6795c9aca65f898fa5b5 MD5 | raw file
  1# -*- coding: utf-8 -*-
  2# TODO: Add an appropriate license to your skill before publishing.  See
  3# the LICENSE file for more information.
  4
  5# Below is the list of outside modules you'll be using in your skill.
  6# They might be built-in to Python, from mycroft-core or from external
  7# libraries.  If you use an external library, be sure to include it
  8# in the requirements.txt file so the library is installed properly
  9# when the skill gets installed later by a user.
 10from os.path import dirname, abspath, join
 11
 12from adapt.intent import IntentBuilder
 13from mycroft.skills.core import MycroftSkill, intent_handler
 14from mycroft.util.log import LOG
 15from googletrans import Translator
 16import os  # for setting google credentials
 17import urllib2  # for http requests
 18from pprint import pprint  # for pretty printing json
 19import json  # for parsing json
 20import sys
 21import paho.mqtt.client as mqtt
 22from mycroft.skills.skill_data import load_regex
 23
 24from mycroft.configuration.Constants import *
 25
 26# Each skill is contained within its own class, which inherits base methods
 27# from the MycroftSkill class.  You extend this class as shown below.
 28
 29# TODO: Change "Template" to a unique name for your skill
 30class Search(MycroftSkill):
 31    # Let's define the class objects here.
 32    ddg_topic_summaries_endpoint = "https://api.duckduckgo.com/?q={}&format=json&pretty=1"
 33    ddg_search_topic_details_endpoint = "{}?ia=about&format=json"
 34    limit = 3
 35    numbers = {0: "शून्य", 1: "एक", 2: "दो", 3: "तीन", 4: "चार", 5: "पाँच", 6: "छः", 7: "सात", 8: "आठ", 9: "नौ",
 36               10: "दस"}
 37    search_results = []
 38
 39    # The constructor of the skill, which calls MycroftSkill's constructor
 40    def __init__(self):
 41        super(Search, self).__init__(name="Search")
 42        # Initialize working variables used within the skill.
 43        self.count = 0
 44        self.translator = Translator()
 45        reload(sys)
 46        sys.setdefaultencoding('utf8')
 47
 48    def initialize(self):
 49        #load_regex(self.regex_dir, self.emitter, self.skill_id)
 50        self.add_tag_handler("KnowMoreDuckDuckGo", self.handle_know_more_search)
 51
 52    # The "handle_xxxx_intent" function is triggered by Mycroft when the
 53    # skill's intent is matched.  The intent is defined by the IntentBuilder()
 54    # pieces, and is triggered when the user's utterance matches the pattern
 55    # defined by the keywords.  In this case, the match occurs when one word
 56    # is found from each of the files:
 57    #    vocab/en-us/Hello.voc
 58    #    vocab/en-us/World.voc
 59    # In this example that means it would match on utterances like:
 60    #   'Hello world'
 61    #   'Howdy you great big world'
 62    #   'Greetings planet earth'
 63    @intent_handler(IntentBuilder("").require("Query"))
 64    def handle_search_intent(self, message):
 65        # In this case, respond by simply speaking a canned response.
 66        # Mycroft will randomly speak one of the lines from the file
 67        #    dialogs/en-us/hello.world.dialog
 68        # if message.data.get('topic') is None and message.data.get('w_topic') is None:
 69        #     LOG.info("===> Couldn't find topic")
 70        #     LOG.info(message.data)
 71        # else:
 72        #     LOG.info("===> found topic")
 73        #     LOG.info(message.data.keys())
 74        #     LOG.info(message.data)
 75        #     LOG.info(message.data["w_topic"])
 76        LOG.info("Handle search called")
 77
 78
 79        translation = self.translator.translate(message.data.get("Query"), dest='en').text
 80
 81        # LOG.info(translation['translatedText'])
 82        query = "+".join(translation.split(" "))
 83
 84        endpoint = self.ddg_topic_summaries_endpoint.format(query)
 85        # #ctx = ssl._create_unverified_context()
 86        #
 87        contents = urllib2.urlopen(endpoint).read()
 88        data = json.loads(contents)
 89        LOG.info(data)
 90        #
 91
 92        abstract = data["AbstractText"]
 93        if abstract:
 94            abstract_text_hindi = self.translator.translate(abstract, src='hi').text
 95            LOG.info(abstract_text_hindi)
 96            message.data["speak"] = abstract_text_hindi
 97            self.publish(message.data[MESSAGE_TOPIC], message.data)
 98            return
 99        else:
100            array = []
101            search_results = []
102            message.data["context"] = {}
103            for i, topic in enumerate(data["RelatedTopics"]):
104                if not ("Text" in topic):
105                    continue
106                text = topic["Text"]
107
108                if text.find("...") != -1:
109                    text = text.split("...")[0]
110                    if text.find(".") != -1:
111                        text = text[:text.rfind(".")]
112                    elif text.find("!") != -1:
113                        text = text[:text.rfind("!")]
114                    elif text.find(";") != -1:
115                        text = text[:text.rfind(";")]
116                    elif text.find(",") != -1:
117                        text = text[:text.rfind(",")]
118                    else:
119                        text = text
120                abstract_text_hindi = self.translator.translate(text, src='hi').text
121                array.append(self.numbers[i + 1] + ", " + abstract_text_hindi + ", की बात कर रहे हैं?")
122                search_results.append({"text": abstract_text_hindi, "url": topic["FirstURL"]})
123                if i == self.limit - 1:
124                    break
125            LOG.info("+==========+")
126            message.data["context"]["options"] = search_results
127            message.data["tags"] = ["KnowMoreDuckDuckGo"]
128            message.data["speak"] = 'मुझे ' + message.data.get("Query") +  'के बारे में बहुतेरे रिजल्ट मिले हैं। क्या आप' + " या, ".join(array)
129            self.publish(message.data[MESSAGE_TOPIC], message.data)
130
131    # @intent_handler(IntentBuilder("").require('SelectSearch')
132    #                 .require('KnowMoreContext').build())
133    def handle_know_more_search(self, message):
134        LOG.info("Know more called!!")
135        LOG.info(self.local_regex)
136        LOG.info("Know more called!!")
137        regex_result = self.fill_message_using_regex(message.data.get("utterances")[0], "select.search")
138        LOG.info("Know more called1!!")
139        message.data["tags"] = []
140        if "SelectSearch" not in regex_result:
141            LOG.info("Not able to match regex")
142            return
143        LOG.info("Know more called!!")
144
145        search_select = regex_result.get("SelectSearch")
146        search_results = message.data["context"]["options"]
147        # here we need to calculate the distance in sets of the query SelectSearch
148        # and the variables we have stored in self.search_results. Whichever has the least
149        # distance, we should output the DDG results from that link
150        input_set = set(map(lambda x: x.lower(), search_select.split(" ")))
151        count = sys.maxint
152        select = -1
153        for i, entry in enumerate(search_results):
154            super_set = set(map(lambda x: x.lower(), entry["text"].split(" ")))
155            if len(input_set - super_set) < count:
156                count = len(input_set - super_set)
157                select = i
158        if select == -1:
159            message.data["speak"] = "माफ कीजिएगा किसी परेशानी की वजह से हम बैकएंड से अपडेट नहीं ला पाए। कृपया दुबारा कोशिश करें"
160        else:
161            endpoint = self.ddg_search_topic_details_endpoint.format(search_results[select]["url"])
162
163            contents = urllib2.urlopen(endpoint).read()
164            data = json.loads(contents)
165
166            abstract = data["AbstractText"]
167            if abstract:
168                abstract_text_hindi = self.translator.translate(abstract, src='hi').text
169                message.data["speak"] = abstract_text_hindi
170            else:
171                message.data["speak"] = "माफ कीजिएगा किसी परेशानी की वजह से हम बैकएंड से अपडेट नहीं ला पाए। कृपया दुबारा कोशिश करें"
172        self.publish(message.data[MESSAGE_TOPIC], message.data)
173
174
175# The "create_skill()" method is used to create an instance of the skill.
176# Note that it's outside the class itself.
177def create_skill():
178    return Search()