From 21d194d14510abb149d22c8cbd56570cd6b62266 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 7 Mar 2020 14:25:25 -0500 Subject: Make _audioInject internal to Backend --- ext/bg/js/audio.js | 44 -------------------------------------------- ext/bg/js/backend.js | 47 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 48 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/audio.js b/ext/bg/js/audio.js index c94121ae..361a19cc 100644 --- a/ext/bg/js/audio.js +++ b/ext/bg/js/audio.js @@ -138,47 +138,3 @@ function audioUrlNormalize(url, baseUrl, basePath) { } return url; } - -function audioBuildFilename(definition) { - if (definition.reading || definition.expression) { - let filename = 'yomichan'; - if (definition.reading) { - filename += `_${definition.reading}`; - } - if (definition.expression) { - filename += `_${definition.expression}`; - } - - return filename += '.mp3'; - } - return null; -} - -async function audioInject(definition, fields, sources, optionsContext, audioSystem) { - let usesAudio = false; - for (const fieldValue of Object.values(fields)) { - if (fieldValue.includes('{audio}')) { - usesAudio = true; - break; - } - } - - if (!usesAudio) { - return true; - } - - try { - const expressions = definition.expressions; - const audioSourceDefinition = Array.isArray(expressions) ? expressions[0] : definition; - - const {uri} = await audioSystem.getDefinitionAudio(audioSourceDefinition, sources, {tts: false, optionsContext}); - const filename = audioBuildFilename(audioSourceDefinition); - if (filename !== null) { - definition.audio = {url: uri, filename}; - } - - return true; - } catch (e) { - return false; - } -} diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 6e5235ed..1fdc4c70 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -21,7 +21,7 @@ conditionsTestValue, profileConditionsDescriptor handlebarsRenderDynamic requestText, requestJson, optionsLoad dictConfigured, dictTermsSort, dictEnabledSet -audioGetUrl, audioInject +audioGetUrl jpConvertReading, jpDistributeFuriganaInflected, jpKatakanaToHiragana AnkiNoteBuilder, AudioSystem, Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema, ClipboardMonitor*/ @@ -434,12 +434,11 @@ class Backend { const templates = this.defaultAnkiFieldTemplates; if (mode !== 'kanji') { - await audioInject( + await this._audioInject( definition, options.anki.terms.fields, options.audio.sources, - optionsContext, - this.audioSystem + optionsContext ); } @@ -775,6 +774,35 @@ class Backend { return await audioGetUrl(definition, source, options); } + async _audioInject(definition, fields, sources, optionsContext) { + let usesAudio = false; + for (const fieldValue of Object.values(fields)) { + if (fieldValue.includes('{audio}')) { + usesAudio = true; + break; + } + } + + if (!usesAudio) { + return true; + } + + try { + const expressions = definition.expressions; + const audioSourceDefinition = Array.isArray(expressions) ? expressions[0] : definition; + + const {uri} = await this.audioSystem.getDefinitionAudio(audioSourceDefinition, sources, {tts: false, optionsContext}); + const filename = this._createInjectedAudioFileName(audioSourceDefinition); + if (filename !== null) { + definition.audio = {url: uri, filename}; + } + + return true; + } catch (e) { + return false; + } + } + async _injectScreenshot(definition, fields, screenshot) { let usesScreenshot = false; for (const fieldValue of Object.values(fields)) { @@ -815,6 +843,17 @@ class Backend { return handlebarsRenderDynamic(template, data); } + _createInjectedAudioFileName(definition) { + const {reading, expression} = definition; + if (!reading && !expression) { return null; } + + let filename = 'yomichan'; + if (reading) { filename += `_${reading}`; } + if (expression) { filename += `_${expression}`; } + filename += '.mp3'; + return filename; + } + static _getTabUrl(tab) { return new Promise((resolve) => { chrome.tabs.sendMessage(tab.id, {action: 'getUrl'}, {frameId: 0}, (response) => { -- cgit v1.2.3 From 391f3dd29af2017b540b38e67a06242af85268ba Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 7 Mar 2020 14:36:16 -0500 Subject: Update how audio URIs are built --- ext/bg/js/audio.js | 104 +++++++++++++++++++++++++++++---------------------- ext/bg/js/backend.js | 8 ++-- 2 files changed, 64 insertions(+), 48 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/audio.js b/ext/bg/js/audio.js index 361a19cc..80e9cb9a 100644 --- a/ext/bg/js/audio.js +++ b/ext/bg/js/audio.js @@ -18,8 +18,49 @@ /*global jpIsStringEntirelyKana*/ -const audioUrlBuilders = new Map([ - ['jpod101', async (definition) => { +class AudioUriBuilder { + constructor() { + this._getUrlHandlers = new Map([ + ['jpod101', this._getUriJpod101.bind(this)], + ['jpod101-alternate', this._getUriJpod101Alternate.bind(this)], + ['jisho', this._getUriJisho.bind(this)], + ['text-to-speech', this._getUriTextToSpeech.bind(this)], + ['text-to-speech-reading', this._getUriTextToSpeechReading.bind(this)], + ['custom', this._getUriCustom.bind(this)] + ]); + } + + normalizeUrl(url, baseUrl, basePath) { + if (url) { + if (url[0] === '/') { + if (url.length >= 2 && url[1] === '/') { + // Begins with "//" + url = baseUrl.substring(0, baseUrl.indexOf(':') + 1) + url; + } else { + // Begins with "/" + url = baseUrl + url; + } + } else if (!/^[a-z][a-z0-9\-+.]*:/i.test(url)) { + // No URI scheme => relative path + url = baseUrl + basePath + url; + } + } + return url; + } + + async getUri(mode, definition, options) { + const handler = this._getUrlHandlers.get(mode); + if (typeof handler === 'function') { + try { + return await handler(definition, options); + } catch (e) { + // NOP + } + } + return null; + } + + async _getUriJpod101(definition) { let kana = definition.reading; let kanji = definition.expression; @@ -37,8 +78,9 @@ const audioUrlBuilders = new Map([ } return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`; - }], - ['jpod101-alternate', async (definition) => { + } + + async _getUriJpod101Alternate(definition) { const response = await new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('POST', 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'); @@ -54,7 +96,7 @@ const audioUrlBuilders = new Map([ const url = row.querySelector('audio>source[src]').getAttribute('src'); const reading = row.getElementsByClassName('dc-vocab_kana').item(0).textContent; if (url && reading && (!definition.reading || definition.reading === reading)) { - return audioUrlNormalize(url, 'https://www.japanesepod101.com', '/learningcenter/reference/'); + return this.normalizeUrl(url, 'https://www.japanesepod101.com', '/learningcenter/reference/'); } } catch (e) { // NOP @@ -62,8 +104,9 @@ const audioUrlBuilders = new Map([ } throw new Error('Failed to find audio URL'); - }], - ['jisho', async (definition) => { + } + + async _getUriJisho(definition) { const response = await new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', `https://jisho.org/search/${definition.expression}`); @@ -78,7 +121,7 @@ const audioUrlBuilders = new Map([ if (audio !== null) { const url = audio.getElementsByTagName('source').item(0).getAttribute('src'); if (url) { - return audioUrlNormalize(url, 'https://jisho.org', '/search/'); + return this.normalizeUrl(url, 'https://jisho.org', '/search/'); } } } catch (e) { @@ -86,55 +129,28 @@ const audioUrlBuilders = new Map([ } throw new Error('Failed to find audio URL'); - }], - ['text-to-speech', async (definition, options) => { + } + + async _getUriTextToSpeech(definition, options) { const voiceURI = options.audio.textToSpeechVoice; if (!voiceURI) { throw new Error('No voice'); } return `tts:?text=${encodeURIComponent(definition.expression)}&voice=${encodeURIComponent(voiceURI)}`; - }], - ['text-to-speech-reading', async (definition, options) => { + } + + async _getUriTextToSpeechReading(definition, options) { const voiceURI = options.audio.textToSpeechVoice; if (!voiceURI) { throw new Error('No voice'); } return `tts:?text=${encodeURIComponent(definition.reading || definition.expression)}&voice=${encodeURIComponent(voiceURI)}`; - }], - ['custom', async (definition, options) => { - const customSourceUrl = options.audio.customSourceUrl; - return customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (hasOwn(definition, m1) ? `${definition[m1]}` : m0)); - }] -]); - -async function audioGetUrl(definition, mode, options, download) { - const handler = audioUrlBuilders.get(mode); - if (typeof handler === 'function') { - try { - return await handler(definition, options, download); - } catch (e) { - // NOP - } } - return null; -} -function audioUrlNormalize(url, baseUrl, basePath) { - if (url) { - if (url[0] === '/') { - if (url.length >= 2 && url[1] === '/') { - // Begins with "//" - url = baseUrl.substring(0, baseUrl.indexOf(':') + 1) + url; - } else { - // Begins with "/" - url = baseUrl + url; - } - } else if (!/^[a-z][a-z0-9\-+.]*:/i.test(url)) { - // No URI scheme => relative path - url = baseUrl + basePath + url; - } + async _getUriCustom(definition, options) { + const customSourceUrl = options.audio.customSourceUrl; + return customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (hasOwn(definition, m1) ? `${definition[m1]}` : m0)); } - return url; } diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 1fdc4c70..66378b0c 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -21,9 +21,8 @@ conditionsTestValue, profileConditionsDescriptor handlebarsRenderDynamic requestText, requestJson, optionsLoad dictConfigured, dictTermsSort, dictEnabledSet -audioGetUrl jpConvertReading, jpDistributeFuriganaInflected, jpKatakanaToHiragana -AnkiNoteBuilder, AudioSystem, Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema, ClipboardMonitor*/ +AnkiNoteBuilder, AudioSystem, AudioUriBuilder, Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema, ClipboardMonitor*/ class Backend { constructor() { @@ -36,6 +35,7 @@ class Backend { this.optionsSchema = null; this.defaultAnkiFieldTemplates = null; this.audioSystem = new AudioSystem({getAudioUri: this._getAudioUri.bind(this)}); + this.audioUriBuilder = new AudioUriBuilder(); this.optionsContext = { depth: 0, url: window.location.href @@ -515,7 +515,7 @@ class Backend { async _onApiAudioGetUrl({definition, source, optionsContext}) { const options = this.getOptions(optionsContext); - return await audioGetUrl(definition, source, options); + return await this.audioUriBuilder.getUri(source, definition, options); } _onApiScreenshotGet({options}, sender) { @@ -771,7 +771,7 @@ class Backend { } const options = this.getOptions(optionsContext); - return await audioGetUrl(definition, source, options); + return await this.audioUriBuilder.getUri(source, definition, options); } async _audioInject(definition, fields, sources, optionsContext) { -- cgit v1.2.3 From aad4ab5eccaeed14514d676c0de4f3e2db718072 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 7 Mar 2020 14:37:44 -0500 Subject: Rename audio functions using "url" to use "uri" --- ext/bg/js/backend.js | 4 ++-- ext/bg/js/settings/audio.js | 4 ++-- ext/mixed/js/api.js | 4 ++-- ext/mixed/js/display.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 66378b0c..eb88a6c1 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -67,7 +67,7 @@ class Backend { ['noteView', this._onApiNoteView.bind(this)], ['templateRender', this._onApiTemplateRender.bind(this)], ['commandExec', this._onApiCommandExec.bind(this)], - ['audioGetUrl', this._onApiAudioGetUrl.bind(this)], + ['audioGetUri', this._onApiAudioGetUri.bind(this)], ['screenshotGet', this._onApiScreenshotGet.bind(this)], ['forward', this._onApiForward.bind(this)], ['frameInformationGet', this._onApiFrameInformationGet.bind(this)], @@ -513,7 +513,7 @@ class Backend { return this._runCommand(command, params); } - async _onApiAudioGetUrl({definition, source, optionsContext}) { + async _onApiAudioGetUri({definition, source, optionsContext}) { const options = this.getOptions(optionsContext); return await this.audioUriBuilder.getUri(source, definition, options); } diff --git a/ext/bg/js/settings/audio.js b/ext/bg/js/settings/audio.js index 6f581d9b..c825be6b 100644 --- a/ext/bg/js/settings/audio.js +++ b/ext/bg/js/settings/audio.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global getOptionsContext, getOptionsMutable, settingsSaveOptions, apiAudioGetUrl +/*global getOptionsContext, getOptionsMutable, settingsSaveOptions, apiAudioGetUri AudioSystem, AudioSourceUI*/ let audioSourceUI = null; @@ -26,7 +26,7 @@ async function audioSettingsInitialize() { audioSystem = new AudioSystem({ getAudioUri: async (definition, source) => { const optionsContext = getOptionsContext(); - return await apiAudioGetUrl(definition, source, optionsContext); + return await apiAudioGetUri(definition, source, optionsContext); } }); diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index 26f4389d..0ab07039 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -69,8 +69,8 @@ function apiTemplateRender(template, data) { return _apiInvoke('templateRender', {data, template}); } -function apiAudioGetUrl(definition, source, optionsContext) { - return _apiInvoke('audioGetUrl', {definition, source, optionsContext}); +function apiAudioGetUri(definition, source, optionsContext) { + return _apiInvoke('audioGetUri', {definition, source, optionsContext}); } function apiCommandExec(command, params) { diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 3fe8e684..a220c1f7 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -18,7 +18,7 @@ /*global docRangeFromPoint, docSentenceExtract apiKanjiFind, apiTermsFind, apiNoteView, apiOptionsGet, apiDefinitionsAddable, apiDefinitionAdd -apiScreenshotGet, apiForward, apiAudioGetUrl +apiScreenshotGet, apiForward, apiAudioGetUri AudioSystem, DisplayGenerator, WindowScroll, DisplayContext, DOM*/ class Display { @@ -919,6 +919,6 @@ class Display { async _getAudioUri(definition, source) { const optionsContext = this.getOptionsContext(); - return await apiAudioGetUrl(definition, source, optionsContext); + return await apiAudioGetUri(definition, source, optionsContext); } } -- cgit v1.2.3 From 9cd4a52b9e701f47c7ca7b44c52cbcd66b7bcb05 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 7 Mar 2020 14:39:25 -0500 Subject: Rename audio.js to audio-uri-builder.js --- ext/bg/background.html | 2 +- ext/bg/js/audio-uri-builder.js | 156 +++++++++++++++++++++++++++++++++++++++++ ext/bg/js/audio.js | 156 ----------------------------------------- 3 files changed, 157 insertions(+), 157 deletions(-) create mode 100644 ext/bg/js/audio-uri-builder.js delete mode 100644 ext/bg/js/audio.js (limited to 'ext') diff --git a/ext/bg/background.html b/ext/bg/background.html index f6e00bf5..44abe8fd 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -24,7 +24,7 @@ - + diff --git a/ext/bg/js/audio-uri-builder.js b/ext/bg/js/audio-uri-builder.js new file mode 100644 index 00000000..80e9cb9a --- /dev/null +++ b/ext/bg/js/audio-uri-builder.js @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2017-2020 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/*global jpIsStringEntirelyKana*/ + +class AudioUriBuilder { + constructor() { + this._getUrlHandlers = new Map([ + ['jpod101', this._getUriJpod101.bind(this)], + ['jpod101-alternate', this._getUriJpod101Alternate.bind(this)], + ['jisho', this._getUriJisho.bind(this)], + ['text-to-speech', this._getUriTextToSpeech.bind(this)], + ['text-to-speech-reading', this._getUriTextToSpeechReading.bind(this)], + ['custom', this._getUriCustom.bind(this)] + ]); + } + + normalizeUrl(url, baseUrl, basePath) { + if (url) { + if (url[0] === '/') { + if (url.length >= 2 && url[1] === '/') { + // Begins with "//" + url = baseUrl.substring(0, baseUrl.indexOf(':') + 1) + url; + } else { + // Begins with "/" + url = baseUrl + url; + } + } else if (!/^[a-z][a-z0-9\-+.]*:/i.test(url)) { + // No URI scheme => relative path + url = baseUrl + basePath + url; + } + } + return url; + } + + async getUri(mode, definition, options) { + const handler = this._getUrlHandlers.get(mode); + if (typeof handler === 'function') { + try { + return await handler(definition, options); + } catch (e) { + // NOP + } + } + return null; + } + + async _getUriJpod101(definition) { + let kana = definition.reading; + let kanji = definition.expression; + + if (!kana && jpIsStringEntirelyKana(kanji)) { + kana = kanji; + kanji = null; + } + + const params = []; + if (kanji) { + params.push(`kanji=${encodeURIComponent(kanji)}`); + } + if (kana) { + params.push(`kana=${encodeURIComponent(kana)}`); + } + + return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`; + } + + async _getUriJpod101Alternate(definition) { + const response = await new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('POST', 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.addEventListener('error', () => reject(new Error('Failed to scrape audio data'))); + xhr.addEventListener('load', () => resolve(xhr.responseText)); + xhr.send(`post=dictionary_reference&match_type=exact&search_query=${encodeURIComponent(definition.expression)}`); + }); + + const dom = new DOMParser().parseFromString(response, 'text/html'); + for (const row of dom.getElementsByClassName('dc-result-row')) { + try { + const url = row.querySelector('audio>source[src]').getAttribute('src'); + const reading = row.getElementsByClassName('dc-vocab_kana').item(0).textContent; + if (url && reading && (!definition.reading || definition.reading === reading)) { + return this.normalizeUrl(url, 'https://www.japanesepod101.com', '/learningcenter/reference/'); + } + } catch (e) { + // NOP + } + } + + throw new Error('Failed to find audio URL'); + } + + async _getUriJisho(definition) { + const response = await new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', `https://jisho.org/search/${definition.expression}`); + xhr.addEventListener('error', () => reject(new Error('Failed to scrape audio data'))); + xhr.addEventListener('load', () => resolve(xhr.responseText)); + xhr.send(); + }); + + const dom = new DOMParser().parseFromString(response, 'text/html'); + try { + const audio = dom.getElementById(`audio_${definition.expression}:${definition.reading}`); + if (audio !== null) { + const url = audio.getElementsByTagName('source').item(0).getAttribute('src'); + if (url) { + return this.normalizeUrl(url, 'https://jisho.org', '/search/'); + } + } + } catch (e) { + // NOP + } + + throw new Error('Failed to find audio URL'); + } + + async _getUriTextToSpeech(definition, options) { + const voiceURI = options.audio.textToSpeechVoice; + if (!voiceURI) { + throw new Error('No voice'); + } + + return `tts:?text=${encodeURIComponent(definition.expression)}&voice=${encodeURIComponent(voiceURI)}`; + } + + async _getUriTextToSpeechReading(definition, options) { + const voiceURI = options.audio.textToSpeechVoice; + if (!voiceURI) { + throw new Error('No voice'); + } + + return `tts:?text=${encodeURIComponent(definition.reading || definition.expression)}&voice=${encodeURIComponent(voiceURI)}`; + } + + async _getUriCustom(definition, options) { + const customSourceUrl = options.audio.customSourceUrl; + return customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (hasOwn(definition, m1) ? `${definition[m1]}` : m0)); + } +} diff --git a/ext/bg/js/audio.js b/ext/bg/js/audio.js deleted file mode 100644 index 80e9cb9a..00000000 --- a/ext/bg/js/audio.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2017-2020 Alex Yatskov - * Author: Alex Yatskov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*global jpIsStringEntirelyKana*/ - -class AudioUriBuilder { - constructor() { - this._getUrlHandlers = new Map([ - ['jpod101', this._getUriJpod101.bind(this)], - ['jpod101-alternate', this._getUriJpod101Alternate.bind(this)], - ['jisho', this._getUriJisho.bind(this)], - ['text-to-speech', this._getUriTextToSpeech.bind(this)], - ['text-to-speech-reading', this._getUriTextToSpeechReading.bind(this)], - ['custom', this._getUriCustom.bind(this)] - ]); - } - - normalizeUrl(url, baseUrl, basePath) { - if (url) { - if (url[0] === '/') { - if (url.length >= 2 && url[1] === '/') { - // Begins with "//" - url = baseUrl.substring(0, baseUrl.indexOf(':') + 1) + url; - } else { - // Begins with "/" - url = baseUrl + url; - } - } else if (!/^[a-z][a-z0-9\-+.]*:/i.test(url)) { - // No URI scheme => relative path - url = baseUrl + basePath + url; - } - } - return url; - } - - async getUri(mode, definition, options) { - const handler = this._getUrlHandlers.get(mode); - if (typeof handler === 'function') { - try { - return await handler(definition, options); - } catch (e) { - // NOP - } - } - return null; - } - - async _getUriJpod101(definition) { - let kana = definition.reading; - let kanji = definition.expression; - - if (!kana && jpIsStringEntirelyKana(kanji)) { - kana = kanji; - kanji = null; - } - - const params = []; - if (kanji) { - params.push(`kanji=${encodeURIComponent(kanji)}`); - } - if (kana) { - params.push(`kana=${encodeURIComponent(kana)}`); - } - - return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`; - } - - async _getUriJpod101Alternate(definition) { - const response = await new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - xhr.open('POST', 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'); - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xhr.addEventListener('error', () => reject(new Error('Failed to scrape audio data'))); - xhr.addEventListener('load', () => resolve(xhr.responseText)); - xhr.send(`post=dictionary_reference&match_type=exact&search_query=${encodeURIComponent(definition.expression)}`); - }); - - const dom = new DOMParser().parseFromString(response, 'text/html'); - for (const row of dom.getElementsByClassName('dc-result-row')) { - try { - const url = row.querySelector('audio>source[src]').getAttribute('src'); - const reading = row.getElementsByClassName('dc-vocab_kana').item(0).textContent; - if (url && reading && (!definition.reading || definition.reading === reading)) { - return this.normalizeUrl(url, 'https://www.japanesepod101.com', '/learningcenter/reference/'); - } - } catch (e) { - // NOP - } - } - - throw new Error('Failed to find audio URL'); - } - - async _getUriJisho(definition) { - const response = await new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - xhr.open('GET', `https://jisho.org/search/${definition.expression}`); - xhr.addEventListener('error', () => reject(new Error('Failed to scrape audio data'))); - xhr.addEventListener('load', () => resolve(xhr.responseText)); - xhr.send(); - }); - - const dom = new DOMParser().parseFromString(response, 'text/html'); - try { - const audio = dom.getElementById(`audio_${definition.expression}:${definition.reading}`); - if (audio !== null) { - const url = audio.getElementsByTagName('source').item(0).getAttribute('src'); - if (url) { - return this.normalizeUrl(url, 'https://jisho.org', '/search/'); - } - } - } catch (e) { - // NOP - } - - throw new Error('Failed to find audio URL'); - } - - async _getUriTextToSpeech(definition, options) { - const voiceURI = options.audio.textToSpeechVoice; - if (!voiceURI) { - throw new Error('No voice'); - } - - return `tts:?text=${encodeURIComponent(definition.expression)}&voice=${encodeURIComponent(voiceURI)}`; - } - - async _getUriTextToSpeechReading(definition, options) { - const voiceURI = options.audio.textToSpeechVoice; - if (!voiceURI) { - throw new Error('No voice'); - } - - return `tts:?text=${encodeURIComponent(definition.reading || definition.expression)}&voice=${encodeURIComponent(voiceURI)}`; - } - - async _getUriCustom(definition, options) { - const customSourceUrl = options.audio.customSourceUrl; - return customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (hasOwn(definition, m1) ? `${definition[m1]}` : m0)); - } -} -- cgit v1.2.3 From 0cbf427ab50061b48c9027e63e9ee8a209946d37 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 9 Mar 2020 21:00:57 -0400 Subject: Update argument order --- ext/bg/js/audio-uri-builder.js | 4 ++-- ext/bg/js/backend.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/audio-uri-builder.js b/ext/bg/js/audio-uri-builder.js index 80e9cb9a..15cea995 100644 --- a/ext/bg/js/audio-uri-builder.js +++ b/ext/bg/js/audio-uri-builder.js @@ -48,8 +48,8 @@ class AudioUriBuilder { return url; } - async getUri(mode, definition, options) { - const handler = this._getUrlHandlers.get(mode); + async getUri(definition, source, options) { + const handler = this._getUrlHandlers.get(source); if (typeof handler === 'function') { try { return await handler(definition, options); diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index eb88a6c1..adc6f13d 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -515,7 +515,7 @@ class Backend { async _onApiAudioGetUri({definition, source, optionsContext}) { const options = this.getOptions(optionsContext); - return await this.audioUriBuilder.getUri(source, definition, options); + return await this.audioUriBuilder.getUri(definition, source, options); } _onApiScreenshotGet({options}, sender) { @@ -771,7 +771,7 @@ class Backend { } const options = this.getOptions(optionsContext); - return await this.audioUriBuilder.getUri(source, definition, options); + return await this.audioUriBuilder.getUri(definition, source, options); } async _audioInject(definition, fields, sources, optionsContext) { -- cgit v1.2.3