-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
115 lines (98 loc) · 3.88 KB
/
Copy pathindex.js
File metadata and controls
115 lines (98 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const puppeteer = require('puppeteer');
async function translate(...args) {
let detect = 'auto', text, target;
// Check argument format
if (args.length === 1 && typeof args[0] === 'object') {
({ detect = 'auto', text, target } = args[0]);
} else if (args.length === 2) {
[text, target] = args;
detect = 'auto'; // Default detect to 'auto' for two arguments
} else if (args.length === 3) {
[detect, text, target] = args;
} else {
throw new Error('Invalid arguments: Provide { detect, text, target }, (detect, text, target), or (text, target)');
}
if (!text || !target) {
throw new Error('Text and target language are required');
}
const encodedText = encodeURIComponent(text);
let result = { detect: 'success', translated_text: '' };
let url = `https://translate.google.com/?sl=${encodeURIComponent(detect)}&tl=${encodeURIComponent(target)}&text=${encodedText}&op=translate`;
const browser = await puppeteer.launch({ headless: 'new' });
try {
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });
// Get detected source language
let detectedLanguage = '';
try {
detectedLanguage = await page.$eval('[data-language-code][aria-selected="true"]', el => el.getAttribute('data-language-code') || 'auto');
} catch (err) {
detectedLanguage = 'unknown';
}
const selectors = [
'span.ryNqvb',
'span[jsname="V67aGc"].VfPpkd-vQzf8d',
'div.HwtZe span',
'span[class*="translation"]'
];
let translatedText = null;
for (const selector of selectors) {
try {
await page.waitForSelector(selector, { timeout: 10000 });
const texts = await page.$$eval(selector, els => els.map(el => el.textContent.trim()).filter(text => text && text !== 'Test'));
if (texts.length > 0) {
translatedText = texts.join(' ');
break;
}
} catch (err) {
// Silently continue to next selector
}
}
// Check if provided detect language matches and translation is valid
if (detect !== 'auto' && detectedLanguage !== detect) {
result.detect = 'fail';
url = `https://translate.google.com/?sl=auto&tl=${encodeURIComponent(target)}&text=${encodedText}&op=translate`;
await page.goto(url, { waitUntil: 'networkidle2' });
translatedText = null;
for (const selector of selectors) {
try {
await page.waitForSelector(selector, { timeout: 10000 });
const texts = await page.$$eval(selector, els => els.map(el => el.textContent.trim()).filter(text => text && text !== 'Test'));
if (texts.length > 0) {
translatedText = texts.join(' ');
break;
}
} catch (err) {
// Silently continue to next selector
}
}
} else if (!translatedText || translatedText === text && detect !== target) {
result.detect = 'fail';
url = `https://translate.google.com/?sl=auto&tl=${encodeURIComponent(target)}&text=${encodedText}&op=translate`;
await page.goto(url, { waitUntil: 'networkidle2' });
translatedText = null;
for (const selector of selectors) {
try {
await page.waitForSelector(selector, { timeout: 10000 });
const texts = await page.$$eval(selector, els => els.map(el => el.textContent.trim()).filter(text => text && text !== 'Test'));
if (texts.length > 0) {
translatedText = texts.join(' ');
break;
}
} catch (err) {
// Silently continue to next selector
}
}
}
if (!translatedText || translatedText === 'Test') {
throw new Error(`Translation not found. Tried selectors: ${selectors.join(', ')}`);
}
result.translated_text = translatedText;
return result;
} catch (error) {
throw error;
} finally {
await browser.close();
}
}
module.exports = translate;