From 3652f85f7565d23df3a5140726df0c59703f06fc Mon Sep 17 00:00:00 2001 From: tangwang Date: Thu, 18 Dec 2025 18:06:24 +0800 Subject: [PATCH] trans for index --- query/translator.py | 101 +++++++++++++++++++++++++++++------------------------------------------------------------------------ 1 file changed, 29 insertions(+), 72 deletions(-) diff --git a/query/translator.py b/query/translator.py index e193791..0e77f77 100644 --- a/query/translator.py +++ b/query/translator.py @@ -136,11 +136,11 @@ class Translator: # Optimization: Skip translation if not needed if target_lang == 'en' and self._is_english_text(text): - logger.debug(f"[Translator] Text is already English, skipping translation: '{text[:50]}...'") + logger.info(f"[Translator] Text is already English, skipping translation: '{text[:50]}...'") return text if target_lang == 'zh' and (self._contains_chinese(text) or self._is_pure_number(text)): - logger.debug(f"[Translator] Text contains Chinese or is pure number, skipping translation: '{text[:50]}...'") + logger.info(f"[Translator] Text contains Chinese or is pure number, skipping translation: '{text[:50]}...'") return text # Use provided context or default context @@ -157,6 +157,10 @@ class Translator: if self.use_cache and self.redis_client: cached = self._get_cached_translation_redis(text, target_lang, source_lang, translation_context, prompt) if cached: + logger.info( + f"[Translator] Cache hit: source={source_lang or 'auto'} " + f"target={target_lang} | text='{text[:80]}...' -> '{cached[:80]}...'" + ) return cached # If no API key, return mock translation (for testing) @@ -164,19 +168,24 @@ class Translator: logger.debug(f"[Translator] No API key, returning original text (mock mode)") return text - # Translate using DeepL with fallback + # Translate using DeepL (Pro endpoint only, no free fallback) + logger.info( + f"[Translator] Translating text: target={target_lang}, " + f"source={source_lang or 'auto'}, context={translation_context}, " + f"prompt={'yes' if prompt else 'no'} | text='{text[:80]}...'" + ) result = self._translate_deepl(text, target_lang, source_lang, translation_context, prompt) - # If translation failed, try fallback to free API - if result is None and "api.deepl.com" in self.DEEPL_API_URL: - logger.debug(f"[Translator] Pro API failed, trying free API...") - result = self._translate_deepl_free(text, target_lang, source_lang, translation_context, prompt) - # If still failed, return original text with warning if result is None: logger.warning(f"[Translator] Translation failed for '{text[:50]}...', returning original text") result = text + logger.info( + f"[Translator] Translation completed: source={source_lang or 'auto'} " + f"target={target_lang} | original='{text[:80]}...' -> '{result[:80]}...'" + ) + # Cache result if result and self.use_cache and self.redis_client: self._set_cached_translation_redis(text, target_lang, result, source_lang, translation_context, prompt) @@ -268,68 +277,9 @@ class Translator: logger.error(f"[Translator] Translation failed: {e}", exc_info=True) return None - def _translate_deepl_free( - self, - text: str, - target_lang: str, - source_lang: Optional[str], - context: Optional[str] = None, - prompt: Optional[str] = None - ) -> Optional[str]: - """ - Translate using DeepL Free API. - - Note: Free API may not support glossary_id parameter. - """ - # Map to DeepL language codes - target_code = self.LANG_CODE_MAP.get(target_lang, target_lang.upper()) - - headers = { - "Authorization": f"DeepL-Auth-Key {self.api_key}", - "Content-Type": "application/json", - } - - # Use prompt as context parameter for DeepL API - api_context = prompt if prompt else context - - payload = { - "text": [text], - "target_lang": target_code, - } - - if source_lang: - source_code = self.LANG_CODE_MAP.get(source_lang, source_lang.upper()) - payload["source_lang"] = source_code - - # Add context parameter - if api_context: - payload["context"] = api_context - - # Note: Free API typically doesn't support glossary_id - # But we can still use context hints in the text - - try: - response = requests.post( - "https://api-free.deepl.com/v2/translate", - headers=headers, - json=payload, - timeout=self.timeout - ) - - if response.status_code == 200: - data = response.json() - if "translations" in data and len(data["translations"]) > 0: - return data["translations"][0]["text"] - else: - logger.error(f"[Translator] DeepL Free API error: {response.status_code} - {response.text}") - return None - - except requests.Timeout: - logger.warning(f"[Translator] Free API request timed out") - return None - except Exception as e: - logger.error(f"[Translator] Free API translation failed: {e}", exc_info=True) - return None + # NOTE: _translate_deepl_free is intentionally not implemented. + # We do not support automatic fallback to the free endpoint, to avoid + # mixing Pro keys with https://api-free.deepl.com and related 403 errors. def translate_multi( self, @@ -493,8 +443,12 @@ class Translator: if value: # Sliding expiration: reset expiration time on access self.redis_client.expire(cache_key, self.expire_time) - logger.debug(f"[Translator] Cache hit for translation: {text} -> {target_lang}") + logger.info( + f"[Translator] Redis cache hit: key={cache_key}, " + f"target={target_lang}, value='{value[:80]}...'" + ) return value + logger.debug(f"[Translator] Redis cache miss: key={cache_key}, target={target_lang}") return None except Exception as e: logger.error(f"[Translator] Redis error during get translation cache: '{text}' {target_lang}: {e}") @@ -516,7 +470,10 @@ class Translator: try: cache_key = f"{self.cache_prefix}:{target_lang.upper()}:{text}" self.redis_client.setex(cache_key, self.expire_time, translation) - logger.debug(f"[Translator] Cached translation: {text} -> {target_lang}: {translation}") + logger.info( + f"[Translator] Cached translation: key={cache_key}, " + f"target={target_lang}, value='{translation}...'" + ) except Exception as e: logger.error(f"[Translator] Redis error during set translation cache: '{text}' {target_lang}: {e}") -- libgit2 0.21.2