Beispiel #1
0
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
Beispiel #2
0
        async def _ws():
            async with aiohttp.ClientSession() as client:
                async with client.ws_connect(
                        f"{self._api_root}all?sessionKey={self._session_key}",
                        **kwargs) as ws:
                    while True:
                        try:
                            event = await ws.receive_json()
                        except TypeError:
                            if ws.closed:
                                logger.warning(
                                    'Websocket closed, try relogin in 10s')
                                await asyncio.sleep(10)
                                await self.relogin()
                                return
                            logger.error(f"TypeError in parsing ws event")
                            continue
                        if not event:
                            continue

                        logger.debug(f"[event] {event}")
                        try:
                            event = self.as_event(event)
                            if event:
                                self.handle_event_nowait(event)
                        except Exception as e:
                            logger.critical(e)
                            return
Beispiel #3
0
 async def _poll():
     while True:
         try:
             res = await self._fetch_message()
             if res.ok:
                 for event in res.data:
                     self.handle_event_nowait(event)
         except Exception as e:
             logger.error(e)
         finally:
             await asyncio.sleep(interval)
Beispiel #4
0
 async def _auth(self):
     try:
         async with aiohttp.request("POST",
                                    self._api_root + 'auth',
                                    json={'authKey':
                                          self._auth_key}) as resp:
             if 200 <= resp.status < 300:
                 result = json.loads(await resp.text())
                 logger.info(f'Login Mirai: {result}')
                 if result.get('code') == 0:
                     return result['session']
     except Exception as e:
         logger.error(e)
         return
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
    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))