Update __init__.py

fix language Detection
This commit is contained in:
DrStone71
2025-06-17 02:22:24 +02:00
committed by GitHub
parent 31e851cec8
commit 8d4ba650d9
+54 -82
View File
@@ -4,10 +4,13 @@ import traceback
import os
import threading
from pathlib import Path
from langdetect import detect, DetectorFactory
DetectorFactory.seed = 0
class ArgosTranslateManager:
"""Gestore per le operazioni di traduzione con Argos Translate"""
# Mappa completa delle lingue supportate con i loro nomi completi
LANGUAGE_MAP = {
"auto": "Auto-detect",
@@ -50,220 +53,189 @@ class ArgosTranslateManager:
"uk": "Ukrainian (Українська)",
"vi": "Vietnamese (Tiếng Việt)",
}
# Lock per thread safety durante il download
_download_lock = threading.Lock()
_downloading = set()
@classmethod
def get_language_list(cls):
"""Restituisce la lista delle lingue per il menu dropdown con nomi completi"""
return [f"{code} - {name}" for code, name in cls.LANGUAGE_MAP.items()]
@classmethod
def get_language_code_from_display(cls, display_name):
"""Estrae il codice lingua dal nome visualizzato"""
if " - " in display_name:
return display_name.split(" - ")[0]
return display_name
@classmethod
def get_language_display_names(cls):
"""Restituisce la lista dei nomi visualizzati delle lingue"""
return [f"{code}: {name}" for code, name in cls.LANGUAGE_MAP.items()]
@classmethod
def autodetect_language(cls, text):
"""
Rileva la lingua usando langdetect, altrimenti fallback su simple_language_detect.
"""
if not text or len(text.strip()) < 3:
return "en"
try:
code = detect(text)
# 'zh-cn', 'zh-tw' ecc. → normalizza a 'zh'
if code.startswith("zh"):
code = "zh"
if code not in cls.LANGUAGE_MAP:
# Prova mapping per codici tipo 'pt', 'pt-br', 'pt-pt'
base = code.split('-')[0]
if base in cls.LANGUAGE_MAP:
code = base
else:
return "en"
return code
except Exception:
# fallback sul sistema grezzo
return cls.simple_language_detect(text)
@classmethod
def simple_language_detect(cls, text):
"""Semplice rilevamento della lingua basato su caratteri comuni"""
if not text or len(text.strip()) < 3:
return "en"
text_lower = text.lower()
# Controllo per cirillico (russo, ucraino)
# Cirillico
if any(ord(char) >= 0x0400 and ord(char) <= 0x04FF for char in text):
if any(word in text_lower for word in ["що", "але", "або", "який", "яка", "яке"]):
return "uk" # Ucraino
return "ru" # Russo
# Controllo per caratteri cinesi/giapponesi/coreani
return "uk"
return "ru"
if any(ord(char) >= 0x4E00 and ord(char) <= 0x9FFF for char in text):
return "zh" # Cinese
return "zh"
if any(ord(char) >= 0x3040 and ord(char) <= 0x309F for char in text):
return "ja" # Hiragana giapponese
return "ja"
if any(ord(char) >= 0xAC00 and ord(char) <= 0xD7AF for char in text):
return "ko" # Coreano
# Controllo per arabo
return "ko"
if any(ord(char) >= 0x0600 and ord(char) <= 0x06FF for char in text):
return "ar"
# Controllo per ebraico
if any(ord(char) >= 0x0590 and ord(char) <= 0x05FF for char in text):
return "he"
# Controllo per greco
if any(ord(char) >= 0x0370 and ord(char) <= 0x03FF for char in text):
return "el"
# Controllo per thai
if any(ord(char) >= 0x0E00 and ord(char) <= 0x0E7F for char in text):
return "th"
# Controlli per lingue europee con caratteri speciali
if any(char in text for char in "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ"):
if any(word in text_lower for word in ["il", "la", "le", "di", "da", "in", "con", "per", "che", "non", "una", "uno"]):
return "it" # Italiano
return "it"
elif any(word in text_lower for word in ["el", "la", "los", "las", "de", "del", "en", "con", "por", "que", "no", "es", "un", "una"]):
return "es" # Spagnolo
return "es"
elif any(word in text_lower for word in ["le", "la", "les", "de", "du", "des", "en", "dans", "avec", "pour", "que", "ne", "un", "une"]):
return "fr" # Francese
return "fr"
elif any(word in text_lower for word in ["der", "die", "das", "den", "dem", "des", "ein", "eine", "und", "oder", "nicht", "ist"]):
return "de" # Tedesco
return "de"
elif any(word in text_lower for word in ["o", "a", "os", "as", "de", "do", "da", "em", "com", "por", "que", "não", "um", "uma"]):
return "pt" # Portoghese
# Controlli per lingue nordiche
return "pt"
if any(word in text_lower for word in ["och", "att", "är", "den", "det", "en", "ett", "för", "på", "av"]):
return "sv" # Svedese
return "sv"
if any(word in text_lower for word in ["og", "at", "er", "den", "det", "en", "et", "for", "på", "av"]):
return "no" # Norvegese
return "no"
if any(word in text_lower for word in ["og", "at", "er", "den", "det", "en", "et", "for", "på", "af"]):
return "da" # Danese
# Default inglese
return "da"
return "en"
@classmethod
def ensure_translation_package(cls, source_lang, target_lang):
"""Assicura che il pacchetto di traduzione sia installato, scaricandolo se necessario"""
if source_lang == "auto":
return True # Non possiamo pre-scaricare per auto-detect
if source_lang == target_lang:
return True # Non serve traduzione
package_key = f"{source_lang}-{target_lang}"
# Evita download multipli simultanei dello stesso pacchetto
with cls._download_lock:
if package_key in cls._downloading:
print(f"Package {package_key} is already being downloaded, waiting...")
return False
try:
# Controlla se il pacchetto è già installato
installed_languages = argostranslate.translate.get_installed_languages()
source_language = next((lang for lang in installed_languages if lang.code == source_lang), None)
target_language = next((lang for lang in installed_languages if lang.code == target_lang), None)
if source_language and target_language:
translation = source_language.get_translation(target_language)
if translation:
return True # Pacchetto già installato e funzionante
# Aggiorna l'indice dei pacchetti
print(f"Updating package index...")
argostranslate.package.update_package_index()
# Ottieni i pacchetti disponibili
available_packages = argostranslate.package.get_available_packages()
# Trova il pacchetto per la traduzione richiesta
target_package = next(
(pkg for pkg in available_packages
(pkg for pkg in available_packages
if pkg.from_code == source_lang and pkg.to_code == target_lang),
None
)
if target_package is None:
print(f"No translation package available from '{source_lang}' to '{target_lang}'")
return False
if target_package.is_installed():
print(f"Package {source_lang}->{target_lang} is already installed")
return True
# Marca come in download
cls._downloading.add(package_key)
# Scarica e installa il pacchetto
print(f"Downloading translation package: {source_lang} -> {target_lang}")
print(f"Package size: ~{target_package.size // 1024 // 1024}MB (this may take a while...)")
print(f"Package size: ~{getattr(target_package, 'size', 0) // 1024 // 1024}MB (this may take a while...)")
cls._downloading.add(package_key)
download_path = target_package.download()
argostranslate.package.install_from_path(download_path)
print(f"Successfully installed package: {source_lang} -> {target_lang}")
return True
except Exception as e:
print(f"Error downloading package {source_lang}->{target_lang}: {e}")
traceback.print_exc()
return False
finally:
# Rimuovi dalla lista dei download in corso
cls._downloading.discard(package_key)
@classmethod
def translate_text(cls, text, source_lang="auto - Auto-detect", target_lang="en - English"):
"""Traduce il testo usando Argos Translate, scaricando i pacchetti se necessario"""
if not text or not text.strip():
return text
try:
# Estrai i codici lingua dai nomi visualizzati
source_code = cls.get_language_code_from_display(source_lang)
target_code = cls.get_language_code_from_display(target_lang)
# Auto-rilevamento se necessario
if source_code == "auto":
detected_lang = cls.simple_language_detect(text)
detected_lang = cls.autodetect_language(text)
print(f"Auto-detected language: {detected_lang} ({cls.LANGUAGE_MAP.get(detected_lang, 'Unknown')})")
source_code = detected_lang
# Se è già nella lingua target, restituisci il testo originale
if source_code == target_code:
print(f"Text is already in target language ({target_code})")
return text
# Assicura che il pacchetto di traduzione sia installato
if not cls.ensure_translation_package(source_code, target_code):
print(f"Could not ensure translation package for {source_code}->{target_code}")
return text
# Ottieni le lingue installate (refresh dopo possibile download)
installed_languages = argostranslate.translate.get_installed_languages()
# Trova le lingue sorgente e target
source_language = next((lang for lang in installed_languages if lang.code == source_code), None)
target_language = next((lang for lang in installed_languages if lang.code == target_code), None)
if source_language is None:
print(f"Source language '{source_code}' not available after package check")
return text
if target_language is None:
print(f"Target language '{target_code}' not available after package check")
return text
# Ottieni la traduzione
translation = source_language.get_translation(target_language)
if translation is None:
print(f"No translation model available from '{source_code}' to '{target_code}'")
return text
# Esegui la traduzione
translated_text = translation.translate(text)
print(f"Translated ({source_code}->{target_code}): {text[:50]}{'...' if len(text) > 50 else ''}")
return translated_text
except Exception as e:
print(f"Translation error: {e}")
traceback.print_exc()