您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Google Translate API Library for UserScripts
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/521561/1508824/Google%20Translate%20API%20Library.js
// ==UserScript== // @name Google Translate API Library // @namespace http://tampermonkey.net/ // @version 2024.12.24.2 // @description Google Translate API Library for UserScripts // @author Yuusei // @grant GM_xmlhttpRequest // @icon https://cdn-icons-png.flaticon.com/512/9502/9502737.png // ==/UserScript== const GoogleTranslateAPI = (function () { 'use strict'; const translationCache = new Map(); const CACHE_EXPIRY = 24 * 60 * 60 * 1000; const MAX_BATCH_SIZE = 128; const MAX_RETRIES = 3; const RETRY_DELAY = 1000; const languages = { auto: 'Automatic', af: 'Afrikaans', sq: 'Albanian', am: 'Amharic', ar: 'Arabic', hy: 'Armenian', az: 'Azerbaijani', eu: 'Basque', be: 'Belarusian', bn: 'Bengali', bs: 'Bosnian', bg: 'Bulgarian', ca: 'Catalan', ceb: 'Cebuano', ny: 'Chichewa', 'zh-cn': 'Chinese Simplified', 'zh-tw': 'Chinese Traditional', co: 'Corsican', hr: 'Croatian', cs: 'Czech', da: 'Danish', nl: 'Dutch', en: 'English', eo: 'Esperanto', et: 'Estonian', tl: 'Filipino', fi: 'Finnish', fr: 'French', fy: 'Frisian', gl: 'Galician', ka: 'Georgian', de: 'German', el: 'Greek', gu: 'Gujarati', ht: 'Haitian Creole', ha: 'Hausa', haw: 'Hawaiian', iw: 'Hebrew', hi: 'Hindi', hmn: 'Hmong', hu: 'Hungarian', is: 'Icelandic', ig: 'Igbo', id: 'Indonesian', ga: 'Irish', it: 'Italian', ja: 'Japanese', jw: 'Javanese', kn: 'Kannada', kk: 'Kazakh', km: 'Khmer', ko: 'Korean', ku: 'Kurdish (Kurmanji)', ky: 'Kyrgyz', lo: 'Lao', la: 'Latin', lv: 'Latvian', lt: 'Lithuanian', lb: 'Luxembourgish', mk: 'Macedonian', mg: 'Malagasy', ms: 'Malay', ml: 'Malayalam', mt: 'Maltese', mi: 'Maori', mr: 'Marathi', mn: 'Mongolian', my: 'Myanmar (Burmese)', ne: 'Nepali', no: 'Norwegian', ps: 'Pashto', fa: 'Persian', pl: 'Polish', pt: 'Portuguese', pa: 'Punjabi', ro: 'Romanian', ru: 'Russian', sm: 'Samoan', gd: 'Scots Gaelic', sr: 'Serbian', st: 'Sesotho', sn: 'Shona', sd: 'Sindhi', si: 'Sinhala', sk: 'Slovak', sl: 'Slovenian', so: 'Somali', es: 'Spanish', su: 'Sundanese', sw: 'Swahili', sv: 'Swedish', tg: 'Tajik', ta: 'Tamil', te: 'Telugu', th: 'Thai', tr: 'Turkish', uk: 'Ukrainian', ur: 'Urdu', uz: 'Uzbek', vi: 'Vietnamese', cy: 'Welsh', xh: 'Xhosa', yi: 'Yiddish', yo: 'Yoruba', zu: 'Zulu', }; function validateLanguage(language) { if (!language) { throw new Error('Language cannot be empty'); } const isoCode = getISOCode(language); if (!isoCode) { throw new Error(`Language not supported: ${language}`); } return isoCode; } function getISOCode(language) { if (!language) return false; language = language.toLowerCase(); if (language in languages) return language; let keys = Object.keys(languages).filter(key => { if (typeof languages[key] !== 'string') return false; return languages[key].toLowerCase() === language; }); return keys[0] || false; } function isSupported(language) { return Boolean(getISOCode(language)); } function getCacheKey(text, options) { return `${text}|${options.from}|${options.to}`; } function getFromCache(text, options) { const key = getCacheKey(text, options); const cached = translationCache.get(key); if (cached && Date.now() - cached.timestamp < CACHE_EXPIRY) { return cached.result; } return null; } function saveToCache(text, options, result) { const key = getCacheKey(text, options); translationCache.set(key, { result, timestamp: Date.now(), }); } async function translate(text, options = {}) { if (!text) throw new Error('Text cannot be empty'); options.from = options.from || 'auto'; options.to = options.to || 'en'; options.from = validateLanguage(options.from); options.to = validateLanguage(options.to); const cached = getFromCache(text, options); if (cached) return cached; let baseUrl = 'https://translate.googleapis.com/translate_a/single'; let data = { client: 'gtx', sl: options.from, tl: options.to, dt: 't', q: text, }; let url = `${baseUrl}?` + new URLSearchParams(data).toString(); return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: url, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', Accept: '*/*', }, timeout: 10000, onload: function (response) { try { if (response.status !== 200) { throw new Error(`HTTP Error: ${response.status}`); } const body = JSON.parse(response.responseText); if (!body || !Array.isArray(body) || !body[0]) { throw new Error('Invalid response structure'); } let result = { text: '', from: { language: { didYouMean: false, iso: body[2] || options.from, }, text: { autoCorrected: false, value: '', didYouMean: false, }, }, raw: body, }; result.text = body[0] .filter(chunk => chunk && chunk[0]) .map(chunk => decodeURIComponent(chunk[0].trim())) .join(' ') .trim(); saveToCache(text, options, result); resolve(result); } catch (error) { reject(new Error('Error processing response: ' + error.message)); } }, onerror: function (error) { reject(new Error('Connection error: ' + error)); }, ontimeout: function () { reject(new Error('Timeout: Request took too long')); }, }); }); } async function translateWithRetry(text, options = {}, maxRetries = MAX_RETRIES, delay = RETRY_DELAY) { let lastError; for (let i = 0; i < maxRetries; i++) { try { return await translate(text, options); } catch (error) { lastError = error; console.log(`Try ${i + 1}/${maxRetries} failed:`, error); if (i < maxRetries - 1) { await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, i))); } } } throw new Error(`Translation failed after ${maxRetries} attempts: ${lastError.message}`); } async function translateBatch(texts, options = {}) { if (!Array.isArray(texts)) { throw new Error('Texts must be an array'); } const results = []; const chunks = []; // Chia nhỏ mảng texts thành các chunks có kích thước MAX_BATCH_SIZE for (let i = 0; i < texts.length; i += MAX_BATCH_SIZE) { chunks.push(texts.slice(i, i + MAX_BATCH_SIZE)); } // Dịch từng chunk for (const chunk of chunks) { const chunkResults = await Promise.all( chunk.map(text => translateWithRetry(text, options).catch(error => ({ error }))) ); results.push(...chunkResults); } return results; } function clearExpiredCache() { const now = Date.now(); for (const [key, value] of translationCache.entries()) { if (now - value.timestamp > CACHE_EXPIRY) { translationCache.delete(key); } } } setInterval(clearExpiredCache, 60 * 60 * 1000); return { translate, translateWithRetry, translateBatch, languages, getISOCode, isSupported, clearExpiredCache, }; })(); if (typeof module !== 'undefined' && module.exports) { module.exports = GoogleTranslateAPI; }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址