Last active
October 10, 2022 02:32
-
-
Save pk49800/4ae8df583b35f5d63043cd3388e9831d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global api, hash */ | |
class enen_Oxford { | |
constructor(options) { | |
this.token = ''; | |
this.gtk = ''; | |
this.options = options; | |
this.maxexample = 2; | |
this.word = ''; | |
} | |
async displayName() { | |
let locale = await api.locale(); | |
if (locale.indexOf('CN') != -1) return '牛津英英'; | |
if (locale.indexOf('TW') != -1) return '牛津英英'; | |
return 'Oxford EN->EN Dictionary'; | |
} | |
setOptions(options) { | |
this.options = options; | |
this.maxexample = options.maxexample; | |
} | |
async getToken() { | |
let homeurl = 'https://fanyi.baidu.com/'; | |
let homepage = await api.fetch(homeurl); | |
let tmatch = /token: ['"](.+?)['"]/gi.exec(homepage); | |
if (!tmatch || tmatch.length < 2) return null; | |
let gmatch = /window.gtk = ['"](.+?)['"]/gi.exec(homepage); | |
if (!gmatch || gmatch.length < 2) return null; | |
return { | |
'token': tmatch[1], | |
'gtk': gmatch[1] | |
}; | |
} | |
async findTerm(word) { | |
this.word = word; | |
let deflection = await api.deinflect(word) || []; | |
let promises = [word, deflection].map(x => this.findOxford(x)); | |
let results = await Promise.all(promises); | |
return [].concat(...results).filter(x => x); | |
} | |
async findOxford(word) { | |
// helper function | |
function buildDefinitionBlock(exp, pos, defs) { | |
if (!defs || !Array.isArray(defs) || defs.length < 0) return ''; | |
let definition = ''; | |
let sentence = ''; | |
let sentnum = 0; | |
for (const def of defs) { | |
if (def.text) definition += `<span class='tran'><span class='eng_tran'>${def.text}</span></span>`; | |
if (def.tag == 'id' || def.tag == 'pv') | |
definition += def.enText ? `<div class="idmphrase">${def.enText}</div>` : ''; | |
//if (def.tag == 'xrs') | |
// definition += `<span class='tran'><span class='eng_tran'>${def.data[0].data[0].text}</span></span>`; | |
if (def.tag == 'd' || def.tag == 'ud') | |
definition += pos + `<span class='tran'><span class='eng_tran'>${def.enText}</span></span>`; | |
if (def.tag == 'x' && sentnum < maxexample) { | |
sentnum += 1; | |
let enText = def.enText.replace(RegExp(exp, 'gi'), `<b>${exp}</b>`); | |
sentence += `<li class='sent'><span class='eng_sent'>${enText}</span></li>`; | |
} | |
} | |
definition += sentence ? `<ul class="sents">${sentence}</ul>` : ''; | |
return definition; | |
} | |
const maxexample = this.maxexample; | |
let notes = []; | |
if (!word) return notes; | |
let base = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh&simple_means_flag=3'; | |
if (!this.token || !this.gtk) { | |
let common = await this.getToken(); | |
if (!common) return []; | |
this.token = common.token; | |
this.gtk = common.gtk; | |
} | |
let sign = hash(word, this.gtk); | |
if (!sign) return; | |
let dicturl = base + `&query=${word}&sign=${sign}&token=${this.token}`; | |
let data = ''; | |
try { | |
data = JSON.parse(await api.fetch(dicturl)); | |
let oxford = getOxford(data); | |
let bdsimple = oxford.length ? [] : getBDSimple(data); //Combine Youdao Concise English-Chinese Dictionary to the end. | |
let bstrans = oxford.length || bdsimple.length ? [] : getBDTrans(data); //Combine Youdao Translation (if any) to the end. | |
return [].concat(oxford, bdsimple, bstrans); | |
} catch (err) { | |
return []; | |
} | |
function getBDTrans(data) { | |
try { | |
if (data.dict_result && data.dict_result.length != 0) return []; | |
if (!data.trans_result || data.trans_result.data.length < 1) return []; | |
let css = '<style>.odh-expression {font-size: 1em!important;font-weight: normal!important;}</style>'; | |
let expression = data.trans_result.data[0].src; | |
let definition = data.trans_result.data[0].dst; | |
return [{ css, expression, definitions: [definition] }]; | |
} catch (error) { | |
return []; | |
} | |
} | |
function getBDSimple(data) { | |
try { | |
let simple = data.dict_result.simple_means; | |
let expression = simple.word_name; | |
if (!expression) return []; | |
let symbols = simple.symbols[0]; | |
//let reading_uk = symbols.ph_en || ''; | |
//let reading_us = symbols.ph_am || ''; | |
//let reading = reading_uk && reading_us ? `uk[${reading_uk}] us[${reading_us}]` : ''; | |
let reading = '/ ' + symbols.ph_en + ' /'|| ''; | |
let audios = []; | |
audios[0] = `https://fanyi.baidu.com/gettts?lan=uk&text=${encodeURIComponent(expression)}&spd=3&source=web`; | |
audios[1] = `https://fanyi.baidu.com/gettts?lan=en&text=${encodeURIComponent(expression)}&spd=3&source=web`; | |
if (!symbols.parts || symbols.parts.length < 1) return []; | |
let definition = '<ul class="ec">'; | |
for (const def of symbols.parts) | |
if (def.means && def.means.length > 0) { | |
let pos = def.part || def.part_name || ''; | |
pos = pos ? `<span class="pos simple">${pos}</span>` : ''; | |
definition += `<li class="ec">${pos}<span class="ec_chn">${def.means.join()}</span></li>`; | |
} | |
definition += '</ul>'; | |
let css = `<style> | |
ul.ec, li.ec {margin:0; padding:0;} | |
span.simple {background-color: #999!important} | |
span.pos {text-transform:lowercase; font-size:0.9em; margin-right:5px; padding:2px 4px; color:white; background-color:#0d47a1; border-radius:3px;} | |
</style>`; | |
notes.push({ css, expression, reading, extrainfo, definitions: [definition], audios }); | |
return notes; | |
} catch (error) { | |
return []; | |
} | |
} | |
function getOxford(data) { | |
try { | |
let simple = data.dict_result.simple_means; | |
let expression = simple.word_name; | |
if (!expression) return []; | |
let symbols = simple.symbols[0]; | |
// let reading_uk = symbols.ph_en || ''; | |
// let reading_us = symbols.ph_am || ''; | |
// let reading = reading_uk && reading_us ? `uk[${reading_uk}] us[${reading_us}]` : ''; | |
let reading = '/ ' + symbols.ph_en + ' /' || ''; | |
let audios = []; | |
audios[0] = `https://fanyi.baidu.com/gettts?lan=uk&text=${encodeURIComponent(expression)}&spd=3&source=web`; | |
audios[1] = `https://fanyi.baidu.com/gettts?lan=en&text=${encodeURIComponent(expression)}&spd=3&source=web`; | |
let entries = data.dict_result.oxford.entry[0].data; | |
if (!entries) return []; | |
let definitions = []; | |
for (const entry of entries) { | |
if (entry.tag == 'p-g' || entry.tag == 'h-g') { | |
let pos = ''; | |
for (const group of entry.data) { | |
let definition = ''; | |
if (group.tag == 'p') { | |
pos = `<span class='pos'>${group.p_text}</span>`; | |
} | |
if (group.tag == 'd') { | |
definition += pos + `<span class='tran'><span class='eng_tran'>${group.enText}</span></span>`; | |
definitions.push(definition); | |
} | |
if (group.tag == 'n-g') { | |
definition += buildDefinitionBlock(expression, pos, group.data); | |
definitions.push(definition); | |
} | |
//if (group.tag == 'xrs') { | |
// definition += buildDefinitionBlock(pos, group.data[0].data); | |
// definitions.push(definition); | |
//} | |
if (group.tag == 'sd-g' || group.tag == 'ids-g' || group.tag == 'pvs-g') { | |
for (const item of group.data) { | |
if (item.tag == 'sd') definition = `<div class="dis"><span class="eng_dis">${item.enText}</span></div>` + definition; | |
let defs = []; | |
if (item.tag == 'n-g' || item.tag == 'id-g' || item.tag == 'pv-g') defs = item.data; | |
if (item.tag == 'vrs' || item.tag == 'xrs') defs = item.data[0].data; | |
definition += buildDefinitionBlock(expression, pos, defs); | |
} | |
definitions.push(definition); | |
} | |
} | |
} | |
} | |
let css = enen_Oxford.renderCSS(); | |
notes.push({ css, expression, reading, definitions, audios }); | |
return notes; | |
} catch (error) { | |
return []; | |
} | |
} | |
} | |
static renderCSS() { | |
let css = ` | |
<style> | |
div.dis {font-weight: bold;margin-bottom:3px;padding:0;} | |
span.grammar, | |
span.informal {margin: 0 2px;color: #0d47a1;} | |
span.complement {margin: 0 2px;font-weight: bold;} | |
div.idmphrase {font-weight: bold;margin: 0;padding: 0;} | |
span.eng_dis {margin-right: 5px;} | |
span.chn_dis {margin: 0;padding: 0;} | |
span.pos {text-transform:lowercase; font-size:0.9em; margin-right:5px; padding:2px 4px; color:white; background-color:#0d47a1; border-radius:3px;} | |
span.tran {margin:0; padding:0;} | |
span.eng_tran {margin-right:3px; padding:0;} | |
span.chn_tran {color:#0d47a1;} | |
ul.sents {font-size:0.9em; list-style:square inside; margin:3px 0;padding:5px;background:rgba(13,71,161,0.1); border-radius:5px;} | |
li.sent {margin:0; padding:0;} | |
span.eng_sent {margin-right:5px;} | |
span.chn_sent {color:#0d47a1;} | |
</style>`; | |
return css; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment