def deactivate_named_layer(self, name): if name in self.named_layers: i = self.named_layers[name] LOG.info("deactivating layer named: " + name) self.deactivate_layer(i) else: LOG.error("no layer named: " + name)
def add_channel(cls, channel): url = channel.get("stream") channel_id = cls.channel2id(channel) if url in [ch.get("stream") for idx, ch in cls.dead_channels.items()]: LOG.error("Channel has been previously flagged DEAD, refused to " "add channel") LOG.debug(str(channel)) return for idx, ch in cls.channels.items(): ch_url = ch["stream"] if url != ch_url: continue LOG.debug(f"Stream previously added: {url}") if is_compatible_dict(ch, channel): LOG.debug(f"merging channel data {channel_id}:{idx}") cls.channels[idx] = cls.create_merged_channel(ch, channel) return else: if channel_id in cls.channels: LOG.error(f"channel data doesn't " f"match, {channel_id} already in database") LOG.warning("refused to merge, replacing channel") LOG.info(f"Adding channel: {channel_id}") channel["expires"] = 0 channel["status"] = StreamStatus.UNKNOWN channel["_dead_counter"] = 0 cls.channels[channel_id] = channel
def remove_named_layer(self, name): if name in self.named_layers: i = self.named_layers[name] LOG.info("removing layer named: " + name) self.remove_layer(i) else: LOG.error("no layer named: " + name)
def __init__(self): path = join(enclosure2rootdir(), "mycroft", "configuration", "mycroft.conf") super().__init__(path) if not self.path or not isfile(self.path): LOG.error("mycroft root path not found, could not load default " ".conf")
def read(self): try: audio = self.queue.get(timeout=0.5) except Empty: return if audio is None: return tag, data, source = audio if tag == AUDIO_DATA: if data is not None: if self.state.sleeping: self.wake_up(data) else: self.process(data, source) elif tag == STREAM_START: self.stt.stream_start() elif tag == STREAM_DATA: self.stt.stream_data(data) elif tag == STREAM_STOP: self.stt.stream_stop() else: LOG.error("Unknown audio queue type %r" % audio)
def handle_binary(self, client, payload): audio_queue = self.clients[client.peer].get("audio_queue") if audio_queue: try: audio_queue.put(payload) except Exception as e: LOG.error("Could not put audio in queue: " + str(e))
def get_mycroft_marketplace_skills(branch:str=None, parse_github:bool=False, skiplist=None): skiplist = skiplist or [] data = get_marketplace_json(branch) for _, skill in data.items(): url = skill["repo"] branch = skill["tree"] if normalize_github_url(url) in skiplist: continue data = { "skillname": skill["display_name"], "foldername": skill["name"], "url": url, "branch": branch, "description": skill["description"], "authorname": skill["github_username"], "examples": skill["examples"], "category": skill["categories"][0], "tags": list(set(skill["tags"] + skill["categories"])), "platforms": skill["platforms"], "short_description": skill["short_desc"] } if parse_github: try: validate_branch(branch, url) except GithubInvalidBranch: LOG.error("branch : {branch} not available for skill: {skill}".format(branch=branch, skill=url)) continue if not is_valid_github_skill_url(url, branch): LOG.error("{skill} does not seem like a valid skill".format(skill=url)) continue yield SkillEntry.from_json(data, parse_github=parse_github)
def transcribe(self, audio): def send_unknown_intent(): """ Send message that nothing was transcribed. """ self.emitter.emit('recognizer_loop:speech.recognition.unknown') try: # Invoke the STT engine on the audio clip text = self.stt.execute(audio) if text is not None: text = text.lower().strip() LOG.debug("STT: " + text) else: send_unknown_intent() LOG.info('no words were transcribed') self.save_utt(text, audio) return text except sr.RequestError as e: LOG.error("Could not request Speech Recognition {0}".format(e)) except ConnectionError as e: LOG.error("Connection Error: {0}".format(e)) self.emitter.emit("recognizer_loop:no_internet") except RequestException as e: LOG.error(e.__class__.__name__ + ': ' + str(e)) except sr.UnknownValueError: LOG.error("Speech Recognition could not understand audio") except Exception as e: send_unknown_intent() LOG.exception(e) LOG.error("Speech Recognition Error") self.play_error() self.save_utt("", audio) return None
def install_skill(self, skill: SkillEntry, folder=None): """ Installs a SkillEntry with any required auth_token :param skill: Skill to install :param folder: Skills directory to install to (skill unpacked to {folder}/{skill.uuid}) """ self.emit("osm.install.start", {"folder": folder, "skill": skill.json}) store = None try: self.validate_appstore_name(skill.appstore) store = self.get_appstore(skill.appstore) store.authenticate(bootstrap=False) except Exception as e: LOG.error(e) self.emit("osm.install.error", { "folder": folder, "skill": skill.json, "error": str(e) }) try: skill.install(folder) except Exception as e: LOG.error(e) self.emit("osm.install.error", { "folder": folder, "skill": skill.json, "error": str(e) }) if store: store.clear_authentication() self.emit("osm.install.finish", { "folder": folder, "skill": skill.json })
def _read_data(): """ Writes the dictionary of state data from the IPC directory. Returns: dict: loaded state information """ managerIPCDir = os.path.join(get_ipc_directory(), "managers") path = os.path.join(managerIPCDir, "disp_info") permission = "r" if os.path.isfile(path) else "w+" if permission == "w+" and os.path.isdir(managerIPCDir) is False: os.makedirs(managerIPCDir) data = {} try: with open(path, permission) as dispFile: if os.stat(str(dispFile.name)).st_size != 0: data = json.load(dispFile) except Exception as e: LOG.error(e) os.remove(path) _read_data() return data
def get_youtube_audio_stream(url, download=False, convert=False): if pafy is None: LOG.error("can not extract audio stream, pafy is not available") LOG.info("pip install youtube-dl") LOG.info("pip install pafy") return url try: stream = pafy.new(url) except: return None stream = stream.getbestaudio() if not stream: return None if download: path = join(gettempdir(), url.split("watch?v=")[-1] + "." + stream.extension) if not exists(path): stream.download(path) if convert: mp3 = join(gettempdir(), url.split("watch?v=")[-1] + ".mp3") if not exists(mp3): # convert file to mp3 command = ["ffmpeg", "-n", "-i", path, "-acodec", "libmp3lame", "-ab", "128k", mp3] subprocess.call(command) return mp3 return path return stream.url
def replace_named_layer(self, name, intent_list=None): if name in self.named_layers: i = self.named_layers[name] LOG.info("replacing layer named: " + name) self.replace_layer(i, intent_list) else: LOG.error("no layer named: " + name)
def transcribe(self, audio): def send_unknown_intent(): """ Send message that nothing was transcribed. """ self.emitter.emit('recognizer_loop:speech.recognition.unknown') try: # Invoke the STT engine on the audio clip text = self.stt.execute(audio) if text is not None: text = text.lower().strip() LOG.debug("STT: " + text) else: send_unknown_intent() LOG.info('no words were transcribed') if self.save_utterances: mtd = self._compile_metadata(text) filename = os.path.join(self.saved_utterances_dir, mtd["name"]) with open(filename, 'wb') as f: f.write(audio.get_wav_data()) filename = os.path.join(self.saved_utterances_dir, mtd["name"].replace(".wav", ".json")) with open(filename, 'w') as f: json.dump(mtd, f, indent=4) return text except sr.RequestError as e: LOG.error("Could not request Speech Recognition {0}".format(e)) except ConnectionError as e: LOG.error("Connection Error: {0}".format(e)) self.emitter.emit("recognizer_loop:no_internet") except RequestException as e: LOG.error(e.__class__.__name__ + ': ' + str(e)) except Exception as e: send_unknown_intent() LOG.error(e) LOG.error("Speech Recognition could not understand audio") # If enabled, play a wave file with a short sound to audibly # indicate speech recognition failed sound = CONFIGURATION["listener"].get('error_sound') audio_file = resolve_resource_file(sound) try: if audio_file: if audio_file.endswith(".wav"): play_wav(audio_file).wait() elif audio_file.endswith(".mp3"): play_mp3(audio_file).wait() elif audio_file.endswith(".ogg"): play_ogg(audio_file).wait() else: play_audio(audio_file).wait() except Exception as e: LOG.warning(e) return None dialog_name = 'not connected to the internet' self.emitter.emit('speak', {'utterance': dialog_name})
def validate_connection(self): try: if not self.tts.voice: raise Exception("Polly TTS Voice not configured") output = self.tts.describe_voices() except NoCredentialsError: LOG.error('PollyTTS credentials not set') raise
def previous(self): LOG.info("Going to previous Intent Layer") self.current_layer -= 1 if self.current_layer < 0: self.current_layer = 0 LOG.error("Already in layer 0") else: self.activate_layer(self.current_layer)
def handle_incoming_mycroft(self, message): assert isinstance(message, Message) if message.msg_type == "speak": utterance = message.data["utterance"] self.speak(utterance) elif message.msg_type == "hive.complete_intent_failure": LOG.error("complete intent failure") self.speak('I don\'t know how to answer that')
def __init__(self, control=None): if alsaaudio is None: LOG.error("pyalsaaudio not installed") LOG.info("Run pip install pyalsaaudio==0.8.2") raise ImportError if control is None: control = alsaaudio.mixers()[0] self.get_mixer(control)
def step(callback=callback): try: if not self.finished: self.animate() if callback: callback(self) except Exception as e: LOG.error(e)
def remove_layer(self, layer_name): layer_name = f"{self.skill_id}:{layer_name}" if layer_name in self._layers: self.deactivate_layer(layer_name) LOG.info("removing layer named: " + layer_name) self._layers.pop(layer_name) else: LOG.error("no layer named: " + layer_name)
def deactivate_layer(self, layer_num): # error check if layer_num < 0 or layer_num > len(self.layers): LOG.error("invalid layer number") return False LOG.info("Deactivating Layer " + str(layer_num)) for intent_name in self.layers[layer_num]: self.disable_intent(intent_name) return True
def display(self): """ Display self.index in Pictures List of paths """ if len(self.pictures): pic = self.pictures[self.index] self.handle_window(pic) else: LOG.error("Nothing to window")
def async_volume_handler(self, vol): LOG.error("ASYNC SET VOL PASSED IN %s" % (vol,)) if vol > 1.0: vol = vol / 10 self.current_volume = vol LOG.error("ASYNC SET VOL TO %s" % (self.current_volume,)) # notify anybody listening on the bus who cares self.bus.emit(Message("hardware.volume", { "volume": self.current_volume}, context={"source": ["enclosure"]}))
def _respond(self, message): """ gather data and emit to bus """ try: if self.callback: self.callback(message) except Exception as e: LOG.error(e) self.service.respond(message)
def handle_speak_message(self, payload, client, tts_engine, tts_voice): utterance = payload["utterance"] try: audio_data = self.get_tts(utterance, tts_engine, tts_voice) client.sendMessage(audio_data, True) except Exception as e: LOG.error(f"Could not convert TTS due to {e}") return payload = json.dumps(payload) client.sendMessage(payload)
def deactivate_layer(self, layer_name): layer_name = f"{self.skill_id}:{layer_name}" if layer_name in self._layers: LOG.info("deactivating layer named: " + layer_name) if layer_name in self._active_layers: self._active_layers.remove(layer_name) for intent in self._layers[layer_name]: self.skill.disable_intent(intent) else: LOG.error("no layer named: " + layer_name)
def activate_layer(self, layer_name): layer_name = f"{self.skill_id}:{layer_name}" if layer_name in self._layers: LOG.info("activating layer named: " + layer_name) if layer_name not in self._active_layers: self._active_layers.append(layer_name) for intent in self._layers[layer_name]: self.skill.enable_intent(intent) else: LOG.error("no layer named: " + layer_name)
def handle_incoming_mycroft(self, message): assert isinstance(message, Message) if message.msg_type == "speak": utterance = message.data["utterance"] self.speak(utterance) if message.data["expect_response"]: self.loop.responsive_recognizer.trigger_listen() elif message.msg_type == "hive.complete_intent_failure": LOG.error("complete intent failure") self.speak('I don\'t know how to answer that')
def encrypt(key, text, nonce=None): if AES is None: LOG.error("run pip install pycryptodome") raise ImportError if not isinstance(text, bytes): text = bytes(text, encoding="utf-8") if not isinstance(key, bytes): key = bytes(key, encoding="utf-8") cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) ciphertext, tag = cipher.encrypt_and_digest(text) return ciphertext, tag, cipher.nonce
def handle_incoming_mycroft(self, message): assert isinstance(message, Message) addr = message.context.get("deltachat_user") if not addr: return if message.msg_type == "speak": utterance = message.data["utterance"] self.speak(utterance, addr) elif message.msg_type == "hive.complete_intent_failure": LOG.error("complete intent failure") self.speak('I don\'t know how to answer that', addr)
def handle_incoming_mycroft(self, message): assert isinstance(message, Message) user_data = message.context.get("user") if user_data: if message.msg_type == "speak": utterance = message.data["utterance"] self.speak(utterance, user_data) elif message.msg_type == "hive.complete_intent_failure": LOG.error("complete intent failure") utterance = 'I don\'t know how to answer that' self.speak(utterance, user_data)