def main():
    parser = ArgumentParser()
    subparsers = parser.add_subparsers(dest='action')
    subparsers.add_parser('setup')
    args = parser.parse_args()
    if args.action == 'setup':
        import mycroft.util
        from mycroft.util.log import PrintLogger, Level
        mycroft.util.log = PrintLogger(Level.INFO)
        mycroft.util.log._get_prefix = lambda level, offset: ''

    from mycroft.util import log
    from mycroft.root import Root

    if args.action == 'setup':
        Root(None, blacklist=['skills'])
        return

    rt = Root()

    if rt.config['use_server'] and rt.device_info:
        rt.config.load_remote()

    rt.intent.context.compile()
    rt.interfaces.all.run(gp_daemon=True)

    try:
        rt.main_thread.wait()
    except KeyboardInterrupt:
        pass
    log.info('Quiting...')
    sleep(0.1)
    print()
    def __init__(self, rt):
        ServicePlugin.__init__(self, rt)
        sys.path.append(self.rt.paths.skills)

        def inject_rt(cls):
            cls.rt = rt

        log.info('Loading skills...')
        GroupPlugin.__init__(self, gp_alter_class=inject_rt, gp_blacklist=self.config['blacklist'],
                             gp_timeout=10.0, gp_daemon=True)
        for name, thread in self._init_threads.items():
            if thread.is_alive():
                log.warning('Skill init method taking too long for:', name)
        log.info('Finished loading skills.')

        # The watch manager stores the watches and provides operations on watches
        wm = pyinotify.WatchManager()
        mask = pyinotify.IN_MODIFY | pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MOVED_TO
        skills_dir = self.rt.paths.skills

        handler = EventHandler(self, skills_dir)
        notifier = pyinotify.ThreadedNotifier(wm, handler)
        notifier.daemon = True
        wm.add_watch(skills_dir, mask, rec=True, auto_add=True)
        notifier.start()
        self.git_repo = self.create_git_repo()
Beispiel #3
0
    def _run_prehandlers(self, matches: List[IntentMatch]) -> List[Package]:
        """Iterate through matches, executing prehandlers"""
        package_generators = []
        for match in matches:

            def callback(match=match):
                data = self.intent_data[match.intent_id]
                prehandler = data.get('prehandler', self.default_prehandler)
                package = self.rt.package(match=match)
                package.skill = self.intent_to_skill[match.intent_id]
                return self._run_handler(prehandler, package)

            package_generators.append(callback)

        for package in run_parallel(package_generators,
                                    filter_none=True,
                                    label='prehandler'):
            match = package.match

            log.info(str(match.intent_id) + ':', str(match.confidence))
            log.debug('\tConfidence:', package.confidence)

            if match.confidence is not None:
                package.confidence = sqrt(package.confidence *
                                          match.confidence)
            yield package
    def reload(self, folder_name):
        log.debug('Reloading', folder_name + '...')
        skill_name = folder_name.replace(self._suffix_, '')

        if skill_name in self._plugins:
            safe_run(self._plugins[skill_name]._unload, label='Skill unload')
            del self._plugins[skill_name]

        if skill_name in self._classes:
            self.rt.intent.remove_skill(skill_name)
            del self._classes[skill_name]

        if not isfile(join(self.rt.paths.skills, folder_name, 'skill.py')):
            return

        cls = self.load_skill_class(folder_name)
        if not cls:
            return

        cls.rt = self.rt
        self._classes[skill_name] = cls

        def init():
            self._plugins[skill_name] = cls()
            return True

        if safe_run(
                init, label='Reloading ' + skill_name, custom_exception=NotImplementedError,
                custom_handler=lambda e, l: log.info(l + ': Skipping disabled plugin')
        ):
            self.rt.intent.context.compile()
            log.info('Reloaded', folder_name)
 def _get_transcription(self, recording):
     utterance = ''
     try:
         utterance = self.stt.transcribe(recording)
     except ValueError:
         log.info('Found no words in audio')
     except RequestException:
         log.exception('Speech Client')
     else:
         log.info('Utterance: ' + utterance)
     return utterance
    def __init__(self, rt):
        # type: (Root) -> None
        self.rt = rt

        if self._package_struct:
            if 'package' not in self.rt:
                log.warning('Package struct for module loaded before package:',
                            self._plugin_path)
            else:
                self.rt.package.add_struct(self._package_struct)

        if not self._plugin_path and self._config:
            print('PLUGIN_PATH:', self._plugin_path, self._attr_name,
                  self._config, self)
            raise RuntimeError(
                'Cannot set _config for non-dynamically loaded class {}'.
                format(self.__class__.__name__))

        if 'config' in rt and self._plugin_path:
            if self._root_config:
                rt.config.inject(self._root_config)
            if self._config:
                rt.config.inject(self._config, self._plugin_path)

            self.config = {}
            rt.config.on_change(self._plugin_path, self.on_config_change)

            self.on_config_change(rt.config.get_path(self._plugin_path))

        else:
            self.config = {}

        if 'config' in rt and self._required_attributes:
            for required_attribute in self._required_attributes:
                if required_attribute not in self.rt.config['platform'][
                        'attributes']:
                    raise NotImplementedError('Missing attribute: ' +
                                              required_attribute)

        if 'plugin_versions' in rt:
            old_version = rt.plugin_versions.get(self._plugin_path)
            if old_version != self.__version__:
                if self.setup.__func__ is not BasePlugin.setup:
                    log.info(
                        'Running {}.setup() to upgrade from {} to {}'.format(
                            self.__class__.__name__, old_version,
                            self.__version__))
                self.setup()
                rt.plugin_versions[self._plugin_path] = self.__version__
Beispiel #7
0
 def _try_run_packages(self,
                       packages: List[Package]) -> Union[Package, None]:
     """Iterates through packages, executing handlers until one succeeds"""
     while len(packages) > 0:
         package = max(packages, key=lambda x: x.confidence)
         intent_id = package.match.intent_id
         del packages[packages.index(package)]
         log.info('Selected intent', intent_id, package.confidence)
         try:
             handler = self.intent_data[intent_id].get(
                 'handler', self.default_handler)
             return self._run_handler(handler, package)
         except Exception:
             log.exception(intent_id, 'callback')
     return None
 def __init__(self, rt):
     super().__init__(rt)
     sys.stdout = StreamHandler(lambda x: log.info(x, stack_offset=3))
     sys.stderr = StreamHandler(lambda x: log.error(x, stack_offset=3))
     self.response_event = Event()
     self.response_event.set()
     self.prompt = self.config['prompt']
    def record_phrase(self) -> AudioData:
        """Records until a period of silence"""
        log.info('Recording...')
        raw_audio = b'\0' * self.sample_width
        self.integral = 0
        self.noise_level = 0
        total_sec = 0
        while total_sec < self.recording_timeout:
            self._check_intercept()
            chunk = self.stream.read(self.chunk_size)
            raw_audio += chunk
            total_sec += self.chunk_sec
            energy = self._calc_energy(chunk)
            self.update_energy(energy)
            if self.integral > self.required_integral and self.noise_level == 0:
                break

        log.info('Done recording.')
        return AudioData(raw_audio, self.sample_rate, self.sample_width)
Beispiel #10
0
    def calc_package(self, query: str) -> Package:
        """
        Find the best intent and run the handler to find the result

        Args:
            query: input sentence
        Returns:
            package: object containing display data from skill
        """
        log.info('Query:', query)
        query = query.strip().lower()

        matches = self.context.calc_intents(query)
        matches = [i for i in matches if i.confidence > 0.5]

        packages = self._run_prehandlers(matches)
        result_package = self._try_run_packages(
            [i for i in packages if i.confidence > 0.5])
        if result_package:
            return result_package
        log.info('No intents matched. Falling back.')

        matches = [
            IntentMatch(intent_id, confidence=None, query=query)
            for intent_id in self.fallback_intents
        ]

        packages = self._run_prehandlers(matches)
        result_package = self._try_run_packages(list(packages))
        if result_package:
            return result_package
        log.info('All fallbacks failed.')

        return self.rt.package()
    def _load_classes(self, package, suffix, blacklist):
        """
        Looks in the skill folder and loads the
        CamelCase equivalent class of the snake case folder
        This class should be inside the skill.py file. Example:

        skills/
            time_skill/
                skill.py - class TimeSkill(MycroftSkill):
            weather_skill/
                skill.py - class WeatherSkill(MycroftSkill):
        """
        log.info('Loading classes...')
        self.setup()

        classes = {}
        folder_names, invalid_names = listdir(self.rt.paths.skills), []

        for folder_name in folder_names:
            if not folder_name.endswith(suffix) or \
                    not isfile(join(self.rt.paths.skills, folder_name, 'skill.py')):
                invalid_names.append(folder_name)
                continue

            attr_name = folder_name[:-len(suffix)]
            if attr_name in blacklist:
                continue

            cls = self.load_skill_class(folder_name)
            if not cls:
                continue

            classes[attr_name] = cls

        log.info('Skipped folders:', ', '.join(invalid_names))
        return classes
            def func(*args, **kwargs):
                def create_plugin(*args, **kwargs):
                    new_cls = (alter_class(cls) or cls) if alter_class else cls
                    instance = new_cls(*args, **kwargs)
                    self._plugins[self._make_name(new_cls)] = instance
                    return instance

                plugin = safe_run(create_plugin,
                                  args=args,
                                  kwargs=kwargs,
                                  label='Loading ' + cls._attr_name +
                                  self._suffix_,
                                  custom_exception=NotImplementedError,
                                  custom_handler=lambda e, l: log.info(
                                      l + ': Skipping disabled plugin'))
                if not plugin:
                    log.debug('Unloading partially loaded plugin:',
                              cls._attr_name + self._suffix_)
                    self._on_partial_load(cls._attr_name)
                return plugin
 def on_activation(self):
     """Called by child classes"""
     log.info('Heard wake word!')
     self._has_activated = True
Beispiel #14
0
 def compile(self):
     log.info('Training...')
     self.container.train()
     log.info('Training complete!')