bdtranslate
Version:
百度翻译免apikey工具
255 lines (241 loc) • 6.59 kB
JavaScript
/**
* User: lvxin
* Date: 2016/7/7
* Time: 22:36
*/
var fileUtil = require('lxfileutil')();
var request = require('request');
var cheerio = require("cheerio");
/**
* Class Translator
* @param config
* @returns {Translator}
* @constructor
*/
function Translator(config) {
if (!(this instanceof Translator)) {
return new Translator();
}
config = config || {};
this.header = config.headers || {
'Accept': '*/*',
'User-Agent': 'request',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Host': 'fanyi.baidu.com',
'Origin': 'http://fanyi.baidu.com',
'Referer': 'http://fanyi.baidu.com/?aldtype=16047',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
this.transOption = {
url: config.transUrl || 'http://fanyi.baidu.com/v2transapi',
method: "POST",
headers: this.header
}
this.lanOption = {
url: config.lanUrl || 'http://fanyi.baidu.com/langdetect',
method: "POST",
headers: this.header
}
this.domainUrl = "http://fanyi.baidu.com/";
this.splitRegExp = /([^]{1,4999})/ig;
this.maxLength = 4999;
}
/**
* 序列化参数
* @param json
*/
Translator.prototype.serialize = function (json) {
var key, ret = "";
for (key in json) {
ret = ret === "" ? key + "=" + json[key] : ret + "&" + key + "=" + json[key];
}
return ret;
}
/**
*语言检测接口
* @param word
* @param callback
*/
Translator.prototype.languageDet = function (word, callback) {
this.lanOption.body = this.serialize({query: word.slice(0, 40)});
request(this.lanOption, callback);
}
/**
* 获取支持的语言列表
* @param cb
*/
Translator.prototype.getLanguageCode = function (cb) {
var self = this;
var regExp = /(^[\s]*)|([\s]*$)/ig;
request(this.domainUrl, function (err, res, body) {
var $, ret = {};
if (err && self.isFunction(cb)) {
cb.call(null, err, null);
return;
}
$ = cheerio.load(body);
$(".from-language-list .language-list a").each(function (i, v) {
var _$v = $(v);
ret[_$v.attr("value")] = $(v).text().replace(regExp, "");
})
;
(self.isFunction(cb) && cb.call(null, null, ret));
})
}
/**
* ---
* @param f
* @returns {boolean}
*/
Translator.prototype.isFunction = function (f) {
return typeof f === "function";
}
/**
* 处理百度接口结果
* @param res
* @returns {*}
*/
Translator.prototype.handleResult = function (res) {
var ret = "";
if (res.trans_result && res.trans_result.data) {
res.trans_result.data.forEach(function (v, i) {
ret = ret === "" ? v.dst : ret + "\r\n" + v.dst;
})
return ret;
}
return false;
}
/**
* 自动翻译 自动检测语言,取前40个字符检测
* @param word
* @param callback
*/
Translator.prototype.autoTrans = function (word, toLan, callback) {
var self = this;
this.languageDet(word, function (err, res, body) {
var result;
if (err) {
(self.isFunction(callback) && callback.call(null, err, null));
} else {
result = JSON.parse(body);
if (result.msg === "success") {
if (result.lan === toLan) {
(self.isFunction(callback) && callback.call(null, null, word));
return;
}
self.translate(word, result.lan, toLan, callback);
} else {
(self.isFunction(callback) && callback.call(null, {success: false, msg: body, code: 500}, null));
}
}
})
}
/**
* 翻译
* @param word
* @param lan
* @param toLan
* @param callback
*/
Translator.prototype.translate = function (word, lan, toLan, callback) {
var self = this;
this.transOption.body = this.serialize({
from: lan,
to: toLan,
query: word,
transtype: word.length > 5 ? 'translang' : ''
})
request(this.transOption, function (err, res, body) {
var result;
if (err) {
throw new Error(err);
} else {
if (result = self.handleResult(JSON.parse(body))) {
(self.isFunction(callback) && callback.call(null, null, result));
} else {
(self.isFunction(callback) && callback.call(null, {success: false, msg: body, code: 500}, null));
}
}
})
}
/**
* 翻译 超长自动拆分
* @word
* @lan
* @toLan
* @callback
*/
Translator.prototype.translateText = function (word, lan, toLan, callback) {
var subText;
if (word.length > this.maxLength) {
subText = word.match(this.splitRegExp);
if (subText) {
this.transTask(subText, lan, toLan, callback)
} else {
(this.isFunction(callback) && callback.call(null, {success: false, msg: "match reg error"}, null));
}
return;
}
this.translate(word, lan, toLan, callback);
}
/**
* 检查结果队列
* @param rescache
* @param cb
*/
Translator.prototype.checkRes = function (rescache, cb) {
var ret = "", i, len;
if (rescache.every(function (v) {
return v.state !== "P" ? true : false
})) {
for (i = 0, len = rescache.length; i < len; i++) {
ret += rescache[i].state === "S" ? rescache[i].result : "[trans err]";
}
if (this.isFunction(cb)) {
cb.call(null, null, ret);
}
}
}
/**
* 异步翻译一个队列,并按顺序返回结果。
* @param lst
* @param lan
* @param toLan
* @param cb
*/
Translator.prototype.transTask = function (lst, lan, toLan, cb) {
var i, len, flag = [], self = this;
for (i = 0, len = lst.length; i < len; i++) {
flag.push({state: "P", result: "", index: i});
this.translateText(lst[i], lan, toLan, (function (_index) {
return function (err, result) {
if (err) {
flag[_index].state = "E";
return;
}
flag[_index].state = "S";
flag[_index].result = result;
self.checkRes(flag, cb);
}
})(i))
}
}
/**
* 翻译一个文件
* @param path
* @param lan
* @param toLan
* @param callback
*/
Translator.prototype.translateFile = function (path, lan, toLan, callback) {
var self = this;
fileUtil.readFile(path, {encoding: 'utf-8'}, function (err, buffer) {
if (err) {
(self.isFunction(callback) && callback.call(null, err, null));
return;
}
self.translateText(buffer.toString(), lan, toLan, callback);
})
}
module.exports = Translator;