Файловый менеджер - Редактировать - /home/gqdcvggs/go.imators.com/deepl-translator.js.tar
Назад
home/gqdcvggs/imators.com/deepl-translator.js 0000644 00000026364 15114742023 0015364 0 ustar 00 const fs = require('fs').promises; const path = require('path'); const axios = require('axios'); const readline = require('readline'); const cliProgress = require('cli-progress'); const CONFIG = { DEEPL_API_KEY: '34f2c2d3-aa64-49bc-6e8e-eb4fdb428f0b:fx', INPUT_DIR: './fr', OUTPUT_DIR: './ar', EXCLUDED_FILES: [ 'config.php', 'database.php', 'functions.php', ], EXCLUDED_DIRECTORIES: [ 'vendor', 'node_modules', 'assets', '.well-know', 'link', 'fr', ], EXCLUDED_TERMS: [ '©', 'Academ', '©', 'Imators', ], TRANSLATION_MAPPINGS: { 'Academ': 'Academ', 'Something': 'Something', 'Imateurs': 'Imators', } }; class TranslationStats { constructor() { this.totalFiles = 0; this.processedFiles = 0; this.totalStrings = 0; this.translatedStrings = 0; this.errorCount = 0; this.startTime = Date.now(); this.characterCount = 0; this.skippedFiles = 0; } printSummary() { const duration = ((Date.now() - this.startTime) / 1000).toFixed(2); console.log('\n==========================================='); console.log(' Translation Summary by Imators Systems '); console.log('==========================================='); console.log(`Files Processed : ${this.processedFiles}/${this.totalFiles}`); console.log(`Files Skipped : ${this.skippedFiles}`); console.log(`Strings Translated : ${this.translatedStrings}/${this.totalStrings}`); console.log(`Characters Count : ${this.characterCount}`); console.log(`Errors Encountered : ${this.errorCount}`); console.log(`Total Duration : ${duration} seconds`); console.log('===========================================\n'); } } class DeepLTranslator { constructor(apiKey) { this.apiKey = apiKey; this.baseURL = 'https://api-free.deepl.com/v2/translate'; this.requestDelay = 1000; } async sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async translateText(text, stats) { for (const term of CONFIG.EXCLUDED_TERMS) { if (text.includes(term)) { return text; } } for (const [original, translation] of Object.entries(CONFIG.TRANSLATION_MAPPINGS)) { if (text.includes(original)) { return text.replace(original, translation); } } try { await this.sleep(this.requestDelay); stats.characterCount += text.length; console.log(`\n→ Translation request for: "${text}"`); const response = await axios.post(this.baseURL, new URLSearchParams({ text: text, source_lang: 'FR', target_lang: 'AR', }), { headers: { 'Authorization': `DeepL-Auth-Key ${this.apiKey}`, 'Content-Type': 'application/x-www-form-urlencoded', } } ); let translation = response.data.translations[0].text; CONFIG.EXCLUDED_TERMS.forEach(term => { const regex = new RegExp(term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi'); translation = translation.replace(regex, term); }); console.log(`✓ Translated to: "${translation}"`); return translation; } catch (error) { if (error.response?.status === 429) { console.log('\n! Rate limit reached. Pausing for 60 seconds...'); await this.sleep(60000); return this.translateText(text, stats); } console.error('Translation error:', error.message); throw error; } } } async function extractTranslatableStrings(content) { const matches = new Set(); const dom = content.toString(); const patterns = [ {pattern: />([^<>]+)</g, group: 1}, {pattern: /<h[1-6][^>]*>(.*?)<\/h[1-6]>/g, group: 1}, {pattern: /<p[^>]*>(.*?)<\/p>/g, group: 1}, {pattern: /<li[^>]*>(.*?)<\/li>/g, group: 1}, {pattern: /<span[^>]*>(.*?)<\/span>/g, group: 1}, {pattern: /<div[^>]*>(.*?)<\/div>/g, group: 1}, {pattern: /title="([^"]+)"/g, group: 1}, {pattern: /alt="([^"]+)"/g, group: 1}, {pattern: /placeholder="([^"]+)"/g, group: 1}, {pattern: /aria-label="([^"]+)"/g, group: 1}, {pattern: /data-text="([^"]+)"/g, group: 1}, {pattern: /value="([^"]+)"/g, group: 1}, {pattern: /content="([^"]+)"/g, group: 1} ]; patterns.forEach(({pattern, group}) => { let match; while ((match = pattern.exec(dom)) !== null) { let text = match[group].trim(); if (isValidText(text)) { // Exclure les styles et les scripts if (!isStyleOrScript(text)) { // Exclure les attributs class text = removeClassAttributes(text); matches.add(text); } } } }); const results = Array.from(matches).filter(text => !shouldExcludeText(text)); results.forEach(text => console.log(`• "${text}"`)); return results; } function isValidText(text) { return text && text.length > 1 && /[a-zA-ZÀ-ÿ]/.test(text) && !text.includes('<?') && !text.includes('?>') && !text.match(/^[0-9\s\W]+$/); } function shouldExcludeText(text) { return text.includes('function') || text.includes('class=') || text.includes('style=') || text.includes('src=') || text.includes('href=') || text.startsWith('{') || text.startsWith('//') || text.startsWith('/*') || text.startsWith('console.') || CONFIG.EXCLUDED_TERMS.some(term => text === term); } function isStyleOrScript(text) { return /<style(\s|\S)*?<\/style>/gi.test(text) || /<script(\s|\S)*?<\/script>/gi.test(text); } function removeClassAttributes(text) { return text.replace(/\sclass="[^"]*"/gi, ''); } async function shouldProcessFile(filePath) { const relativePath = path.relative(CONFIG.INPUT_DIR, filePath); const fileName = path.basename(filePath); if (CONFIG.EXCLUDED_DIRECTORIES.some(dir => relativePath.startsWith(dir))) { console.log(`Skipping excluded directory: ${relativePath}`); return false; } if (CONFIG.EXCLUDED_FILES.includes(fileName)) { console.log(`Skipping excluded file: ${fileName}`); return false; } return true; } async function scanDirectory(dir) { try { const items = await fs.readdir(dir, { withFileTypes: true }); let files = []; for (const item of items) { const fullPath = path.join(dir, item.name); if (item.isDirectory()) { files = files.concat(await scanDirectory(fullPath)); } else if (path.extname(item.name) === '.php' && await shouldProcessFile(fullPath)) { files.push(fullPath); } } return files; } catch (error) { console.error('Directory scan error:', error.message); throw error; } } async function askForConfirmation(question) { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); return new Promise(resolve => { rl.question(`${question} (y/n): `, answer => { rl.close(); resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes'); }); }); } async function translatePhpFile(translator, filePath, outputDir, stats) { try { const relativePath = path.relative('./', filePath); const outputPath = path.join(outputDir, relativePath); const outputDirFull = path.dirname(outputPath); console.log(`\n[Processing] ${relativePath}`); const content = await fs.readFile(filePath, 'utf8'); const stringsToTranslate = await extractTranslatableStrings(content); stats.totalStrings += stringsToTranslate.length; if (stringsToTranslate.length === 0) { console.log(' • No translatable content found'); return; } console.log(` • Found ${stringsToTranslate.length} translatable items`); let translatedContent = content; for (const text of stringsToTranslate) { const translation = await translator.translateText(text, stats); const escapedText = text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); translatedContent = translatedContent.replace( new RegExp(`(>|title="|alt="|placeholder="|aria-label="|data-text="|value="|content=")${escapedText}(?=<|")`, 'g'), `$1${translation}` ); stats.translatedStrings++; } await fs.mkdir(outputDirFull, { recursive: true }); await fs.writeFile(outputPath, translatedContent); stats.processedFiles++; console.log(`✓ Saved translation to: ${outputPath}`); } catch (error) { console.error(`! Error processing ${filePath}:`, error.message); stats.errorCount++; } } async function translateDirectory(apiKey, inputDir, outputDir) { const stats = new TranslationStats(); try { console.log('\n==========================================='); console.log(' Translation | By Imators Systems '); console.log('===========================================\n'); console.log('Scanning directory for PHP files...'); const phpFiles = await scanDirectory(inputDir); stats.totalFiles = phpFiles.length; console.log(`\nFound ${phpFiles.length} PHP files:`); phpFiles.forEach(file => console.log(` • ${path.relative('./', file)}`) ); // Afficher le tableau détaillé avant le lancement console.log('\nTranslation Details:'); console.log(' • Source Directory:', CONFIG.INPUT_DIR); console.log(' • Target Directory:', CONFIG.OUTPUT_DIR); console.log(' • Files to Translate:', stats.totalFiles); if (phpFiles.length === 0) { console.log('\n! No PHP files found.'); return; } const confirmed = await askForConfirmation('\nProceed with translation?'); if (!confirmed) { console.log('\n! Operation cancelled'); return; } console.log('\nInitiating translation process...'); const translator = new DeepLTranslator(apiKey); // Initialiser la barre de progression const progressBar = new cliProgress.SingleBar( {}, cliProgress.Presets.shades_classic ); progressBar.start(phpFiles.length, 0); for (const file of phpFiles) { await translatePhpFile(translator, file, outputDir, stats); progressBar.increment(); } progressBar.stop(); stats.printSummary(); console.log('✓ Translation process completed successfully!\n'); } catch (error) { console.error('\n! Critical error:', error.message); stats.printSummary(); } } translateDirectory(CONFIG.DEEPL_API_KEY, CONFIG.INPUT_DIR, CONFIG.OUTPUT_DIR);
| ver. 1.6 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка