From ec293040698b67acb95256a9c1f088dbf4d9febd Mon Sep 17 00:00:00 2001 From: SXP-Simon Date: Sun, 8 Feb 2026 21:53:49 +0800 Subject: [PATCH] Refactor: Translate comments and logs to Chinese in application layer --- src/application/message_converter.py | 40 ++++----- src/application/reporting_service.py | 122 +++++++++++++------------- src/application/scheduling_service.py | 102 ++++++++++----------- 3 files changed, 132 insertions(+), 132 deletions(-) diff --git a/src/application/message_converter.py b/src/application/message_converter.py index bcda88d..3040aad 100644 --- a/src/application/message_converter.py +++ b/src/application/message_converter.py @@ -1,8 +1,8 @@ """ -Message Converter - Bridges raw platform messages to UnifiedMessage +消息转换器 - 连接原始平台消息和 UnifiedMessage -This module provides backward compatibility by converting between -raw platform message formats and the new UnifiedMessage format. +该模块通过在原始平台消息格式和新的 UnifiedMessage 格式之间进行转换, +提供向后兼容性。 """ from typing import List, Dict, Any, Optional @@ -17,29 +17,29 @@ from ..domain.value_objects.unified_message import ( class MessageConverter: """ - Converts between raw platform messages and UnifiedMessage format. + 在原始平台消息和 UnifiedMessage 格式之间进行转换。 - This provides a migration path: existing code can continue using - raw dicts while new code uses UnifiedMessage. + 这提供了一个迁移路径:现有代码可以继续使用原始字典, + 而新代码使用 UnifiedMessage。 """ @staticmethod def from_onebot_message(raw_msg: dict, group_id: str) -> Optional[UnifiedMessage]: """ - Convert OneBot v11 raw message to UnifiedMessage. + 将 OneBot v11 原始消息转换为 UnifiedMessage。 Args: - raw_msg: Raw message dict from OneBot API - group_id: Group ID + raw_msg: 来自 OneBot API 的原始消息字典 + group_id: 群组 ID Returns: - UnifiedMessage or None if conversion fails + UnifiedMessage 或 None(如果转换失败) """ try: sender = raw_msg.get("sender", {}) message_chain = raw_msg.get("message", []) - # Handle string message format + # 处理字符串消息格式 if isinstance(message_chain, str): message_chain = [{"type": "text", "data": {"text": message_chain}}] @@ -104,7 +104,7 @@ class MessageConverter: raw_data=seg )) - # Extract reply_to from contents + # 从内容中提取 reply_to reply_to = None for c in contents: if c.type == MessageContentType.REPLY and c.raw_data: @@ -130,9 +130,9 @@ class MessageConverter: @staticmethod def to_onebot_message(unified: UnifiedMessage) -> dict: """ - Convert UnifiedMessage back to OneBot v11 raw format. + 将 UnifiedMessage 转换回 OneBot v11 原始格式。 - For backward compatibility with existing code that expects raw dicts. + 用于与期望原始字典的现有代码向后兼容。 """ message_chain = [] @@ -154,7 +154,7 @@ class MessageConverter: elif content.type == MessageContentType.VIDEO: message_chain.append({"type": "video", "data": {"url": content.url}}) - # Ensure sender fields are populated, even if missing in original + # 确保填充发送者字段,即使原始数据中缺失 sender_data = { "user_id": unified.sender_id, "nickname": unified.sender_name, @@ -167,14 +167,14 @@ class MessageConverter: "group_id": unified.group_id, "message": message_chain, "time": unified.timestamp, - # Add these helper fields for old analyzers that might expect them directly + # 添加这些辅助字段,以便旧分析器可以直接使用 "raw_message": unified.text_content, "user_id": unified.sender_id, } @staticmethod def batch_from_onebot(raw_messages: List[dict], group_id: str) -> List[UnifiedMessage]: - """Convert a batch of OneBot messages to UnifiedMessage list.""" + """将一批 OneBot 消息转换为 UnifiedMessage 列表。""" result = [] for raw_msg in raw_messages: unified = MessageConverter.from_onebot_message(raw_msg, group_id) @@ -184,15 +184,15 @@ class MessageConverter: @staticmethod def batch_to_onebot(unified_messages: List[UnifiedMessage]) -> List[dict]: - """Convert a batch of UnifiedMessage to OneBot raw format.""" + """将一批 UnifiedMessage 转换为 OneBot 原始格式。""" return [MessageConverter.to_onebot_message(msg) for msg in unified_messages] @staticmethod def unified_to_analysis_text(messages: List[UnifiedMessage]) -> str: """ - Convert UnifiedMessage list to analysis text format for LLM. + 将 UnifiedMessage 列表转换为 LLM 分析文本格式。 - This is the format expected by the existing LLM analyzers. + 这是现有 LLM 分析器期望的格式。 """ lines = [] for msg in messages: diff --git a/src/application/reporting_service.py b/src/application/reporting_service.py index 6cdd5ea..44f9567 100644 --- a/src/application/reporting_service.py +++ b/src/application/reporting_service.py @@ -1,7 +1,7 @@ """ -Reporting Service - Application service for generating and sending reports +报告服务 - 生成和发送报告的应用服务 -This service coordinates report generation and delivery to groups. +该服务协调报告的生成并将其发送到群组。 """ from datetime import datetime @@ -20,10 +20,10 @@ from ..infrastructure.persistence import HistoryRepository class ReportingService: """ - Application service for generating and managing reports. + 生成和管理报告的应用服务。 - This service coordinates between domain services and infrastructure - to produce and deliver analysis reports. + 该服务协调领域服务和基础设施 + 以生成和发送分析报告。 """ def __init__( @@ -32,11 +32,11 @@ class ReportingService: history_repository: HistoryRepository, ): """ - Initialize the reporting service. + 初始化报告服务。 Args: - config: Configuration manager - history_repository: Repository for storing reports + config: 配置管理器 + history_repository: 用于存储报告的仓库 """ self.config = config self.history = history_repository @@ -52,19 +52,19 @@ class ReportingService: date_str: Optional[str] = None, ) -> str: """ - Generate a complete analysis report. + 生成完整的分析报告。 Args: - group_id: Group identifier - group_name: Group display name - statistics: Group statistics - topics: List of discussion topics - user_titles: List of user titles - golden_quotes: List of golden quotes - date_str: Report date (defaults to today) + group_id: 群组标识符 + group_name: 群组显示名称 + statistics: 群组统计 + topics: 讨论话题列表 + user_titles: 用户称号列表 + golden_quotes: 金句列表 + date_str: 报告日期(默认为今天) Returns: - Formatted report string + 格式化的报告字符串 """ date_str = date_str or datetime.now().strftime("%Y-%m-%d") @@ -73,7 +73,7 @@ class ReportingService: date_str=date_str, ) - # Generate report based on configuration + # 根据配置生成报告 report = generator.generate_full_report( statistics=statistics, topics=topics if self.config.get_include_topics() else [], @@ -94,17 +94,17 @@ class ReportingService: date_str: Optional[str] = None, ) -> str: """ - Generate a brief summary report. + 生成简要摘要报告。 Args: - group_id: Group identifier - statistics: Group statistics - top_topic: Most significant topic - top_quote: Best golden quote - date_str: Report date + group_id: 群组标识符 + statistics: 群组统计 + top_topic: 最重要的话题 + top_quote: 最佳金句 + date_str: 报告日期 Returns: - Brief summary string + 简要摘要字符串 """ date_str = date_str or datetime.now().strftime("%Y-%m-%d") @@ -122,15 +122,15 @@ class ReportingService: date_str: Optional[str] = None, ) -> bool: """ - Save a report to history. + 保存报告到历史记录。 Args: - group_id: Group identifier - report_data: Report data dictionary - date_str: Report date + group_id: 群组标识符 + report_data: 报告数据字典 + date_str: 报告日期 Returns: - True if saved successfully + 如果保存成功则返回 True """ date_str = date_str or datetime.now().strftime("%Y-%m-%d") @@ -146,14 +146,14 @@ class ReportingService: date_str: str, ) -> Optional[Dict[str, Any]]: """ - Get a saved report. + 获取已保存的报告。 Args: - group_id: Group identifier - date_str: Report date + group_id: 群组标识符 + date_str: 报告日期 Returns: - Report data or None + 报告数据或 None """ return self.history.get_analysis_result(group_id, date_str) @@ -163,26 +163,26 @@ class ReportingService: limit: int = 7, ) -> List[Dict[str, Any]]: """ - Get recent reports for a group. + 获取群组的最近报告。 Args: - group_id: Group identifier - limit: Maximum number of reports + group_id: 群组标识符 + limit: 最大报告数 Returns: - List of report data dictionaries + 报告数据字典列表 """ return self.history.get_recent_results(group_id, limit) def has_report_for_today(self, group_id: str) -> bool: """ - Check if a report exists for today. + 检查今天是否已存在报告。 Args: - group_id: Group identifier + group_id: 群组标识符 Returns: - True if report exists + 如果报告存在则返回 True """ today = datetime.now().strftime("%Y-%m-%d") return self.history.has_analysis_for_date(group_id, today) @@ -194,37 +194,37 @@ class ReportingService: format_type: Optional[str] = None, ) -> str: """ - Format a report for a specific platform. + 为特定平台格式化报告。 Args: - report: Raw report text - platform: Target platform - format_type: Override format type + report: 原始报告文本 + platform: 目标平台 + format_type: 覆盖格式类型 Returns: - Platform-formatted report + 平台格式化的报告 """ format_type = format_type or self.config.get_report_format() - # For now, return as-is. Can be extended for platform-specific formatting + # 目前保持原样返回。可以扩展为平台特定的格式化 if format_type == "markdown": return report elif format_type == "text": - # Strip markdown formatting + # 去除 markdown 格式 return self._strip_markdown(report) else: return report def _strip_markdown(self, text: str) -> str: - """Strip markdown formatting from text.""" - # Simple markdown stripping + """从文本中去除 markdown 格式。""" + # 简单的 markdown 去除 import re - # Remove bold + # 去除加粗 text = re.sub(r"\*\*(.*?)\*\*", r"\1", text) - # Remove italic + # 去除斜体 text = re.sub(r"\*(.*?)\*", r"\1", text) - # Remove headers + # 去除标题 text = re.sub(r"^#+\s*", "", text, flags=re.MULTILINE) return text @@ -239,18 +239,18 @@ class ReportingService: golden_quotes: List[GoldenQuote], ) -> Dict[str, Any]: """ - Create a report data dictionary for storage. + 创建用于存储的报告数据字典。 Args: - group_id: Group identifier - group_name: Group display name - statistics: Group statistics - topics: List of topics - user_titles: List of user titles - golden_quotes: List of golden quotes + group_id: 群组标识符 + group_name: 群组显示名称 + statistics: 群组统计 + topics: 话题列表 + user_titles: 用户称号列表 + golden_quotes: 金句列表 Returns: - Report data dictionary + 报告数据字典 """ return { "group_id": group_id, diff --git a/src/application/scheduling_service.py b/src/application/scheduling_service.py index 77ec456..72ad309 100644 --- a/src/application/scheduling_service.py +++ b/src/application/scheduling_service.py @@ -1,8 +1,8 @@ """ -Scheduling Service - Application service for scheduled analysis +调度服务 - 计划分析的应用服务 -This service manages scheduled analysis tasks and coordinates -with the analysis orchestrator. +该服务管理计划的分析任务并与 +分析编排器协调。 """ import asyncio @@ -16,13 +16,13 @@ from ..shared.constants import TASK_STATE_PENDING, TASK_STATE_RUNNING, TASK_STAT class ScheduledTask: - """Represents a scheduled analysis task.""" + """表示一个计划的分析任务。""" def __init__( self, task_id: str, group_id: str, - scheduled_time: str, # HH:MM format + scheduled_time: str, # HH:MM 格式 callback: Callable, enabled: bool = True, ): @@ -36,7 +36,7 @@ class ScheduledTask: self._calculate_next_run() def _calculate_next_run(self) -> None: - """Calculate the next run time.""" + """计算下一次运行时间。""" if not self.enabled: self.next_run = None return @@ -46,50 +46,50 @@ class ScheduledTask: now = datetime.now() next_run = now.replace(hour=hours, minute=minutes, second=0, microsecond=0) - # If the time has passed today, schedule for tomorrow + # 如果今天的时间已过,计划明天运行 if next_run <= now: next_run += timedelta(days=1) self.next_run = next_run except ValueError: - logger.error(f"Invalid scheduled time format: {self.scheduled_time}") + logger.error(f"无效的计划时间格式: {self.scheduled_time}") self.next_run = None def should_run(self) -> bool: - """Check if the task should run now.""" + """检查任务现在是否应该运行。""" if not self.enabled or not self.next_run: return False now = datetime.now() - # Check if we're within the execution window (5 minute tolerance) + # 检查我们是否在执行窗口内(5分钟容差) if self.next_run <= now <= self.next_run + timedelta(minutes=5): - # Check if we haven't run today + # 检查我们今天是否还没有运行 if self.last_run is None or self.last_run.date() != now.date(): return True return False def mark_completed(self) -> None: - """Mark the task as completed and schedule next run.""" + """将任务标记为完成并计划下一次运行。""" self.last_run = datetime.now() self._calculate_next_run() class SchedulingService: """ - Application service for managing scheduled analysis tasks. + 管理计划分析任务的应用服务。 - This service runs a background loop that checks for and - executes scheduled tasks. + 该服务运行一个后台循环,检查并 + 执行计划的任务。 """ def __init__(self, config: ConfigManager): """ - Initialize the scheduling service. + 初始化调度服务。 Args: - config: Configuration manager + config: 配置管理器 """ self.config = config self._tasks: Dict[str, ScheduledTask] = {} @@ -99,11 +99,11 @@ class SchedulingService: def register_callback(self, name: str, callback: Callable) -> None: """ - Register a callback for scheduled tasks. + 为计划任务注册回调。 Args: - name: Callback name - callback: Async callback function + name: 回调名称 + callback: 异步回调函数 """ self._callbacks[name] = callback @@ -114,22 +114,22 @@ class SchedulingService: callback_name: str = "analyze", ) -> str: """ - Add a scheduled task for a group. + 为群组添加计划任务。 Args: - group_id: Group identifier - scheduled_time: Time in HH:MM format (uses config default if not provided) - callback_name: Name of registered callback to use + group_id: 群组标识符 + scheduled_time: HH:MM 格式的时间(如果未提供,则使用配置默认值) + callback_name: 要使用的注册回调的名称 Returns: - Task ID + 任务 ID """ scheduled_time = scheduled_time or self.config.get_analysis_time() task_id = f"task_{group_id}" callback = self._callbacks.get(callback_name) if not callback: - logger.warning(f"Callback '{callback_name}' not registered") + logger.warning(f"回调 '{callback_name}' 未注册") return task_id task = ScheduledTask( @@ -141,28 +141,28 @@ class SchedulingService: ) self._tasks[task_id] = task - logger.info(f"Added scheduled task {task_id} for {scheduled_time}") + logger.info(f"为 {scheduled_time} 添加了计划任务 {task_id}") return task_id def remove_task(self, task_id: str) -> bool: """ - Remove a scheduled task. + 移除计划任务。 Args: - task_id: Task identifier + task_id: 任务标识符 Returns: - True if task was removed + 如果任务被移除则返回 True """ if task_id in self._tasks: del self._tasks[task_id] - logger.info(f"Removed scheduled task {task_id}") + logger.info(f"移除了计划任务 {task_id}") return True return False def enable_task(self, task_id: str) -> bool: - """Enable a scheduled task.""" + """启用计划任务。""" if task_id in self._tasks: self._tasks[task_id].enabled = True self._tasks[task_id]._calculate_next_run() @@ -170,7 +170,7 @@ class SchedulingService: return False def disable_task(self, task_id: str) -> bool: - """Disable a scheduled task.""" + """禁用计划任务。""" if task_id in self._tasks: self._tasks[task_id].enabled = False self._tasks[task_id].next_run = None @@ -179,13 +179,13 @@ class SchedulingService: def get_task_status(self, task_id: str) -> Optional[Dict[str, Any]]: """ - Get status of a scheduled task. + 获取计划任务的状态。 Args: - task_id: Task identifier + task_id: 任务标识符 Returns: - Task status dictionary or None + 任务状态字典或 None """ task = self._tasks.get(task_id) if not task: @@ -201,20 +201,20 @@ class SchedulingService: } def list_tasks(self) -> List[Dict[str, Any]]: - """List all scheduled tasks.""" + """列出所有计划任务。""" return [self.get_task_status(tid) for tid in self._tasks.keys()] async def start(self) -> None: - """Start the scheduling service.""" + """启动调度服务。""" if self._running: return self._running = True self._task = asyncio.create_task(self._run_loop()) - logger.info("Scheduling service started") + logger.info("调度服务已启动") async def stop(self) -> None: - """Stop the scheduling service.""" + """停止调度服务。""" self._running = False if self._task: self._task.cancel() @@ -222,37 +222,37 @@ class SchedulingService: await self._task except asyncio.CancelledError: pass - logger.info("Scheduling service stopped") + logger.info("调度服务已停止") async def _run_loop(self) -> None: - """Main scheduling loop.""" + """主调度循环。""" while self._running: try: await self._check_and_run_tasks() - # Check every minute + # 每分钟检查一次 await asyncio.sleep(60) except asyncio.CancelledError: break except Exception as e: - logger.error(f"Error in scheduling loop: {e}") + logger.error(f"调度循环出错: {e}") await asyncio.sleep(60) async def _check_and_run_tasks(self) -> None: - """Check for and execute due tasks.""" + """检查并执行到期任务。""" for task in list(self._tasks.values()): if task.should_run(): try: - logger.info(f"Executing scheduled task {task.task_id}") + logger.info(f"正在执行计划任务 {task.task_id}") await task.callback(task.group_id) task.mark_completed() - logger.info(f"Completed scheduled task {task.task_id}") + logger.info(f"计划任务 {task.task_id} 已完成") except Exception as e: - logger.error(f"Failed to execute task {task.task_id}: {e}") + logger.error(f"执行任务 {task.task_id} 失败: {e}") def setup_from_config(self) -> None: - """Set up scheduled tasks from configuration.""" + """根据配置设置计划任务。""" if not self.config.get_auto_analysis_enabled(): - logger.info("Auto analysis is disabled") + logger.info("自动分析已禁用") return enabled_groups = self.config.get_enabled_groups() @@ -261,4 +261,4 @@ class SchedulingService: for group_id in enabled_groups: self.add_task(group_id, analysis_time) - logger.info(f"Set up {len(enabled_groups)} scheduled tasks") + logger.info(f"设置了 {len(enabled_groups)} 个计划任务")