Files
abot/main.py
liuwei 2a54650a6f 完善表情资产后台能力并补充群总结落库
- 新增表情资产表,支持表情文件落盘后的资产沉淀、查询与发送时间回写
- 将表情下载从消息主链路中移出,改为后台定时批处理,降低同步入库阻塞风险
- 抽取通用 CDN 下载与 base64 落盘能力,统一图片与表情文件处理方式
- 在后台通讯录聊天窗口增加表情资产面板,支持查看资产并直接选择发送表情
- 新增后台表情资产接口,支持按群过滤最近表情素材
- 优化消息列表中的表情消息展示,支持在后台直接预览表情图片
- 启动时不再同步补偿历史表情,统一交由定时任务处理,避免影响系统稳定性
- 新增群总结落库表,支持将每日总结写入数据库,便于后续知识库提取与复用
- 将定时总结结果写入数据库,保留总结文本、周期信息、消息数量和元数据
2026-04-02 17:52:17 +08:00

162 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import asyncio
import threading
from admin.GlancesMonitor import GlancesMonitor
from utils.decorator.async_job import async_job
from configuration import Config
from plugins.xiuren_image.images_cache import ImageCacheManager
from robot import Robot
from loguru import logger
from utils.sehuatang.sehuatang_bot import SehuatangCrawler
# INFO 日志(包含 INFO、DEBUG但不包含 WARNING、ERROR
logger.add(
f"logs/wx_info.log",
level="INFO",
filter=lambda record: record["level"].name in ["INFO", "DEBUG"],
rotation="10 MB",
retention="7 days",
encoding="utf-8"
)
# ERROR 日志(仅 ERROR 及以上)
logger.add(
f"logs/wx_error.log",
level="ERROR",
rotation="10 MB",
retention="7 days",
encoding="utf-8"
)
# ERROR 日志(仅 ERROR 及以上)
logger.add(
f"logs/wx_debug.log",
level="DEBUG",
rotation="10 MB",
retention="7 days",
encoding="utf-8"
)
def main():
config = Config()
# 创建机器人实例
robot = Robot(config)
robot.LOG.info(f"ABOT服务 正在启动...")
# 初始化并启动wechat_ipad客户端
if robot.init_wechat_ipad():
robot.LOG.info("wechat_ipad客户端启动成功")
else:
robot.LOG.error("wechat_ipad客户端启动失败")
# 注册定时任务
jobs(robot)
# 启动Dashboard服务器
try:
# 创建Dashboard服务器实例共享robot对象
from admin.dashboard.server import DashboardServer
dashboard_server = DashboardServer(robot_instance=robot)
# 在单独的线程中启动Dashboard服务器
dashboard_thread = threading.Thread(target=dashboard_server.run, daemon=True)
dashboard_thread.start()
robot.LOG.info(f"Dashboard服务器已在 http://{dashboard_server.host}:{dashboard_server.port} 启动")
except Exception as e:
robot.LOG.error(f"Dashboard服务器启动失败: {e}")
try:
robot.LOG.debug(f"开始启动GlancesMonitor")
# 初始化 Glances 监控
monitor = GlancesMonitor(
email_sender=robot.email_sender,
host=config.glances.get("host"),
port=config.glances.get("port"),
cpu_threshold=80.0,
load_threshold=16, # 自动设为 CPU 核心数 * 2
io_threshold=100.0,
disk_usage_threshold=70.0,
handle_threshold=20000,
recipient=config.email.get("alert_recipient")
)
monitor.run()
except Exception as e:
robot.LOG.error(f"GlancesMonitor服务器启动失败: {e}")
robot.LOG.info(f"=" * 50)
asyncio.run(async_job.run_all())
# 让机器人一直跑
robot.keep_running_and_block_process()
def jobs(robot: Robot):
# ✅ 每天 8:30 发送百度新闻
@async_job.at_times(["08:30"])
async def news_baidu_report_auto_job():
await robot.news_baidu_report_auto()
# ✅ 每天 10:30 推送 Epic 免费游戏
@async_job.every_weekday_time(weekday=4, time_str="10:00") # 0=周一4=周五
async def epic_job():
await robot.send_epic_free_games()
# ✅ 每天 02:30 从 redis 写入 sqlite
@async_job.at_times(["02:30"])
async def msg_count_to_db_job():
await robot.message_count_to_db()
# ✅ 每天 09:30 从 sqlite 读取并发送群排行
@async_job.at_times(["09:30"])
async def msg_ranking_job():
await robot.generate_and_send_ranking()
# ✅ 每天 15:30 发涩图 PDF
@async_job.at_times(["15:30"])
async def sehuatang_pdf_job():
await robot.generate_sehuatang_pdf()
# ✅ 每天 01:30 下载秀人网帖子
@async_job.at_times(["01:30"])
async def xiuren_download_job():
await robot.xiu_ren_download_task()
# ✅ 每天 01:30 下载秀人网帖子
@async_job.at_times(["2:30"])
async def shenshiR15_download_job():
await robot.shen_shi_download_task()
# ✅ 每天 17:30 发秀人 PDF如果启用
# @async_job.at_times(["17:30"])
# async def xiuren_pdf_send_job():
# await robot.xiu_ren_pdf_send()
# ✅ 每 3 小时登录验证
@async_job.at_times(["14:43"])
async def login_check_job():
await robot.login_twice_auto_auth()
@async_job.at_times(["05:00"])
async def update_image_cache_job():
logger.info("开始执行图片缓存更新任务")
manager = ImageCacheManager("/mnt/nfs_share") # 替换为你的图片目录
await manager.update_image_cache()
logger.info("图片缓存更新完成")
# ✅ 每2分钟处理一次待下载的图片消息串行处理避免数据库锁竞争
@async_job.every_minutes(5)
async def process_pending_images_job():
if hasattr(robot, 'message_storage') and robot.message_storage:
await robot.message_storage.process_pending_images(minutes_ago=10, batch_size=20)
@async_job.every_minutes(5)
async def process_pending_emojis_job():
if hasattr(robot, 'message_storage') and robot.message_storage:
await robot.message_storage.process_pending_emojis(minutes_ago=60 * 24 * 7, batch_size=30)
if __name__ == "__main__":
main()