/__init__.py
Python | 178 lines | 144 code | 8 blank | 26 comment | 0 complexity | 2f12d0f9205e6795c9aca65f898fa5b5 MD5 | raw file
Possible License(s): GPL-3.0
- # -*- coding: utf-8 -*-
- # TODO: Add an appropriate license to your skill before publishing. See
- # the LICENSE file for more information.
- # Below is the list of outside modules you'll be using in your skill.
- # They might be built-in to Python, from mycroft-core or from external
- # libraries. If you use an external library, be sure to include it
- # in the requirements.txt file so the library is installed properly
- # when the skill gets installed later by a user.
- from os.path import dirname, abspath, join
- from adapt.intent import IntentBuilder
- from mycroft.skills.core import MycroftSkill, intent_handler
- from mycroft.util.log import LOG
- from googletrans import Translator
- import os # for setting google credentials
- import urllib2 # for http requests
- from pprint import pprint # for pretty printing json
- import json # for parsing json
- import sys
- import paho.mqtt.client as mqtt
- from mycroft.skills.skill_data import load_regex
- from mycroft.configuration.Constants import *
- # Each skill is contained within its own class, which inherits base methods
- # from the MycroftSkill class. You extend this class as shown below.
- # TODO: Change "Template" to a unique name for your skill
- class Search(MycroftSkill):
- # Let's define the class objects here.
- ddg_topic_summaries_endpoint = "https://api.duckduckgo.com/?q={}&format=json&pretty=1"
- ddg_search_topic_details_endpoint = "{}?ia=about&format=json"
- limit = 3
- numbers = {0: "शून्य", 1: "एक", 2: "दो", 3: "तीन", 4: "चार", 5: "पाँच", 6: "छः", 7: "सात", 8: "आठ", 9: "नौ",
- 10: "दस"}
- search_results = []
- # The constructor of the skill, which calls MycroftSkill's constructor
- def __init__(self):
- super(Search, self).__init__(name="Search")
- # Initialize working variables used within the skill.
- self.count = 0
- self.translator = Translator()
- reload(sys)
- sys.setdefaultencoding('utf8')
- def initialize(self):
- #load_regex(self.regex_dir, self.emitter, self.skill_id)
- self.add_tag_handler("KnowMoreDuckDuckGo", self.handle_know_more_search)
- # The "handle_xxxx_intent" function is triggered by Mycroft when the
- # skill's intent is matched. The intent is defined by the IntentBuilder()
- # pieces, and is triggered when the user's utterance matches the pattern
- # defined by the keywords. In this case, the match occurs when one word
- # is found from each of the files:
- # vocab/en-us/Hello.voc
- # vocab/en-us/World.voc
- # In this example that means it would match on utterances like:
- # 'Hello world'
- # 'Howdy you great big world'
- # 'Greetings planet earth'
- @intent_handler(IntentBuilder("").require("Query"))
- def handle_search_intent(self, message):
- # In this case, respond by simply speaking a canned response.
- # Mycroft will randomly speak one of the lines from the file
- # dialogs/en-us/hello.world.dialog
- # if message.data.get('topic') is None and message.data.get('w_topic') is None:
- # LOG.info("===> Couldn't find topic")
- # LOG.info(message.data)
- # else:
- # LOG.info("===> found topic")
- # LOG.info(message.data.keys())
- # LOG.info(message.data)
- # LOG.info(message.data["w_topic"])
- LOG.info("Handle search called")
- translation = self.translator.translate(message.data.get("Query"), dest='en').text
- # LOG.info(translation['translatedText'])
- query = "+".join(translation.split(" "))
- endpoint = self.ddg_topic_summaries_endpoint.format(query)
- # #ctx = ssl._create_unverified_context()
- #
- contents = urllib2.urlopen(endpoint).read()
- data = json.loads(contents)
- LOG.info(data)
- #
- abstract = data["AbstractText"]
- if abstract:
- abstract_text_hindi = self.translator.translate(abstract, src='hi').text
- LOG.info(abstract_text_hindi)
- message.data["speak"] = abstract_text_hindi
- self.publish(message.data[MESSAGE_TOPIC], message.data)
- return
- else:
- array = []
- search_results = []
- message.data["context"] = {}
- for i, topic in enumerate(data["RelatedTopics"]):
- if not ("Text" in topic):
- continue
- text = topic["Text"]
- if text.find("...") != -1:
- text = text.split("...")[0]
- if text.find(".") != -1:
- text = text[:text.rfind(".")]
- elif text.find("!") != -1:
- text = text[:text.rfind("!")]
- elif text.find(";") != -1:
- text = text[:text.rfind(";")]
- elif text.find(",") != -1:
- text = text[:text.rfind(",")]
- else:
- text = text
- abstract_text_hindi = self.translator.translate(text, src='hi').text
- array.append(self.numbers[i + 1] + ", " + abstract_text_hindi + ", की बात कर रहे हैं?")
- search_results.append({"text": abstract_text_hindi, "url": topic["FirstURL"]})
- if i == self.limit - 1:
- break
- LOG.info("+==========+")
- message.data["context"]["options"] = search_results
- message.data["tags"] = ["KnowMoreDuckDuckGo"]
- message.data["speak"] = 'मुझे ' + message.data.get("Query") + 'के बारे में बहुतेरे रिजल्ट मिले हैं। क्या आप' + " या, ".join(array)
- self.publish(message.data[MESSAGE_TOPIC], message.data)
- # @intent_handler(IntentBuilder("").require('SelectSearch')
- # .require('KnowMoreContext').build())
- def handle_know_more_search(self, message):
- LOG.info("Know more called!!")
- LOG.info(self.local_regex)
- LOG.info("Know more called!!")
- regex_result = self.fill_message_using_regex(message.data.get("utterances")[0], "select.search")
- LOG.info("Know more called1!!")
- message.data["tags"] = []
- if "SelectSearch" not in regex_result:
- LOG.info("Not able to match regex")
- return
- LOG.info("Know more called!!")
- search_select = regex_result.get("SelectSearch")
- search_results = message.data["context"]["options"]
- # here we need to calculate the distance in sets of the query SelectSearch
- # and the variables we have stored in self.search_results. Whichever has the least
- # distance, we should output the DDG results from that link
- input_set = set(map(lambda x: x.lower(), search_select.split(" ")))
- count = sys.maxint
- select = -1
- for i, entry in enumerate(search_results):
- super_set = set(map(lambda x: x.lower(), entry["text"].split(" ")))
- if len(input_set - super_set) < count:
- count = len(input_set - super_set)
- select = i
- if select == -1:
- message.data["speak"] = "माफ कीजिएगा किसी परेशानी की वजह से हम बैकएंड से अपडेट नहीं ला पाए। कृपया दुबारा कोशिश करें"
- else:
- endpoint = self.ddg_search_topic_details_endpoint.format(search_results[select]["url"])
- contents = urllib2.urlopen(endpoint).read()
- data = json.loads(contents)
- abstract = data["AbstractText"]
- if abstract:
- abstract_text_hindi = self.translator.translate(abstract, src='hi').text
- message.data["speak"] = abstract_text_hindi
- else:
- message.data["speak"] = "माफ कीजिएगा किसी परेशानी की वजह से हम बैकएंड से अपडेट नहीं ला पाए। कृपया दुबारा कोशिश करें"
- self.publish(message.data[MESSAGE_TOPIC], message.data)
- # The "create_skill()" method is used to create an instance of the skill.
- # Note that it's outside the class itself.
- def create_skill():
- return Search()