import asyncio import logging from datetime import datetime, timedelta from typing import Optional from apscheduler.schedulers.asyncio import AsyncIOScheduler from app.client.mysql_client_manager import db_assistant_mysql_client_manager from app.repository.archive_messages_repository import ArchiveMessagesRepository from app.summary.service import SummaryService logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[logging.FileHandler('summary_task.log'), logging.StreamHandler()] ) logger = logging.getLogger(__name__) async def generate_daily_summary(date: Optional[str] = None): """ 生成指定日期的消息摘要,如果不传日期则生成前一天的摘要 Args: date: 日期字符串,格式 YYYY-MM-DD,不传则默认前一天 """ if not date: yesterday = datetime.now() - timedelta(days=1) date = yesterday.strftime("%Y-%m-%d") logger.info(f"开始生成 {date} 的消息摘要...") try: db_assistant_mysql_client_manager.init() async with db_assistant_mysql_client_manager.session_factory() as db_assistant: archive_messages_repository = ArchiveMessagesRepository(db_assistant) service = SummaryService(archive_messages_repository) summaries = await service.get_message_summary(date) logger.info(f"生成完成,共生成 {len(summaries)} 条摘要") for summary in summaries: logger.info(f"日期: {summary.date}, 发送人: {summary.from_user}, 接收人: {summary.to_user}") return summaries except Exception as e: logger.error(f"生成摘要失败: {str(e)}", exc_info=True) raise def start_scheduler(): """ 启动定时任务调度器,每天凌晨2点执行 """ scheduler = AsyncIOScheduler(timezone='Asia/Shanghai') scheduler.add_job( generate_daily_summary, trigger='cron', hour=2, minute=0, second=0, id='daily_summary_task', name='每日消息摘要任务', replace_existing=True ) logger.info("定时任务调度器已启动,每天凌晨2:00执行消息摘要任务") scheduler.start() try: asyncio.get_event_loop().run_forever() except (KeyboardInterrupt, SystemExit): logger.info("正在关闭定时任务调度器...") scheduler.shutdown() if __name__ == '__main__': import sys if len(sys.argv) > 1: # 如果传入了日期参数,直接生成指定日期的摘要 target_date = sys.argv[1] asyncio.run(generate_daily_summary(target_date)) else: # 否则启动定时任务调度器 start_scheduler()