def validate_connection(self): try: subprocess.call([BIN, '--version']) except Exception: LOG.info("Failed to find mimic at: " + BIN) raise Exception( 'Mimic was not found. Run install-mimic.sh to install it.')
def load_module(module, hotword, config, lang, loop): LOG.info('Loading "{}" wake word via {}'.format(hotword, module)) instance = None complete = Event() def initialize(): nonlocal instance, complete try: clazz = HotWordFactory.CLASSES[module] instance = clazz(hotword, config, lang=lang) except TriggerReload: complete.set() sleep(0.5) loop.reload() except NoModelAvailable: LOG.warning('Could not found find model for {} on {}.'.format( hotword, module )) instance = None except Exception: LOG.exception( 'Could not create hotword. Falling back to default.') instance = None complete.set() Thread(target=initialize, daemon=True).start() if not complete.wait(INIT_TIMEOUT): LOG.info('{} is taking too long to load'.format(module)) complete.set() return instance
def on_message(self, event): post = event["data"]["post"] post = json.loads(post) sender = event["data"]["sender_name"] msg = post["message"] channel_id = post["channel_id"] user_id = post["user_id"] channel_data = self.driver.channels.get_channel(channel_id) channel_name = channel_data["name"] if channel_name == user_id + "__" + self.user_id: # direct_message if user_id != self.user_id: self.on_direct_message(event) else: if user_id != self.user_id: mention = False for tag in self.tags: if tag in msg: mention = True break if mention: self.on_mention(event) else: LOG.info("New message at channel: " + channel_name) LOG.info(sender + " said: " + msg) msg = [sender, msg, channel_name] #mycroft.send_msg(msg) return msg
def onConnect(self, response): logger.info("Server connected: {0}".format(response.peer)) self.factory.bus.emit( Message("hive.mind.connected", {"server_id": response.headers["server"]})) self.factory.client = self self.factory.status = "connected"
def process_message(self, client, payload, isBinary): """ Process message from client, decide what to do internally here """ LOG.info("processing message from client: " + str(client.peer)) client_data = self.clients[client.peer] client_protocol, ip, sock_num = client.peer.split(":") if isBinary: # TODO receive files pass else: # add context for this message payload = payload.decode("utf-8") message = Message.deserialize(payload) message.context["source"] = client.peer message.context["destination"] = "skills" if "platform" not in message.context: message.context["platform"] = client_data.get( "platform", "unknown") # messages/skills/intents per user if message.type in client.blacklist.get("messages", []): LOG.warning(client.peer + " sent a blacklisted message " \ "type: " + message.type) return # TODO check intent / skill that will trigger # send client message to internal mycroft bus self.mycroft_send(message.type, message.data, message.context)
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 during_download(self, first_run=False): LOG.info('Still downloading executable...') if first_run: # TODO: Localize self._snd_msg('mouth.text=Updating listener...') if not self.download_complete: self.show_download_progress = Timer(30, self.during_download) self.show_download_progress.start()
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 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 next(self): LOG.info("Going to next Intent Layer") self.current_layer += 1 if self.current_layer > len(self.layers): LOG.info("Already in last layer, going to layer 0") self.current_layer = 0 self.activate_layer(self.current_layer)
def onConnect(self, request): LOG.info("Client connecting: {0}".format(request.peer)) # validate user userpass_encoded = bytes(request.headers.get("authorization"), encoding="utf-8")[2:-1] userpass_decoded = base64.b64decode(userpass_encoded).decode("utf-8") name, key = userpass_decoded.split(":") ip = request.peer.split(":")[1] context = {"source": self.peer} self.platform = request.headers.get("platform", "unknown") try: user = users.get_client_by_api_key(key) except: LOG.info("Client provided an invalid api key") self.factory.mycroft_send( "hive.client.connection.error", { "error": "invalid api key", "ip": ip, "api_key": key, "platform": self.platform }, context) raise ValueError("Invalid API key") # send message to internal mycroft bus data = {"ip": ip, "headers": request.headers} self.blacklist = users.get_blacklist_by_api_key(key) self.factory.mycroft_send("hive.client.connect", data, context) # return a pair with WS protocol spoken (or None for any) and # custom headers to send in initial WS opening handshake HTTP response headers = {"server": NAME} return (None, headers)
def onMessage(self, payload, isBinary): if isBinary: LOG.info("Binary message received: {0} bytes".format(len(payload))) else: LOG.info("Text message received: {0}".format( payload.decode('utf8'))) self.factory.process_message(self, payload, isBinary)
def remove_layer(self, layer_num): if layer_num >= len(self.layers): return False if self.current_layer == layer_num: self.deactivate_layer(layer_num) self.layers.pop(layer_num) LOG.info("Removing layer number " + str(layer_num)) return True
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 validate_connection(self): try: subprocess.call([self.tts.MIMIC_BIN, '--version']) except: LOG.info("Failed to find mimic binary") raise Exception( 'Mimic was not found. See https://forslund.github.io/mycroft-desktop-repo/' )
def execute(self, audio, language=None): language = language or self.lang if language != self.lang: LOG.info("Changing decoder language") self.lang = language self.recognizer = PS_Recognizer(self.lang) return self.recognizer.recognize(audio)
def universal_fallback_handler(message): # auto_Translate input message = self._translate_message(message) LOG.info(get_handler_name(handler)) success = handler(self, message) if success: self.make_active() return success
def onMessage(self, payload, isBinary): logger.info("status: " + self.factory.status) if not isBinary: payload = payload.decode("utf-8") data = {"payload": payload, "isBinary": isBinary} else: data = {"payload": None, "isBinary": isBinary} self.factory.bus.emit(Message("hive.mind.message.received", data))
def replace_layer(self, layer_num, intent_list=None): intent_list = intent_list or [] if self.current_layer == layer_num: self.deactivate_layer(layer_num) LOG.info("Adding layer" + str(intent_list) + " in position " + str(layer_num)) self.layers[layer_num] = intent_list if self.current_layer == layer_num: self.activate_layer(layer_num)
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 on_status_change(self, event): user_id = event["data"]["user_id"] status = event["data"]["status"] user_data = self.driver.users.get_user(user_id=user_id) username = user_data["username"] email = user_data["email"] LOG.info(username + ":" + status)
def onClose(self, wasClean, code, reason): logger.info("WebSocket connection closed: {0}".format(reason)) self.factory.bus.emit( Message("hive.mind.connection.closed", { "wasClean": wasClean, "reason": reason, "code": code })) self.factory.client = None self.factory.status = "disconnected"
def train(self, message=None): single_thread = message.data.get('single_thread', False) self.finished_training_event.clear() LOG.info('Training...') self.engine.train(single_thread=single_thread) LOG.info('Training complete.') self.finished_training_event.set() self.finished_initial_train = True
def onOpen(self): """ Connection from client is opened. Fires after opening websockets handshake has been completed and we can send and receive messages. Register client in factory, so that it is able to track it. """ self.factory.register_client(self, self.platform) LOG.info("WebSocket connection open.")
def connectionLost(self, reason): """ Client lost connection, either disconnected or some error. Remove client from list of tracked connections. """ self.factory.unregister_client(self, reason=u"connection lost") LOG.info("WebSocket connection lost: {0}".format(reason)) ip = self.peer.split(":")[1] data = {"ip": ip, "reason": "connection lost"} context = {"source": self.peer} self.factory.mycroft_send("hive.client.disconnect", data, context)
def on_direct_message(self, event): post = event["data"]["post"] post = json.loads(post) sender = event["data"]["sender_name"] msg = post["message"] channel_id = post["channel_id"] LOG.info("Direct Message from: " + sender) LOG.info("Message: " + msg) # echo self.handle_direct_message(msg, sender, channel_id)
def on_download(self): LOG.info('Downloading Precise executable...') if isdir(join(self.folder, 'precise-stream')): rmtree(join(self.folder, 'precise-stream')) for old_package in glob(join(self.folder, 'precise-engine_*.tar.gz')): os.remove(old_package) self.download_complete = False self.show_download_progress = Timer( 5, self.during_download, args=[True] ) self.show_download_progress.start()
def onClose(self, wasClean, code, reason): self.factory.unregister_client(self, reason=u"connection closed") LOG.info("WebSocket connection closed: {0}".format(reason)) ip = self.peer.split(":")[1] data = { "ip": ip, "code": code, "reason": "connection closed", "wasClean": wasClean } context = {"source": self.peer} self.factory.mycroft_send("hive.client.disconnect", data, context)
def on_typing(self, event): user_id = event["data"]["user_id"] channel_id = event["broadcast"]["channel_id"] channel_data = self.driver.channels.get_channel(channel_id) channel_name = channel_data["name"] user_data = self.driver.users.get_user(user_id=user_id) username = user_data["username"] if channel_name == self.user_id + "__" + user_id: LOG.info(username + " is typing a direct message") else: LOG.info(username + " is typing a message in channel: " + channel_name)
def install_model(self, url: str, wake_word: str) -> str: model_url = url.format(wake_word=wake_word) model_file = join(self.folder, posixpath.basename(model_url)) try: install_package( model_url, self.folder, on_download=lambda: LOG.info('Updated precise model') ) except (HTTPError, ValueError): if isfile(model_file): LOG.info("Couldn't find remote model. Using local file") else: raise NoModelAvailable('Failed to download model:', model_url) return model_file