コード例 #1
0
    def process(self, p: Package):
        if not p.action:
            return
        locale_dir = self.rt.paths.skill_locale(skill_name=p.skill,
                                                lang=p.lang)
        file_base = join(locale_dir, p.action)
        speech = file_base + '.speech'
        dialog = file_base + '.dialog'
        text = file_base + '.text'

        line_id = -1

        if not p.speech:
            if isfile(speech):
                line_id, p.speech = self.render_file(speech, p, Format.speech,
                                                     line_id)
            elif isfile(dialog):
                line_id, p.speech = self.render_file(dialog, p, Format.speech,
                                                     line_id)
            else:
                p.speech = p.text
        if not p.text:
            if isfile(text):
                line_id, p.text = self.render_file(text, p, Format.text,
                                                   line_id)
            elif isfile(dialog):
                line_id, p.text = self.render_file(dialog, p, Format.text,
                                                   line_id)
            else:
                p.text = p.speech

        if not p.speech and not p.text:
            log.warning('No dialog at:', dialog)
コード例 #2
0
def download_extract_tar(tar_url, folder, check_md5=False, subdir='',
                         on_update: Callable = None, on_complete: Callable = None) -> bool:
    """Warning! If check_md5 is True, it will delete <folder>/<subdir> when remote md5 updates"""
    data_file = join(folder, basename(tar_url))

    if not isdir(join(folder, subdir)):
        makedirs(folder, exist_ok=True)
        download(tar_url, data_file)

        import tarfile
        tar = tarfile.open(data_file)
        tar.extractall(path=folder)
        tar.close()
        return True
    elif check_md5:
        md5_url = tar_url + '.md5'
        try:
            remote_md5 = download(md5_url, debug=False, timeout=1).decode('ascii').split(' ')[0]
        except (RequestException, URLError) as e:
            log.warning('Failed to download md5 at url:', md5_url)
            return False
        if remote_md5 != calc_md5(data_file):
            on_update and on_update()
            rmtree(join(folder, subdir))
            download_extract_tar(tar_url, folder, subdir=subdir)
            on_complete and on_complete()
            return True
    return False
コード例 #3
0
    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()
コード例 #4
0
    def __register_intents(self):
        intents = []
        entities = []
        for name in dir(self):
            item = getattr(self, name)
            if callable(item):
                intent_calls = getattr(item, 'intent_calls', None)
                if intent_calls:
                    for params in intent_calls:
                        func, intent, intent_engine, handler_type = params
                        if not intent:
                            log.warning('Skipping empty intent from skill:',
                                        self.skill_name)
                            continue
                        intents.append(intent)
                        self.register_intent(func, intent, intent_engine,
                                             handler_type)

                entity_calls = getattr(item, 'entity_calls', None)
                if entity_calls:
                    for params in entity_calls:
                        entity, intent_engine = params
                        entities.append(entity)
                        self.register_entity(entity, intent_engine)

        log.debug('Intents for', self.skill_name + ':', intents)
        if entities:
            log.debug('Entities for', self.skill_name + ':', entities)
コード例 #5
0
 def format(self, obj, fmt=Format.speech):
     handler = self.formatters.get(type(obj))
     if not handler:
         log.warning('No formatter for', type(obj))
         return str(obj)
     if isclass(handler) or len(signature(handler).parameters) == 1:
         return handler(obj)
     else:
         return handler(obj, fmt)
コード例 #6
0
 def __getattr__(self, item) -> Any:
     if item.startswith('_'):
         raise AttributeError(item)
     if '_plugins' not in self.__dict__:
         raise AttributeError(item)
     if item not in self._plugins:
         log.warning(item, 'plugin does not exist.', stack_offset=1)
         self._plugins[item] = Empty()
     return self._plugins[item]
コード例 #7
0
 def run(self):
     Thread(target=self._run_serial, daemon=True).start()
     while self.rt.main_thread:
         line = self.serial.readline().decode()
         if 'volume.up' in line:
             self.rt.skills.volume.increase_volume()
         elif 'volume.down' in line:
             self.rt.skills.volume.decrease_volume()
         elif 'Command: ' in line:
             pass  # Reply from Arduino
         elif len(line.strip()) > 0:
             log.warning('Could not handle message: ' + line)
コード例 #8
0
    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__
コード例 #9
0
 def __init__(self, timeout=2.0, blacklist=None):
     GroupPlugin.__init__(self,
                          self,
                          gp_order=[
                              'config', 'package', 'scheduler', 'paths',
                              'filesystem', 'plugin_versions', 'identity',
                              'device_info', 'remote_key', 'query',
                              'transformers', 'interfaces', 'intent', '*',
                              'skills', 'main_thread'
                          ],
                          gp_timeout=timeout,
                          gp_daemon=True,
                          gp_blacklist=blacklist)
     for name, thread in self._init_threads.items():
         if thread.is_alive():
             log.warning('Service init method taking too long for:', name)
コード例 #10
0
def run_ordered_parallel(items, get_function, args, kwargs,
                         order=None, daemon=False, label='', warn=False,
                         custom_exception=None, custom_handler=None, timeout=None) \
        -> Union[List[Any], Dict[str, Thread]]:
    order = order or []
    if '*' not in order:
        order.append('*')
    if daemon and timeout is None:
        timeout = 0.0
    return_vals = []

    def run_item(item, name):
        return_val = safe_run(get_function(item),
                              args=args,
                              kwargs=kwargs,
                              label=label + ' ' + name,
                              warn=warn,
                              custom_exception=custom_exception,
                              custom_handler=custom_handler)
        return_vals.append(return_val)

    threads = {}
    for name in set(items) - set(order):
        threads[name] = Thread(target=run_item,
                               args=(items[name], name),
                               daemon=daemon)

    for name in order:
        if name == '*':
            for i in threads.values():
                i.start()
            try:
                join_threads(threads.values(), timeout)
            except KeyboardInterrupt:
                log.error(
                    'KeyboardInterrupt joining threads:',
                    [name for name, t in threads.items() if t.is_alive()])
                raise
        elif name in items:
            run_item(items[name], name)
        else:
            log.warning('Plugin from runner load order not found:', name)

    if not daemon:
        return return_vals
    return threads
コード例 #11
0
def warn_once(key, message, stack_offset=0):
    if key not in warned_keys:
        warned_keys.add(key)
        log.warning(message, stack_offset=stack_offset + 1)
コード例 #12
0
def _log_exception(label, e, warn, stack_offset):
    if warn:
        log.warning(label, '--', e.__class__.__name__ + ':', e, stack_offset=stack_offset + 1)
    else:
        log.exception(label, stack_offset=stack_offset + 1)