UNPKG

bdtranslate

Version:
255 lines (241 loc) 6.59 kB
/** * 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;