feat(translate): refonte du design de la page de traduction et du sélecteur de moteurs (Etapes 1-3)
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m12s

This commit is contained in:
2026-05-31 10:14:23 +02:00
parent 9532fef2cd
commit c1ea65f10f
17 changed files with 956 additions and 325 deletions

View File

@@ -886,6 +886,70 @@ RULES:
return results
def translate_image(self, image_path: str, target_language: str) -> str:
"""Translate text within an image using OpenRouter vision model"""
import base64
try:
# Read and encode image
with open(image_path, "rb") as img_file:
image_data = base64.b64encode(img_file.read()).decode("utf-8")
# Determine image type from extension
ext = image_path.lower().split(".")[-1]
media_type = (
f"image/{ext}"
if ext in ["png", "jpg", "jpeg", "gif", "webp"]
else "image/png"
)
# Determine a vision model. If the current model doesn't support vision,
# use a fast vision fallback model like google/gemini-2.0-flash-001
vision_model = self.model
if "deepseek" in vision_model:
vision_model = "google/gemini-2.0-flash-001"
session = self._get_session()
payload = {
"model": vision_model,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": f"Extract all text from this image and translate it to {target_language}. Return ONLY the translated text, preserving the structure and formatting.",
},
{
"type": "image_url",
"image_url": {
"url": f"data:{media_type};base64,{image_data}"
},
},
],
}
],
"max_tokens": 1000,
}
response = session.post(
f"{self.base_url}/chat/completions",
json=payload,
timeout=60,
)
response.raise_for_status()
result = response.json()
translated = (
result.get("choices", [{}])[0]
.get("message", {})
.get("content", "")
.strip()
)
return translated
except Exception as e:
logger.warning("openrouter_vision_error", error_type=type(e).__name__, error=str(e))
return ""
@staticmethod
def list_recommended_models() -> List[dict]:
"""List recommended models for translation with pricing"""
@@ -1111,11 +1175,13 @@ class TranslationService:
if not self.translate_images:
return ""
# Ollama and OpenAI support image translation
# Ollama, OpenAI, and OpenRouter support image translation
if isinstance(self.provider, OllamaTranslationProvider):
return self.provider.translate_image(image_path, target_language)
elif isinstance(self.provider, OpenAITranslationProvider):
return self.provider.translate_image(image_path, target_language)
elif isinstance(self.provider, OpenRouterTranslationProvider):
return self.provider.translate_image(image_path, target_language)
return ""