url = $_ENV['LIBRETRANSLATE_URL'] ?? getenv('LIBRETRANSLATE_URL') ?? 'http://localhost:5000'; } public function detectLanguage(string $text): ?string { try { $response = $this->request('/detect', ['q' => $text]); if (!empty($response)) { return $response[0]['language'] ?? null; } } catch (\Exception $e) { error_log("Language detection error: " . $e->getMessage()); } return null; } public function translate(string $text, string $sourceLang, string $targetLang): ?string { if ($sourceLang === $targetLang) { return $text; } try { // Primero intentar obtener del caché $cacheKey = $this->generateCacheKey($text, $sourceLang, $targetLang); $cached = $this->getFromCache($cacheKey); if ($cached !== null) { error_log("Translation cache hit for: $sourceLang -> $targetLang"); return $cached; } $lines = explode("\n", $text); $translatedLines = []; foreach ($lines as $line) { if (trim($line) === '') { $translatedLines[] = ''; continue; } $response = $this->request('/translate', [ 'q' => trim($line), 'source' => $sourceLang, 'target' => $targetLang, 'format' => 'text' ]); $translatedLines[] = $response['translatedText'] ?? trim($line); } $result = implode("\n", $translatedLines); // Guardar en caché $this->saveToCache($cacheKey, $result); return $result; } catch (\Exception $e) { error_log("Translation error: " . $e->getMessage()); return null; } } public function translateToMultiple(string $text, string $sourceLang, array $targetLangs): array { $results = []; foreach ($targetLangs as $lang) { $results[$lang] = $this->translate($text, $sourceLang, $lang); } return $results; } public function getSupportedLanguages(): array { if (!empty($this->supportedLanguages)) { return $this->supportedLanguages; } try { $response = $this->request('/languages'); $this->supportedLanguages = $response; return $response; } catch (\Exception $e) { error_log("Get languages error: " . $e->getMessage()); return []; } } public function isLanguageSupported(string $langCode): bool { $languages = $this->getSupportedLanguages(); foreach ($languages as $lang) { if ($lang['code'] === $langCode) { return true; } } return false; } private function request(string $endpoint, array $data = []): array { $url = $this->url . $endpoint; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if (!empty($data)) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/x-www-form-urlencoded' ]); } $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode >= 400) { throw new \Exception("LibreTranslate API Error: HTTP $httpCode"); } $result = json_decode($response, true); if ($result === null) { throw new \Exception("Invalid JSON response from LibreTranslate"); } return $result; } /** * Genera una clave única para el caché de traducciones */ private function generateCacheKey(string $text, string $sourceLang, string $targetLang): string { return md5($text . $sourceLang . $targetLang); } /** * Obtiene una traducción del caché */ private function getFromCache(string $cacheKey): ?string { try { $cacheDir = sys_get_temp_dir() . '/discord_translation_cache'; if (!is_dir($cacheDir)) { mkdir($cacheDir, 0755, true); } $cacheFile = $cacheDir . '/' . $cacheKey . '.txt'; if (file_exists($cacheFile)) { // Verificar que el caché no sea muy antiguo (máximo 30 días) $fileAge = time() - filemtime($cacheFile); if ($fileAge < (30 * 24 * 60 * 60)) { $content = file_get_contents($cacheFile); if ($content !== false) { return $content; } } } } catch (\Exception $e) { error_log("Cache retrieval error: " . $e->getMessage()); } return null; } /** * Guarda una traducción en caché */ private function saveToCache(string $cacheKey, string $translation): void { try { $cacheDir = sys_get_temp_dir() . '/discord_translation_cache'; if (!is_dir($cacheDir)) { mkdir($cacheDir, 0755, true); } $cacheFile = $cacheDir . '/' . $cacheKey . '.txt'; file_put_contents($cacheFile, $translation, LOCK_EX); } catch (\Exception $e) { error_log("Cache save error: " . $e->getMessage()); } } }