def handleForever(self): """Delegates user input to the handling function when activated.""" initial_threshold = None #self.mic.fetchThreshold(RATE=48000, CHUNK=8192, THRESHOLD_TIME=4, AVERAGE_TIME=4) repeat = True while repeat: # Print notifications until empty notifications = self.notifier.getAllNotifications() for notif in notifications: notif = str_formater.unicodeToUTF8(notif, self.logger) self.logger.info("Got new notification: %s" % notif) #self.mic.say(notif) try: threshold, transcribed = self.mic.passiveListen() except KeyboardInterrupt: threshold = None repeat = False except: self.logger.critical("fatal error processing passive listen", exc_info=True) continue if threshold: if transcribed: input = transcribed else: input = self.mic.activeListen(initial_threshold, RATE=44100, CHUNK=8196, LISTEN_TIME=6, AVERAGE_TIME=5) input = str_formater.unicodeToUTF8(input, self.logger) self.logger.debug("got input %s" % (input)) if input: if any(x in input.upper() for x in ["KONIEC"]): repeat = False self.logger.info("Quiting after voice request") self.mic.say("Kończę pracę. Do usłyszenia.") #elif any(x in input.upper().replace('ł','Ł') for x in ["PRZEŁADUJ"]): elif any(x in upperUTF8(input) for x in ["PRZEŁADUJ"]): self.brain.reload_modules() elif any(x in upperUTF8(input) for x in ["ECHO"]): self.mic.say(input) #self.mic.play(input) else: self.delegateInput(input) else: self.mic.say("Powtórz proszę.")
def transcribe(self, audio_file_path, PERSONA_ONLY=False, MUSIC=False): """ Performs STT, transcribing an audio file and returning the result. Arguments: audio_file_path -- the path to the audio file to-be transcribed PERSONA_ONLY -- if True, uses the 'Persona' language model and dictionary MUSIC -- if True, uses the 'Music' language model and dictionary """ wavFile = file(audio_file_path, 'rb') wavFile.seek(44) if MUSIC: self.speechRec_music.decode_raw(wavFile) result = self.speechRec_music.get_hyp() elif PERSONA_ONLY: self.speechRec_persona.decode_raw(wavFile) result = self.speechRec_persona.get_hyp() else: self.speechRec.decode_raw(wavFile) result = self.speechRec.get_hyp() result = result[0].decode('utf-8') result = str_formater.unicodeToUTF8(result, self.logger) self.logger.info("===================") self.logger.info("YOU: " + result) self.logger.info("===================") return result
def transcribe(self, audio_file_path, PERSONA_ONLY=False, MUSIC=False): """ Performs STT, transcribing an audio file and returning the result. Arguments: audio_file_path -- the path to the audio file to-be transcribed PERSONA_ONLY -- if True, uses the 'Persona' language model and dictionary MUSIC -- if True, uses the 'Music' language model and dictionary """ wavFile = file(audio_file_path, 'rb') wavFile.seek(44) if MUSIC: self.speechRec_music.decode_raw(wavFile) result = self.speechRec_music.get_hyp() elif PERSONA_ONLY: self.speechRec_persona.decode_raw(wavFile) result = self.speechRec_persona.get_hyp() else: self.speechRec.decode_raw(wavFile) result = self.speechRec.get_hyp() result = result[0].decode('utf-8') result = str_formater.unicodeToUTF8(result, self.logger) self.logger.info("===================") self.logger.info("YOU: " + result ) self.logger.info("===================") return result
def activeListen(self, THRESHOLD=None, LISTEN=True, MUSIC=False): if not LISTEN: return self.prev input = raw_input("YOU: ") input = str_formater.unicodeToUTF8(input, self.logger) self.prev = input return input
def handleForever(self): """Delegates user input to the handling function when activated.""" initial_threshold = None #self.mic.fetchThreshold(RATE=48000, CHUNK=8192, THRESHOLD_TIME=4, AVERAGE_TIME=4) repeat = True while repeat: # Print notifications until empty notifications = self.notifier.getAllNotifications() for notif in notifications: notif = str_formater.unicodeToUTF8(notif, self.logger) self.logger.info("Got new notification: %s" % notif ) #self.mic.say(notif) try: threshold, transcribed = self.mic.passiveListen() except KeyboardInterrupt: threshold = None repeat = False except: self.logger.critical("fatal error processing passive listen", exc_info=True) continue if threshold: if transcribed: input = transcribed else: input = self.mic.activeListen(initial_threshold, RATE=44100, CHUNK=8196, LISTEN_TIME=6, AVERAGE_TIME=5) input = str_formater.unicodeToUTF8(input, self.logger) self.logger.debug("got input %s" % (input)) if input: if any(x in input.upper() for x in ["KONIEC"]): repeat = False self.logger.info("Quiting after voice request") self.mic.say("Kończę pracę. Do usłyszenia.") #elif any(x in input.upper().replace('ł','Ł') for x in ["PRZEŁADUJ"]): elif any(x in upperUTF8(input) for x in ["PRZEŁADUJ"]): self.brain.reload_modules() elif any(x in upperUTF8(input) for x in ["ECHO"]): self.mic.say(input) #self.mic.play(input) else: self.delegateInput(input) else: self.mic.say("Powtórz proszę.")
def parseDayOfWeek(text, logger): loc = arrow.locales.get_locale('pl') res = None for d in range(7): dow = loc.day_name(d+1) dow = str_formater.unicodeToUTF8(dow, logger) if dow.lower() in text: res = d break return res
def passiveListen(self, PERSONA): try: text = raw_input("You: ") text = str_formater.unicodeToUTF8(text, self.logger) except KeyboardInterrupt: return (True, "koniec") self.logger.info("Got %s; is waiting for %s" % (text, PERSONA)) if text.upper() == PERSONA or text == "": return (True, None) else: return (True, text)
def useIvonaTTS(self, phrase): try: #cmd = "wget -q --restrict-file-names=nocontrol --referer=\"http://translate.google.com\" -U Mozilla -O say.mp3 \"http://translate.google.com/translate_tts?ie=UTF-8&tl=pl&q=%s\" && avconv -y -v quiet -i say.mp3 -f wav say.wav" % phrase audio_file = "say.mp3" self.logger.debug("command for ivona translator: %s" % phrase) phrase = str_formater.unicodeToUTF8(phrase, self.logger) res = self.ivona.fetch_voice(phrase, audio_file) self.logger.debug("ivona res: %s" % repr(res)) except: self.logger.critical("fatal error using ivona tts", exc_info=True) return audio_file
def activeListen(self, THRESHOLD=None, LISTEN=True, MUSIC=False): if self.first_run: self.first_run = False return "" if not LISTEN: return self.prev stop = False while not stop: input = self.pipein.readline()[:-1] if input: stop = True input = str_formater.unicodeToUTF8(input, self.logger) self.prev = input return input
def handleFacebookNotifications(self, lastDate): oauth_access_token = self.profile['keys']['FB_TOKEN'] graph = GraphAPI(oauth_access_token) results = [] try: results = graph.request("me/notifications") except GraphAPIError: self.logger.error( "error getting response form facebook api, for key: %s" % oauth_access_token, exc_info=True) return except: self.logger.error( "error getting response form facebook api, for key: %s" % oauth_access_token, exc_info=True) if not len(results['data']) or not results.has_key('summary'): self.logger.debug("Brak nowych powiadomień na Fejsbuku: %s" % repr(results)) return updates = [] updated_time = results['summary']['updated_time'] self.logger.debug(results['summary']['updated_time']) count = len(results['data']) if count == 1: self.q.put('Masz nowe powiadomienie z Facebooka') else: self.q.put('Masz nowe powiadomienia z Facebooka') for notification in results['data']: #str_formater.checkFormat(notification['title'], self.logger) title = str_formater.unicodeToUTF8(notification['title'], self.logger) #updates.append(title) if updated_time > lastDate: self.q.put(title) self.logger.debug("from:" + repr(notification['from']) + " to:" + repr(notification['to']) + " created_time:" + repr(notification['created_time']) + " unread:" + repr(notification['unread'])) #count = len(results['data']) #mic.say("Masz " + str(count) + " nowych powiadomień na Fejsbuku.|" + "| ".join(updates) ) return updated_time
def emailUser(profile, logger, SUBJECT="", BODY=""): """ Sends an email. Arguments: profile -- contains information related to the user (e.g., email address) SUBJECT -- subject line of the email BODY -- body text of the email """ def generateSMSEmail(profile): """Generates an email from a user's phone number based on their carrier.""" if profile['carrier'] is None or not profile['phone_number']: return None return str(profile['phone_number']) + "@" + profile['carrier'] if profile['prefers_email'] and profile['gmail_address']: # add footer if BODY: B = profile['first_name'] B += ",<br><br>Oto twoje wiadomości:" B += str_formater.unicodeToUTF8(BODY, logger) B += "<br>Wysłane przez osobistego asystenta" BODY = B recipient = profile['gmail_address'] if profile['first_name'] and profile['last_name']: recipient = profile['first_name'] + " " + \ profile['last_name'] + " <%s>" % recipient else: recipient = generateSMSEmail(profile) if not recipient: return False try: if 'mailgun' in profile: user = profile['mailgun']['username'] password = profile['mailgun']['password'] server = 'smtp.mailgun.org' else: user = profile['gmail_address'] password = profile['gmail_password'] server = 'smtp.gmail.com' sendEmail(SUBJECT, BODY, recipient, user, "Jasper <jasper>", password, server, logger) return True except: return False
def useTTS(self, phrase): try: #cmd = "wget -q --restrict-file-names=nocontrol --referer=\"http://translate.google.com\" -U Mozilla -O say.mp3 \"http://translate.google.com/translate_tts?ie=UTF-8&tl=pl&q=%s\" && avconv -y -v quiet -i say.mp3 -f wav say.wav" % phrase audio_file = None self.logger.debug("command for google translator: %s" % phrase) phrase = str_formater.unicodeToUTF8(phrase, self.logger) cmd = ["/home/osmc/jasper/client/tts.sh", phrase] res = subprocess.call(cmd) if res == 0: audio_file = "say.mp3" except: self.logger.critical("fatal error using google tts", exc_info=True) return audio_file
def transcribe(self, audio_file_path, PERSONA_ONLY=False, MUSIC=False): """ Performs STT via the Google Speech API, transcribing an audio file and returning an English string. Arguments: audio_file_path -- the path to the .wav file to be transcribed """ url = "https://www.google.com/speech-api/v2/recognize?output=json&client=chromium&key=%s&lang=%s&maxresults=6&pfilter=2" % ( self.api_key, "pl-PL") wav = open(audio_file_path, 'rb') data = wav.read() wav.close() f = open_audio(audio_file_path, 'r') frame_rate = f.getframerate() f.close() try: req = urllib2.Request(url, data=data, headers={ 'Content-type': 'audio/l16; rate=%s' % str(frame_rate) }) self.logger.debug("google speech api url: %s frame rate: %d" % (url, frame_rate)) response_url = urllib2.urlopen(req) response_read = response_url.read() self.logger.debug("raw response: %s" % repr(response_read)) response_read = response_read.decode('utf-8') if response_read == '{"result":[]}\n': text = None else: decoded = json.loads(response_read.split("\n")[1]) #self.logger.debug("decoded response: %s" % repr(response_read.decode('utf-8'))) text = decoded['result'][0]['alternative'][0]['transcript'] text = str_formater.unicodeToUTF8(text, self.logger) if text: self.logger.info("<<<<<<<<<<<<<<<<<<<") self.logger.info("YOU: " + text) self.logger.info("<<<<<<<<<<<<<<<<<<<") return text except Exception: traceback.print_exc() self.logger.error("Failed to transcribe data: %s" % audio_file_path, exc_info=True)
def activeListen(self, THRESHOLD=None, LISTEN=True, MUSIC=False): data = None self.logger.debug('socket:: activeListen') if not self.last_msg: # send ENQuiry - now we're actively waiting for input from client self.broadcast_message(chr(5)) data = self.process_communication(self.timeout_active) while not data: data = self.process_communication(self.timeout_active) else: data = self.last_msg self.last_msg = "" input_str = str_formater.unicodeToUTF8(data, self.logger) return input_str
def passiveListen(self, PERSONA): """ Listens for PERSONA in everyday sound. Times out after LISTEN_TIME, so needs to be restarted. """ # check if no threshold provided #if self.THRESHOLD == 0: # self.THRESHOLD = self.fetchThreshold() text = raw_input("You: ") text = str_formater.unicodeToUTF8(text, self.logger) self.logger.info("Got %s; is waiting for %s" % (text, PERSONA)) if text.upper() == PERSONA or text == "": return (True, PERSONA) else: return (False, text)
def handle(text, mic, profile, logger, modules): """ Responds to user-input, typically speech text, with a summary of the user's Facebook notifications, including a count and details related to each individual notification. Arguments: text -- user-input, typically transcribed speech mic -- used to interact with the user (for both input and output) profile -- contains information related to the user (e.g., phone number) """ oauth_access_token = profile['keys']['FB_TOKEN'] graph = GraphAPI(oauth_access_token) try: results = graph.request("me/notifications") except GraphAPIError: logger.error("error getting response form facebook api, for key: %s" % oauth_access_token, exc_info=True) mic.say( "Nie mam uprawnienia do twojego konta na Fejsbuku. Sprawdź ustawienia.") return except: logger.error("error getting response form facebook api, for key: %s" % oauth_access_token, exc_info=True) mic.say( "Wybacz, ale ta usługa jest chwilowo niedostępna.") if not len(results['data']): mic.say("Brak nowych powiadomień na Fejsbuku") return updates = [] logger.debug(results) if results['data']: for notification in results['data']: #str_formater.checkFormat(notification['title'], logger) title = str_formater.unicodeToUTF8(notification['title'], logger) updates.append(title) logger.debug("from:" + repr(notification['from']) + " to:" + repr(notification['to']) + " created_time:" + repr(notification['created_time']) + " unread:" + repr(notification['unread']) ) count = len(results['data']) mic.say("Masz " + str(count) + " nowych powiadomień na Fejsbuku.|" + "| ".join(updates) ) return
def transcribe(self, audio_file_path, PERSONA_ONLY=False, MUSIC=False): """ Performs STT via the Google Speech API, transcribing an audio file and returning an English string. Arguments: audio_file_path -- the path to the .wav file to be transcribed """ url = "https://www.google.com/speech-api/v2/recognize?output=json&client=chromium&key=%s&lang=%s&maxresults=6&pfilter=2" % ( self.api_key, "pl-PL") wav = open(audio_file_path, 'rb') data = wav.read() wav.close() f = open_audio(audio_file_path, 'r') frame_rate = f.getframerate() f.close() try: req = urllib2.Request( url, data=data, headers={ 'Content-type': 'audio/l16; rate=%s' % str(frame_rate)}) self.logger.debug("google speech api url: %s frame rate: %d" % (url, frame_rate)) response_url = urllib2.urlopen(req) response_read = response_url.read() self.logger.debug("raw response: %s" % repr(response_read)) response_read = response_read.decode('utf-8') if response_read == '{"result":[]}\n': text = None else: decoded = json.loads(response_read.split("\n")[1]) #self.logger.debug("decoded response: %s" % repr(response_read.decode('utf-8'))) text = decoded['result'][0]['alternative'][0]['transcript'] text = str_formater.unicodeToUTF8(text, self.logger) if text: self.logger.info("<<<<<<<<<<<<<<<<<<<") self.logger.info("YOU: " + text ) self.logger.info("<<<<<<<<<<<<<<<<<<<") return text except Exception: traceback.print_exc() self.logger.error("Failed to transcribe data: %s" % audio_file_path, exc_info=True)
def activeListen(self, THRESHOLD=None, LISTEN=True, MUSIC=False): #if self.first_run: # self.first_run = False # return "" #if not LISTEN: # return self.prev stop = False data = "" #while not stop: if self.connection == None: self.logger.debug('waiting for a connection') self.connection, self.client_address = self.sock.accept() self.logger.debug('client connected: %s' % client_address) try: #print >>sys.stderr, 'client connected:', client_address #while True: data_size = connection.recv(1) if data_size: data_size = ord(data_size) self.logger.debug('received size %d' % (data_size)) else: raise Exception('Socket Connection Error', 'got empty str instead of message size') data = connection.recv(data_size) self.logger.debug('received "%s"' % data) if data: #connection.sendall(data) if data == "stop": stop = True #break else: #self.connection = None raise Exception('Socket Connection Error', 'got empty str instead of message data') except: #self.connection.close() self.connection = None input = str_formater.unicodeToUTF8(data, self.logger) self.prev = input return input
def handle(text, mic, profile, logger, modules): """ Responds to user-input, typically speech text, with a summary of the relevant weather for the requested date (typically, weather information will not be available for days beyond tomorrow). Arguments: text -- user-input, typically transcribed speech mic -- used to interact with the user (for both input and output) profile -- contains information related to the user (e.g., phone number) """ if not profile['location']: mic.say( "Wybacz, ale nie mogę podać prognozy pogody. Wprowadź proszę w ustawieniach miasto.") return mic.say("Pobieram prognozę pogody...") #str_formater.checkFormat(text, logger) text = str_formater.unicodeToUTF8(text, logger) tz = getTimezone(profile) service = DateService(tz=tz) loc = arrow.locales.get_locale('pl') #loc.day_name(1).lower() #date = service.extractDay(text) #if not date: dow = parseDayOfWeek(text.lower(), logger) if dow: now_dow = arrow.utcnow().weekday() if dow > now_dow: date = arrow.utcnow().replace(days=dow - now_dow) else: date = arrow.utcnow().replace(days=dow - now_dow + 7) if 'dzisiaj' in text.lower(): date = arrow.utcnow() elif 'jutro' in text.lower(): date = arrow.utcnow().replace(days=+1) elif 'pojutrze' in text.lower(): date = arrow.utcnow().replace(days=+2) else: date = arrow.utcnow() weekday = loc.day_name(date.weekday()+1).lower() weekday = str_formater.unicodeToUTF8(weekday, logger).replace('Ś','ś') if date.weekday() == arrow.utcnow().weekday(): date_keyword = "dzisiaj" elif date.weekday() == arrow.utcnow().replace(days=+1).weekday(): date_keyword = "jutro" else: date_keyword = weekday #logger.debug("date_keyword %s weekday %s" % (date_keyword, weekday)) forecast = getForecast(profile) output = "" #weekday = 'niedziela' #for entry in forecast: # print entry['title'] for entry in forecast: try: entry = str_formater.unicodeToUTF8(entry, logger) #str_formater.checkFormat(entry['title'].split()[0].strip().lower(), logger) date_desc = entry['title'].split()[0].strip().lower().replace('Ś','ś') #logger.debug('date_desc %s' % date_desc) if date_desc == 'prognoza': #For global forecasts date_desc = entry['title'].split()[2].strip().lower().replace('Ś','ś') #logger.debug('date_desc %s' % date_desc) weather_desc = entry['summary_detail']['value'] elif date_desc == 'obecne': #For first item of global forecasts output += "Obecne warunki pogodowe:|" + \ parseCurrentConditions(entry['summary_detail']['value']) + "| " continue else: weather_desc = entry['summary_detail']['value'].split('|')[1] #US forecasts if weekday == date_desc: output += "Prognoza pogody na " + \ date_keyword + ',| ' + weather_desc break except: logger.error("error parsing forecast", exc_info=True) if output: output = replaceAcronyms(output) mic.say(output) else: mic.say( "Wybacz, ale brak prognozy")