async def handle_event(source: EventProvider, event: Event, **kwargs): """Handle a event received from protocol To avoid blocking awaiting, creating a task to run this :param source: :param event: :return: """ if not isinstance(event, Event): logger.error(f'A non-event {event} passed to handle_event!') return logger.debug(f'Handling {event.type} {event}') res = [] async for result in engine.forward(event=event, source=source, **kwargs): if isinstance(result, Exception): try: raise result except Exception as e: logger.error(f'Error handling event {event} {e}') logger.exception(e) elif result: res.append(result) return res
async def load_plugin(*, module_path: str = None, plugin_dir: str = None) -> Optional[Plugin]: """Load a Plugin by Plugin module path or Plugin directory :param module_path: :param plugin_dir: :return: """ if not plugin_dir: if not module_path: raise ValueError() elif module_path.startswith('.'): plugin_dir = '.' + module_path.replace('.', '/') else: plugin_dir = './' + module_path.replace('.', '/') else: if plugin_dir.startswith('.'): module_path = plugin_dir.replace('/', '.')[1:] else: module_path = plugin_dir.replace('/', '.') logger.info(f'Loading Plugin {module_path} from {plugin_dir} ...') try: plugin_info_path = os.path.join(os.path.expanduser(plugin_dir), ajenga.config.PLUGIN_INFO_FILE) with open(plugin_info_path, encoding='utf-8') as f: plugin_info = json.load(f) if plugin_info.get('name') and get_plugin(plugin_info['name']): logger.error(f'Plugin {plugin_info["name"]} already exists') return None plugin = Plugin(plugin_info, path=module_path) set_current_plugin(plugin) add_plugin(plugin) except Exception as e: logger.exception(e) logger.error(f'Failed to load Plugin config from {plugin_dir}') return None try: module = importlib.import_module(module_path) plugin.load(module) add_plugin(plugin, True) except Exception as e: logger.exception(e) logger.error(f'Failed to load Plugin module from {module_path}') await unload_plugin(plugin, True) return None await meta_provider.send(MetaEvent(MetaEventType.PluginLoad, plugin=plugin)) meta_provider.send_nowait( MetaEvent(MetaEventType.PluginLoaded, plugin=plugin)) logger.info(f'Succeeded to load Plugin "{plugin.name}"') return plugin
def _load_service_config(service_key): config_file = os.path.join(_service_config_dir, f'{service_key}.json') if not os.path.exists(config_file): return {} # config file not found, return default config. try: with open(config_file, encoding='utf8') as f: config = json.load(f) return config except Exception as e: logger.exception(e) return {}
async def wrapper(self, *args, **kwargs): while True: try: return await func(self, *args, **kwargs) except ApiError as e: if e.code == ApiError.CODE_SESSION_FAILED: logger.info('Re-login Mirai') if not await self.relogin(): return ApiResult(Code.Unavailable) if await self._api.verify(qq=self.qq): logger.info('Re-login Success') continue else: return ApiResult(Code.Unavailable) else: return ApiResult(e.code) except Exception as e: logger.exception(e) return ApiResult(Code.Unspecified, message=str(e))
async def unload_plugin(key: Union[str, Plugin], forced: bool = False) -> bool: """Unload a Plugin :param key: Plugin object or module path or name :param forced: Forced to unload :return: Success or not """ plugin = get_plugin(key) if isinstance(key, str) else key if not plugin: logger.warning(f"Plugin {key} not exists") return False plugin_name = plugin.name await meta_provider.send( MetaEvent(MetaEventType.PluginUnload, plugin=plugin)) for service in plugin.services.values(): try: remove_service(service) except Exception as e: logger.exception(e) logger.error(f'Failed to unload service "{service}", error: {e}') result = remove_plugin(plugin) if not result and not forced: return False if plugin.path: for module in list( filter(lambda x: x.startswith(plugin.path), sys.modules.keys())): del sys.modules[module] meta_provider.send_nowait( MetaEvent(MetaEventType.PluginUnloaded, plugin=plugin)) logger.info(f'Succeeded to unload Plugin "{plugin_name}"') return True
async def wrapper(self, *args, **kwargs): try: return await func(self, *args, **kwargs) except Exception as e: logger.exception(e) if (not _ALLOW_RETRY): if isinstance(self, CQSession): self.handle_event_nowait( ApiNotSuccessfulEvent(func.__name__, self.qq, args, kwargs)) return ApiResult(Code.Unspecified, message=str(e)) logger.info("Retrying...") try: return await func(*args, **kwargs) except Exception as e: logger.exception(e) logger.error("Retrying failed") if isinstance(self, CQSession): self.handle_event_nowait( ApiNotSuccessfulEvent(func.__name__, self.qq, args, kwargs)) return ApiResult(Code.Unspecified, message=str(e))