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 __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)
def create_key(self, host: str, path: str, custom_url=None, use_auth=False) -> str: log.debug('Registered remote', path, 'key for', host) self.url_plugins[host] = path if custom_url or use_auth: self.custom_urls[path] = (custom_url, use_auth) return md5(path.encode()).hexdigest()
def process(self, package: Package): """Called to modify attributes within package""" if package.action == UNSET_ACTION: package.action = package.match.intent_id.split( ':')[1] if package.match else '' package.action = package.action or '' self.all.process(package, gp_warn=False) # type: ignore log.debug('Package: \n' + str(package))
def __init__(self, *args, __module__, **kwargs): self._plugin = None if not isinstance(type(self), OptionMeta): raise RuntimeError('{} must have OptionMeta as a metaclass'.format( self.__class__.__name__)) self._class, self._plugin = self.__load_plugin(__module__, args, kwargs) self.__copy_functions(self._plugin) if getattr(self, '_plugin_path', '').count('.') > 1: log.debug('Loaded {} as {}.'.format(self._class.__name__, self.__class__.__name__))
def wait_for_wake_word(self): """Listens to the microphone and returns when it hears the wake word""" log.debug('Waiting for wake word...') self.av_energy = self._calc_energy(self.stream.read(self.chunk_size)) self.engine.continue_listening() while not self._has_activated: self._check_intercept() chunk = self.stream.read(self.chunk_size) self.update_energy(self._calc_energy(chunk)) self.engine.update(chunk) self._has_activated = False self.engine.pause_listening()
def download(url, file: Union[str, io, None] = None, debug=True, timeout=None) -> Union[bytes, None]: """Pass file as a filename, open file object, or None to return the request bytes""" if debug: log.debug('Downloading:', url) import urllib.request import shutil if isinstance(file, str): file = open(file, 'wb') try: with urllib.request.urlopen(url, timeout=timeout) as response: if file: shutil.copyfileobj(response, file) else: return response.read() finally: if file: file.close()
def get(self, name, intents: List[Any], intent_engine='file', skill_name=None) -> IntentContext: """Get a shared intent context or register one sourcing from the given skill""" if name not in self.contexts: skill_name = skill_name or 'shared_intent' context = IntentContext(self.rt, skill_name) for intent in intents: context.register(intent, intent_engine) self.context_providers[name] = skill_name self.contexts[name] = context elif skill_name: log.debug( '{} context provided by {}. Ignoring data from {}.'.format( name, self.context_providers[name], skill_name)) return self.contexts[name]
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 send(self, params): method = params.get('method', 'GET') headers = self.build_headers(params) data = self.build_data(params) json = self.build_json(params) query = self.build_query(params) url = self.build_url(params) try: response = requests.request(method, url, headers=headers, params=query, data=data, json=json, timeout=(3.05, 5)) except RequestException as e: response = e else: log.debug(method, url, response.status_code, stack_offset=3) if isinstance(response, Exception): raise ConnectionError('Failed to {} {}: {}'.format( method, url, response)) return self.get_response(response)
def load_class(package: str, suffix: str, module: str, plugin_path: str, attr_name: str = None): package = package + '.' + module + suffix log.debug('Loading {}{}...'.format(module, suffix)) try: mod = import_module(package) cls_name = to_camel(module + suffix) cls = getattr(mod, cls_name, '') if not isclass(cls): log.error('Could not find', cls_name, 'in', package) elif not issubclass(cls, BasePlugin): log.error( '{} must inherit BasePlugin to be loaded dynamically'.format( cls.__name__)) else: update_dyn_attrs(cls, suffix, plugin_path, attr_name) return cls except Exception: log.exception('Loading Module', package) return None
def __init__(self, rt, on_activation: Callable): super().__init__(rt, on_activation) exe_file = which('precise-engine') precise_folder = join(self.rt.paths.user_config, 'precise') if not exe_file: exe_file = join(precise_folder, 'precise-engine', 'precise-engine') download_extract_tar( self.program_url.format(arch=platform.machine()), precise_folder, check_md5=False, subdir='precise-engine', on_update=lambda: self.rt.interfaces.faceplate.text('Updating listener...'), on_complete=lambda: self.rt.interfaces.faceplate.reset() ) log.debug('Using precise executable: ' + exe_file) model_folder = join(precise_folder, 'models', self.wake_word) model_file = join(model_folder, self.wake_word + '.pb') model_url = self.model_url.format(model_name=self.wake_word) download_extract_tar(model_url, model_folder, check_md5=True) from precise_runner import PreciseRunner, PreciseEngine engine = PreciseEngine(exe_file, model_file, chunk_size=1024) self.runner = PreciseRunner(engine, on_activation=on_activation)