Exemplo n.º 1
0
def ensure_directory_exists(directory, domain=None):
    """ Create a directory and give access rights to all

    Args:
        domain (str): The IPC domain.  Basically a subdirectory to prevent
            overlapping signal filenames.

    Returns:
        str: a path to the directory
    """
    if domain:
        directory = os.path.join(directory, domain)
    directory = os.path.normpath(directory)

    if not os.path.isdir(directory):
        try:
            save = os.umask(0)
            os.makedirs(directory, 0o777)  # give everyone rights to r/w here
        except OSError:
            LOG.warning("Failed to create: " + directory)
            pass
        finally:
            os.umask(save)

    return directory
Exemplo n.º 2
0
    def read(self, size, of_exc=False):
        """
            Read data from stream.

            Arguments:
                size (int): Number of bytes to read
                of_exc (bool): flag determining if the audio producer thread
                               should throw IOError at overflows.

            Returns:
                Data read from device
        """
        frames = collections.deque()
        remaining = size
        while remaining > 0:
            to_read = min(self.wrapped_stream.get_read_available(), remaining)
            if to_read == 0:
                sleep(.01)
                continue
            result = self.wrapped_stream.read(to_read,
                                              exception_on_overflow=of_exc)
            frames.append(result)
            remaining -= to_read

        if self.muted:
            return self.muted_buffer
        input_latency = self.wrapped_stream.get_input_latency()
        if input_latency > 0.2:
            LOG.warning("High input latency: %f" % input_latency)
        audio = b"".join(list(frames))
        return audio
Exemplo n.º 3
0
    def process(self, audio):
        SessionManager.touch()
        payload = {
            'utterance': self.wakeword_recognizer.key_phrase,
            'session': SessionManager.get().session_id,
        }
        self.emitter.emit("recognizer_loop:wakeword", payload)

        if self._audio_length(audio) < self.MIN_AUDIO_SIZE:
            LOG.warning("Audio too short to be processed")
        else:
            stopwatch = Stopwatch()
            with stopwatch:
                transcription = self.transcribe(audio)
            if transcription:
                ident = str(stopwatch.timestamp) + str(hash(transcription))
                # STT succeeded, send the transcribed speech on for processing
                payload = {
                    'utterances': [transcription],
                    'lang': self.stt.lang,
                    'session': SessionManager.get().session_id,
                    'ident': ident
                }
                self.emitter.emit("recognizer_loop:utterance", payload)
                self.metrics.attr('utterances', [transcription])
            else:
                ident = str(stopwatch.timestamp)
            # Report timing metrics
            report_timing(ident, 'stt', stopwatch, {
                'transcription': transcription,
                'stt': self.stt.__class__.__name__
            })
Exemplo n.º 4
0
    def transcribe(self, audio):
        try:
            # Invoke the STT engine on the audio clip
            text = self.stt.execute(audio).lower().strip()
            LOG.debug("STT: " + text)
            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 HTTPError as e:
            if e.response.status_code == 401:
                LOG.warning("Access Denied at owo.ai")
                return "pair my device"  # phrase to start the pairing process
            else:
                LOG.error(e.__class__.__name__ + ': ' + str(e))
        except RequestException as e:
            LOG.error(e.__class__.__name__ + ': ' + str(e))
        except Exception as e:
            self.emitter.emit('recognizer_loop:speech.recognition.unknown')
            if isinstance(e, IndexError):
                LOG.info('no words were transcribed')
            else:
                LOG.error(e)
            LOG.error("Speech Recognition could not understand audio")
            return None
        if connected():
            dialog_name = 'backend.down'
        else:
            dialog_name = 'not connected to the internet'
        self.emitter.emit('speak', {'utterance': dialog.get(dialog_name)})
Exemplo n.º 5
0
def load_skill(skill_descriptor, bus, skill_id, BLACKLISTED_SKILLS=None):
    """ Load skill from skill descriptor.

    Args:
        skill_descriptor: descriptor of skill to load
        bus:              OwO messagebus connection
        skill_id:         id number for skill

    Returns:
        OwOSkill: the loaded skill or None on failure
    """
    BLACKLISTED_SKILLS = BLACKLISTED_SKILLS or []
    path = skill_descriptor["path"]
    name = basename(path)
    LOG.info("ATTEMPTING TO LOAD SKILL: {} with ID {}".format(name, skill_id))
    if name in BLACKLISTED_SKILLS:
        LOG.info("SKILL IS BLACKLISTED " + name)
        return None
    main_file = join(path, MainModule + '.py')
    try:
        with open(main_file, 'rb') as fp:
            skill_module = imp.load_module(name.replace('.',
                                                        '_'), fp, main_file,
                                           ('.py', 'rb', imp.PY_SOURCE))
        if (hasattr(skill_module, 'create_skill')
                and callable(skill_module.create_skill)):
            # v2 skills framework
            skill = skill_module.create_skill()
            skill.settings.allow_overwrite = True
            skill.settings.load_skill_settings_from_file()
            skill.bind(bus)
            try:
                skill.skill_id = skill_id
                skill.load_data_files(path)
                # Set up intent handlers
                skill._register_decorated()
                skill.initialize()
            except Exception as e:
                # If an exception occurs, make sure to clean up the skill
                skill.default_shutdown()
                raise e

            LOG.info("Loaded " + name)
            # The very first time a skill is run, speak the intro
            first_run = skill.settings.get("__OwO_skill_firstrun", True)
            if first_run:
                LOG.info("First run of " + name)
                skill.settings["__OwO_skill_firstrun"] = False
                skill.settings.store()
                intro = skill.get_intro_message()
                if intro:
                    skill.speak(intro)
            return skill
        else:
            LOG.warning("Module {} does not appear to be skill".format(name))
    except Exception:
        LOG.exception("Failed to load skill: " + name)
    return None
Exemplo n.º 6
0
    def remove_fallback(cls, handler_to_del):
        """
            Remove a fallback handler

            Args:
                handler_to_del: reference to handler
        """
        for priority, handler in cls.fallback_handlers.items():
            if handler == handler_to_del:
                del cls.fallback_handlers[priority]
                return
        LOG.warning('Could not remove fallback!')
Exemplo n.º 7
0
    def _register_object(self, message, object_name, register_func):
        file_name = message.data['file_name']
        name = message.data['name']

        LOG.debug('Registering Padatious ' + object_name + ': ' + name)

        if not isfile(file_name):
            LOG.warning('Could not find file ' + file_name)
            return

        register_func(name, file_name)
        self.train_time = get_time() + self.train_delay
        self.wait_and_train()
Exemplo n.º 8
0
 def read(self):
     while self.alive:
         try:
             data = self.serial.readline()[:-2]
             if data:
                 try:
                     data_str = data.decode()
                 except UnicodeError as e:
                     data_str = data.decode('utf-8', errors='replace')
                     LOG.warning('Invalid characters in response from '
                                 ' enclosure: {}'.format(repr(e)))
                 self.process(data_str)
         except Exception as e:
             LOG.error("Reading error: {0}".format(e))
Exemplo n.º 9
0
    def emit(self, message):
        if not self.connected_event.wait(10):
            if not self.started_running:
                raise ValueError('You must execute run_forever() '
                                 'before emitting messages')
            self.connected_event.wait()

        try:
            if hasattr(message, 'serialize'):
                self.client.send(message.serialize())
            else:
                self.client.send(json.dumps(message.__dict__))
        except WebSocketConnectionClosedException:
            LOG.warning('Could not send {} message because connection '
                        'has been closed'.format(message.type))
Exemplo n.º 10
0
 def install_or_update(skill):
     """Install missing defaults and update existing skills"""
     if skills_data.get(skill.name, {}).get('beta'):
         skill.sha = 'HEAD'
     if skill.is_local:
         skill.update()
         if skill.name not in installed_skills:
             skill.update_deps()
     elif skill.name in default_names:
         try:
             skill.install()
         except Exception:
             if skill.name in default_names:
                 LOG.warning('Failed to install default skill: ' +
                             skill.name)
                 nonlocal default_skill_errored
                 default_skill_errored = True
             raise
     installed_skills.add(skill.name)
Exemplo n.º 11
0
 def __init__(self, key_phrase="hey OwO", config=None, lang="en-us"):
     super(SnowboyHotWord, self).__init__(key_phrase, config, lang)
     # Hotword module imports
     from snowboydecoder import HotwordDetector
     # Hotword module config
     module = self.config.get("module")
     if module != "snowboy":
         LOG.warning(module + " module does not match with Hotword class "
                     "snowboy")
     # Hotword params
     models = self.config.get("models", {})
     paths = []
     for key in models:
         paths.append(models[key])
     sensitivity = self.config.get("sensitivity", 0.5)
     self.snowboy = HotwordDetector(paths,
                                    sensitivity=[sensitivity] * len(paths))
     self.lang = str(lang).lower()
     self.key_phrase = str(key_phrase).lower()
Exemplo n.º 12
0
        def handler(message):
            # indicate fallback handling start
            bus.emit(
                message.reply("owo.skill.handler.start",
                              data={'handler': "fallback"}))

            stopwatch = Stopwatch()
            handler_name = None
            with stopwatch:
                for _, handler in sorted(cls.fallback_handlers.items(),
                                         key=operator.itemgetter(0)):
                    try:
                        if handler(message):
                            #  indicate completion
                            handler_name = get_handler_name(handler)
                            bus.emit(
                                message.reply('owo.skill.handler.complete',
                                              data={
                                                  'handler': "fallback",
                                                  "fallback_handler":
                                                  handler_name
                                              }))
                            break
                    except Exception:
                        LOG.exception('Exception in fallback.')
                else:  # No fallback could handle the utterance
                    bus.emit(message.reply('complete_intent_failure'))
                    warning = "No fallback could handle intent."
                    LOG.warning(warning)
                    #  indicate completion with exception
                    bus.emit(
                        message.reply('owo.skill.handler.complete',
                                      data={
                                          'handler': "fallback",
                                          'exception': warning
                                      }))

            # Send timing metric
            if message.context and message.context['ident']:
                ident = message.context['ident']
                report_timing(ident, 'fallback_handler', stopwatch,
                              {'handler': handler_name})
Exemplo n.º 13
0
    def load(self, dialog_dir):
        """
        Load all dialog files within the specified directory.

        Args:
            dialog_dir (str): directory that contains dialog files

        Returns:
            a loaded instance of a dialog renderer
        """
        directory = Path(dialog_dir)
        if not directory.exists() or not directory.is_dir():
            LOG.warning("No dialog files found: " + dialog_dir)
            return self.__renderer

        for path, _, files in os.walk(str(directory)):
            for f in files:
                if f.endswith(".dialog"):
                    self.__renderer.load_template_file(
                        f.replace('.dialog', ''), join(path, f))
        return self.__renderer
Exemplo n.º 14
0
    def on_error(self, ws, error):
        """ On error start trying to reconnect to the websocket. """
        if isinstance(error, WebSocketConnectionClosedException):
            LOG.warning('Could not send message because connection has closed')
        else:
            LOG.exception('=== ' + repr(error) + ' ===')

        try:
            self.emitter.emit('error', error)
            if self.client.keep_running:
                self.client.close()
        except Exception as e:
            LOG.error('Exception closing websocket: ' + repr(e))

        LOG.warning("WS Client will reconnect in %d seconds." % self.retry)
        time.sleep(self.retry)
        self.retry = min(self.retry * 2, 60)
        try:
            self.client = self.create_client()
            self.run_forever()
        except WebSocketException:
            pass
Exemplo n.º 15
0
 def execute(self, audio, language=None):
     LOG.warning("WITSTT language should be configured at wit.ai settings.")
     return self.recognizer.recognize_wit(audio, self.token)
Exemplo n.º 16
0
 def remove_git_locks(self):
     """If git gets killed from an abrupt shutdown it leaves lock files"""
     for i in glob(join(self.msm.skills_dir, '*/.git/index.lock')):
         LOG.warning('Found and removed git lock file: ' + i)
         os.remove(i)
Exemplo n.º 17
0
    def _load_or_reload_skill(self, skill_path):
        """
            Check if unloaded skill or changed skill needs reloading
            and perform loading if necessary.

            Returns True if the skill was loaded/reloaded
        """
        skill_path = skill_path.rstrip('/')
        skill = self.loaded_skills.setdefault(skill_path, {})
        skill.update({"id": basename(skill_path), "path": skill_path})

        # check if folder is a skill (must have __init__.py)
        if not MainModule + ".py" in os.listdir(skill_path):
            return False

        # getting the newest modified date of skill
        modified = _get_last_modified_date(skill_path)
        last_mod = skill.get("last_modified", 0)

        # checking if skill is loaded and hasn't been modified on disk
        if skill.get("loaded") and modified <= last_mod:
            return False  # Nothing to do!

        # check if skill was modified
        elif skill.get("instance") and modified > last_mod:
            # check if skill has been blocked from reloading
            if (not skill["instance"].reload_skill
                    or not skill.get('active', True)):
                return False

            LOG.debug("Reloading Skill: " + basename(skill_path))
            # removing listeners and stopping threads
            try:
                skill["instance"].default_shutdown()
            except Exception:
                LOG.exception("An error occured while shutting down {}".format(
                    skill["instance"].name))

            if DEBUG:
                gc.collect()  # Collect garbage to remove false references
                # Remove two local references that are known
                refs = sys.getrefcount(skill["instance"]) - 2
                if refs > 0:
                    msg = ("After shutdown of {} there are still "
                           "{} references remaining. The skill "
                           "won't be cleaned from memory.")
                    LOG.warning(msg.format(skill['instance'].name, refs))
            del skill["instance"]
            self.bus.emit(
                Message("owo.skills.shutdown", {
                    "path": skill_path,
                    "id": skill["id"]
                }))

        skill["loaded"] = True
        desc = create_skill_descriptor(skill_path)
        skill["instance"] = load_skill(desc, self.bus, skill["id"],
                                       BLACKLISTED_SKILLS)

        skill["last_modified"] = modified
        if skill['instance'] is not None:
            self.bus.emit(
                Message(
                    'owo.skills.loaded', {
                        'path': skill_path,
                        'id': skill['id'],
                        'name': skill['instance'].name,
                        'modified': modified
                    }))
            return True
        else:
            self.bus.emit(
                Message('owo.skills.loading_failure', {
                    'path': skill_path,
                    'id': skill['id']
                }))
        return False
Exemplo n.º 18
0
 def test_logging():
     LOG.debug('testing debug')
     LOG.info('testing info')
     LOG.warning('testing warning')
     LOG.error('testing error')
     LOG('testing custom').debug('test')
Exemplo n.º 19
0
    def remove(self, event_name, func):
        try:
            if event_name in self.emitter._events:
                LOG.debug("Removing found '" + str(event_name) + "'")
            else:
                LOG.debug("Not able to find '" + str(event_name) + "'")
            self.emitter.remove_listener(event_name, func)
        except ValueError as e:
            LOG.warning('Failed to remove event {}: {}'.format(
                event_name, str(func)))
            for line in traceback.format_stack():
                LOG.warning(line.strip())

            if event_name in self.emitter._events:
                LOG.debug("Removing found '" + str(event_name) + "'")
            else:
                LOG.debug("Not able to find '" + str(event_name) + "'")
            LOG.warning("Existing events: " + str(self.emitter._events))
            for evt in self.emitter._events:
                LOG.warning("   " + str(evt))
                LOG.warning("       " + str(self.emitter._events[evt]))
            if event_name in self.emitter._events:
                LOG.debug("Removing found '" + str(event_name) + "'")
            else:
                LOG.debug("Not able to find '" + str(event_name) + "'")
            LOG.warning('----- End dump -----')