/__init__.py
Python | 178 lines | 144 code | 8 blank | 26 comment | 0 complexity | 2f12d0f9205e6795c9aca65f898fa5b5 MD5 | raw file
Possible License(s): GPL-3.0
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()