"""微信消息监听 — 主入口""" from __future__ import annotations import argparse import logging import signal import sys import time from .config import Config from .monitor.event import MessageEvent from .monitor.watcher import WeChatWatcher from .storage.sqlite import SQLiteStorage def setup_logging(config: Config) -> None: fmt = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" handlers: list[logging.Handler] = [logging.StreamHandler(sys.stdout)] if config.log_file: handlers.append(logging.FileHandler(config.log_file, encoding="utf-8")) logging.basicConfig( level=getattr(logging, config.log_level, logging.INFO), format=fmt, handlers=handlers, ) def create_on_message_callback(storage: SQLiteStorage): """创建消息回调:打印 + 持久化""" def _on_message(event: MessageEvent) -> None: msg = event.message # 控制台输出 prefix = "[自己]" if msg.is_self else f"[{msg.sender}]" print(f" {msg.conversation} | {prefix} {msg.content[:120]}") # 存储 storage.save_message(msg) return _on_message def main() -> None: parser = argparse.ArgumentParser(description="微信聊天消息监听器") parser.add_argument("-c", "--conversation", default="", help="指定监听的会话名称(为空则监听当前活跃会话)") parser.add_argument("--db", default="wechat_messages.db", help="SQLite 数据库路径") parser.add_argument("--interval", type=float, default=1.0, help="轮询间隔(秒)") parser.add_argument("--log-level", default="INFO", help="日志级别") args = parser.parse_args() config = Config( poll_interval=args.interval, sqlite_path=args.db, log_level=args.log_level, ) setup_logging(config) logger = logging.getLogger("main") # 初始化存储 storage = SQLiteStorage(config.sqlite_path) storage.connect() # 初始化监听器 watcher = WeChatWatcher(config) watcher.on_message(create_on_message_callback(storage)) logger.info("正在连接微信窗口...") if not watcher.connect(): logger.error("连接微信失败,请确保微信已登录且窗口可见") storage.close() sys.exit(1) # 优雅退出 def _signal_handler(sig, frame): logger.info("收到退出信号,正在停止...") watcher.stop() storage.close() sys.exit(0) signal.signal(signal.SIGINT, _signal_handler) signal.signal(signal.SIGTERM, _signal_handler) # 启动监听 logger.info("开始监听会话: %s", args.conversation or "(当前活跃会话)") watcher.start(conversation=args.conversation) # 主线程保持运行 try: while True: time.sleep(1) if not watcher._wechat.is_alive(): logger.warning("微信窗口已关闭,尝试重新连接...") watcher.stop() time.sleep(2) if watcher.connect(): watcher.start(conversation=args.conversation) else: logger.error("重新连接失败,退出") break except KeyboardInterrupt: pass finally: watcher.stop() storage.close() logger.info("监听器已退出") if __name__ == "__main__": main()