diff --git a/api/app/services/memory_base_service.py b/api/app/services/memory_base_service.py index ce4940d0..25a8281d 100644 --- a/api/app/services/memory_base_service.py +++ b/api/app/services/memory_base_service.py @@ -109,8 +109,36 @@ class MemoryTransService: logger.error(f"翻译失败: {str(e)}") return text # 翻译失败时返回原文 - async def is_english(self,text: str) -> bool: - return bool(re.fullmatch(r"[A-Za-z\s]+", text)) + async def is_english(self, text: str) -> bool: + """ + 检查文本是否为英文 + + Args: + text: 要检查的文本(必须是字符串) + + Returns: + True 如果文本主要是英文,False 否则 + + Note: + - 只接受字符串类型 + - 检查是否主要由英文字母和常见标点组成 + - 允许数字、空格和常见标点符号 + """ + if not isinstance(text, str): + raise TypeError(f"is_english 只接受字符串类型,收到: {type(text).__name__}") + + if not text.strip(): + return True # 空字符串视为英文 + + # 更宽松的英文检查:允许字母、数字、空格和常见标点 + # 如果文本中英文字符占比超过 80%,认为是英文 + english_chars = sum(1 for c in text if c.isascii() and (c.isalnum() or c.isspace() or c in '.,!?;:\'"()-')) + total_chars = len(text) + + if total_chars == 0: + return True + + return (english_chars / total_chars) >= 0.8 async def Translate(self, text: str, target_language: str = "en") -> str: """ 通用翻译方法(保持向后兼容) @@ -144,23 +172,99 @@ async def Translation_English(modid, text, fields=None): Returns: 翻译后的数据,保持原有结构 + + Note: + - 对于字符串:直接翻译 + - 对于列表:递归处理每个元素,保持列表长度和索引不变 + - 对于字典:只翻译指定字段(fields参数) + - 对于其他类型:原样返回 """ trans_service = MemoryTransService(modid) - # 执行翻译 - if isinstance(text, list): - english_result=[] - for i in text: - is_eng=await trans_service.is_english(i) - if not is_eng: - english = await trans_service.Translate(i) - english_result.append(english) - return english_result + + # 处理字符串类型 if isinstance(text, str): - is_eng = await trans_service.is_english(text) - if not is_eng: - english_result = await trans_service.Translate(text) - return english_result - return text + # 空字符串直接返回 + if not text.strip(): + return text + + try: + is_eng = await trans_service.is_english(text) + if not is_eng: + english_result = await trans_service.Translate(text) + return english_result + return text + except Exception as e: + logger.warning(f"翻译字符串失败: {e}") + return text + + # 处理列表类型 + elif isinstance(text, list): + english_result = [] + for item in text: + # 递归处理列表中的每个元素 + if isinstance(item, str): + # 字符串元素:检查是否需要翻译 + if not item.strip(): + english_result.append(item) + continue + + try: + is_eng = await trans_service.is_english(item) + if not is_eng: + translated = await trans_service.Translate(item) + english_result.append(translated) + else: + # 保留英文项,不改变列表长度 + english_result.append(item) + except Exception as e: + logger.warning(f"翻译列表项失败: {e}") + english_result.append(item) + + elif isinstance(item, dict): + # 字典元素:递归调用自己处理字典 + translated_dict = await Translation_English(modid, item, fields) + english_result.append(translated_dict) + + elif isinstance(item, list): + # 嵌套列表:递归处理 + translated_list = await Translation_English(modid, item, fields) + english_result.append(translated_list) + + else: + # 其他类型(数字、布尔值等):原样保留 + english_result.append(item) + + return english_result + + # 处理字典类型 + elif isinstance(text, dict): + # 确定要翻译的字段 + if fields is None: + # 默认翻译字段 + fields = [ + 'content', 'summary', 'statement', 'description', + 'name', 'aliases', 'caption', 'emotion_keywords', + 'text', 'title', 'label', 'type' # 添加常用字段 + ] + + # 创建副本,避免修改原始数据 + result = text.copy() + + for field in fields: + if field in result and result[field] is not None: + # 递归翻译字段值(可能是字符串、列表或嵌套字典) + try: + result[field] = await Translation_English(modid, result[field], fields) + except Exception as e: + logger.warning(f"翻译字段 {field} 失败: {e}") + # 翻译失败时保留原值 + continue + + return result + + # 其他类型(数字、布尔值、None等):原样返回 + else: + return text class MemoryBaseService: """记忆服务基类,提供共享的辅助方法"""