From db6e309fdd692ce157ae4f19818fc4ac59d08406 Mon Sep 17 00:00:00 2001 From: MuXinCG <202322130196@mail.sdu.edu.cn> Date: Wed, 18 Feb 2026 22:44:34 +0800 Subject: [PATCH] Add email qq and signal --- EvoScientist/channels/email/channel.py | 22 +++++++-------- EvoScientist/channels/qq/channel.py | 24 ++++++++--------- EvoScientist/channels/signal/channel.py | 36 ++++++++++++------------- 3 files changed, 39 insertions(+), 43 deletions(-) diff --git a/EvoScientist/channels/email/channel.py b/EvoScientist/channels/email/channel.py index c1eb765..e3bb69c 100644 --- a/EvoScientist/channels/email/channel.py +++ b/EvoScientist/channels/email/channel.py @@ -86,6 +86,17 @@ class EmailChannel(Channel, PollingMixin): logger.info(f"Email channel started (IMAP: {cfg.imap_host}, poll {cfg.poll_interval}s)") await self._start_polling() + async def _cleanup(self) -> None: + await self._stop_polling() + if self._imap: + try: + self._imap.close() + self._imap.logout() + except Exception: + pass + self._imap = None + logger.info("Email channel stopped") + def _connect_imap(self) -> None: cfg = self.config try: @@ -353,14 +364,3 @@ class EmailChannel(Channel, PollingMixin): except Exception as e: logger.error(f"SMTP attachment send failed: from={from_addr} to={to} error={e}") raise RuntimeError(f"SMTP attachment: {e}") - - async def _cleanup(self) -> None: - await self._stop_polling() - if self._imap: - try: - self._imap.close() - self._imap.logout() - except Exception: - pass - self._imap = None - logger.info("Email channel stopped") diff --git a/EvoScientist/channels/qq/channel.py b/EvoScientist/channels/qq/channel.py index 100b3cf..35b47e0 100644 --- a/EvoScientist/channels/qq/channel.py +++ b/EvoScientist/channels/qq/channel.py @@ -90,6 +90,17 @@ class QQChannel(Channel): logger.error(f"QQ auth failed: {e}") self._running = False + async def _cleanup(self) -> None: + self._running = False + if self._bot_task: + self._bot_task.cancel() + try: + await self._bot_task + except asyncio.CancelledError: + pass + self._client = None + logger.info("QQ channel stopped") + # ── Incoming ────────────────────────────────────────────────── async def _on_msg(self, message, msg_type: str) -> None: @@ -243,16 +254,3 @@ class QQChannel(Channel): if caption: await self._send_chunk(chat_id, caption, caption, None, metadata or {}) return True - - # ── Cleanup ─────────────────────────────────────────────────── - - async def _cleanup(self) -> None: - self._running = False - if self._bot_task: - self._bot_task.cancel() - try: - await self._bot_task - except asyncio.CancelledError: - pass - self._client = None - logger.info("QQ channel stopped") diff --git a/EvoScientist/channels/signal/channel.py b/EvoScientist/channels/signal/channel.py index 9e297c1..c43a34c 100644 --- a/EvoScientist/channels/signal/channel.py +++ b/EvoScientist/channels/signal/channel.py @@ -61,6 +61,23 @@ class SignalChannel(Channel): # (start() must return so that run() can iterate receive()) self._listen_task = asyncio.create_task(self._listen_loop()) + async def _cleanup(self) -> None: + if hasattr(self, "_listen_task") and self._listen_task: + self._listen_task.cancel() + self._listen_task = None + if self._writer: + self._writer.close() + try: + await self._writer.wait_closed() + except Exception: + pass + self._writer = None + self._reader = None + if self._daemon_proc: + self._daemon_proc.terminate() + self._daemon_proc = None + logger.info("Signal channel stopped") + async def _ensure_daemon(self) -> None: """Start signal-cli daemon if not already running.""" try: @@ -404,22 +421,3 @@ class SignalChannel(Channel): await self._rpc_call("send", params) return True - - # ── Cleanup ─────────────────────────────────────────────────── - - async def _cleanup(self) -> None: - if hasattr(self, "_listen_task") and self._listen_task: - self._listen_task.cancel() - self._listen_task = None - if self._writer: - self._writer.close() - try: - await self._writer.wait_closed() - except Exception: - pass - self._writer = None - self._reader = None - if self._daemon_proc: - self._daemon_proc.terminate() - self._daemon_proc = None - logger.info("Signal channel stopped")