Files
msgbot/main.py
T
youpaishidifu 2a3ecdba14 修复bot自言自语大小写不敏感问题 + 退出时后台内存回收不阻塞
- monitor.py: 去重管道所有比较改为大小写不敏感(recent_replies时间窗口、_replied_texts、_fuzzy_duplicate、子串包含、长公共子串、_last_bot_reply_content)
- main.py: CTRL+C信号处理将内存回收放到后台线程,不阻塞退出
- gui.py: 无实质修改(仅格式)
2026-08-23 21:30:05 +08:00

87 lines
2.7 KiB
Python

"""消息问答助手 — 入口"""
import logging
import os
import sys
import signal
import threading
# ── Worker 模式检测:PyInstaller 打包后,exe 被调用来运行 worker 脚本时,
# 通过环境变量区分,避免 bootloader 执行 main() 导致闪退 ──
if os.environ.get("EASYOCR_WORKER") == "1":
# 直接执行 worker 逻辑,跳过 GUI 初始化
import easyocr_worker
easyocr_worker._main()
sys.exit(0)
# 确保在项目目录
os.chdir(os.path.dirname(os.path.abspath(__file__)))
# 配置日志
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
)
# 文件日志(持久化,便于排查)
_fh = logging.FileHandler("msgbot.log", encoding="utf-8", mode="w")
_fh.setLevel(logging.DEBUG)
_fh.setFormatter(logging.Formatter("%(asctime)s [%(name)s] %(levelname)s: %(message)s"))
# 过滤 comtypes 的 DEBUG 洪流
class ComtypesFilter(logging.Filter):
def filter(self, record):
return not record.name.startswith("comtypes") or record.levelno >= logging.WARNING
_fh.addFilter(ComtypesFilter())
logging.getLogger().addHandler(_fh)
logger = logging.getLogger("msgbot")
def main():
logger.info("消息问答助手启动中...")
# 动态导入 gui,避免 customtkinter 等缺失导致整个程序崩溃前无日志
try:
from gui import MsgBotApp
except ImportError as e:
logger.error(f"导入 GUI 失败: {e}")
logger.error("请先安装依赖: pip install -r requirements.txt")
sys.exit(1)
app = MsgBotApp()
# Ctrl+C 信号处理:Windows Tkinter mainloop 不响应 KeyboardInterrupt
# 需 signal handler 强制停止监控 + 释放内存 + 退出
def _sigint_handler(sig, frame):
logger.info("收到 Ctrl+C,正在关闭...")
# 后台线程执行内存回收,不阻塞退出
def _cleanup_in_background():
try:
# 释放OCR引擎(杀子进程+系统内存回收)
app._ocr_manager._release()
except Exception:
pass
try:
app.monitor.stop()
except Exception:
pass
# 系统内存清理
from gui import _force_system_memory_cleanup
_force_system_memory_cleanup()
logger.info("后台内存回收完成")
threading.Thread(target=_cleanup_in_background, daemon=True, name="sigint-cleanup").start()
# 立即退出,不等待内存回收完成
app.quit()
sys.exit(0)
signal.signal(signal.SIGINT, _sigint_handler)
app.mainloop()
if __name__ == "__main__":
main()