first commit
This commit is contained in:
154
modules/translator.py
Normal file
154
modules/translator.py
Normal file
@@ -0,0 +1,154 @@
|
||||
# modules/translator.py
|
||||
"""
|
||||
Модуль для перевода текста с кешем
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
import time
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class TranslationProvider(ABC):
|
||||
"""Абстрактный класс для провайдеров перевода"""
|
||||
|
||||
@abstractmethod
|
||||
def translate(self, text, source_lang, target_lang):
|
||||
pass
|
||||
|
||||
|
||||
class GoogleTranslateProvider(TranslationProvider):
|
||||
"""Провайдер Google Translate"""
|
||||
|
||||
def __init__(self, api_key):
|
||||
self.api_key = api_key
|
||||
|
||||
def translate(self, text, source_lang='pl', target_lang='uk'):
|
||||
try:
|
||||
from googletrans import Translator
|
||||
translator = Translator()
|
||||
result = translator.translate(text, src=source_lang, dest=target_lang)
|
||||
return result.text
|
||||
except Exception as e:
|
||||
logging.error(f"Google Translate error: {e}")
|
||||
raise
|
||||
|
||||
|
||||
class DeepLProvider(TranslationProvider):
|
||||
"""Провайдер DeepL"""
|
||||
|
||||
def __init__(self, api_key):
|
||||
self.api_key = api_key
|
||||
|
||||
def translate(self, text, source_lang='PL', target_lang='UK'):
|
||||
try:
|
||||
import deepl
|
||||
translator = deepl.Translator(self.api_key)
|
||||
result = translator.translate_text(text, source_lang=source_lang, target_lang=target_lang)
|
||||
return result.text
|
||||
except Exception as e:
|
||||
logging.error(f"DeepL error: {e}")
|
||||
raise
|
||||
|
||||
|
||||
class LibreTranslateProvider(TranslationProvider):
|
||||
"""Провайдер LibreTranslate"""
|
||||
|
||||
def __init__(self, url, api_key=None):
|
||||
self.url = url
|
||||
self.api_key = api_key
|
||||
|
||||
def translate(self, text, source_lang='pl', target_lang='uk'):
|
||||
try:
|
||||
import requests
|
||||
|
||||
data = {
|
||||
'q': text,
|
||||
'source': source_lang,
|
||||
'target': target_lang,
|
||||
'format': 'text'
|
||||
}
|
||||
|
||||
if self.api_key:
|
||||
data['api_key'] = self.api_key
|
||||
|
||||
response = requests.post(f"{self.url}/translate", data=data)
|
||||
response.raise_for_status()
|
||||
|
||||
return response.json()['translatedText']
|
||||
except Exception as e:
|
||||
logging.error(f"LibreTranslate error: {e}")
|
||||
raise
|
||||
|
||||
|
||||
class TranslationService:
|
||||
"""Сервис для перевода с кешем"""
|
||||
|
||||
def __init__(self, config, storage):
|
||||
self.config = config
|
||||
self.storage = storage
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
# Инициализация провайдера
|
||||
self.provider = self._init_provider()
|
||||
|
||||
# Настройки
|
||||
self.cache_enabled = config.get('translation.cache_enabled', True)
|
||||
self.source_lang = config.get('translation.google.source_lang', 'pl')
|
||||
self.target_lang = config.get('translation.google.target_lang', 'uk')
|
||||
|
||||
def _init_provider(self):
|
||||
"""Инициализирует провайдера перевода"""
|
||||
service = self.config.get('translation.service', 'google')
|
||||
|
||||
if service == 'google':
|
||||
api_key = self.config.get('translation.google.api_key')
|
||||
if not api_key:
|
||||
self.logger.warning("Google Translate API key not found, using googletrans library")
|
||||
return GoogleTranslateProvider(api_key)
|
||||
|
||||
elif service == 'deepl':
|
||||
api_key = self.config.get('translation.deepl.api_key')
|
||||
if not api_key:
|
||||
raise ValueError("DeepL API key is required")
|
||||
return DeepLProvider(api_key)
|
||||
|
||||
elif service == 'libretranslate':
|
||||
url = self.config.get('translation.libretranslate.url')
|
||||
api_key = self.config.get('translation.libretranslate.api_key')
|
||||
return LibreTranslateProvider(url, api_key)
|
||||
|
||||
else:
|
||||
raise ValueError(f"Unsupported translation service: {service}")
|
||||
|
||||
def translate(self, text):
|
||||
"""Переводит текст с использованием кеша"""
|
||||
if not text or not text.strip():
|
||||
return text
|
||||
|
||||
text = text.strip()
|
||||
|
||||
# Проверяем кеш
|
||||
if self.cache_enabled:
|
||||
cached = self.storage.get_translation_from_cache(text)
|
||||
if cached:
|
||||
return cached
|
||||
|
||||
try:
|
||||
# Переводим
|
||||
translated = self.provider.translate(text, self.source_lang, self.target_lang)
|
||||
|
||||
# Сохраняем в кеш
|
||||
if self.cache_enabled and translated:
|
||||
self.storage.save_translation_to_cache(text, translated)
|
||||
|
||||
# Небольшая пауза чтобы не превысить лимиты API
|
||||
time.sleep(0.1)
|
||||
|
||||
return translated
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Translation failed for text '{text[:50]}...': {e}")
|
||||
return text # Возвращаем оригинальный текст при ошибке
|
||||
|
||||
|
||||
Reference in New Issue
Block a user