AudioUriBuilder simplification (#799)

* Rename variables to disambiguate

* Update handler argument convention

* Update getUri argument convention

* Change _getAudioUri argument convention

* Change getDefinitionAudio argument convention

* Add api.getDefinitionAudio definition
This commit is contained in:
toasted-nutbread 2020-09-10 11:57:38 -04:00 committed by GitHub
parent 17ebe6a754
commit 35abd517b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 42 deletions

View File

@ -124,15 +124,16 @@ class AnkiNoteBuilder {
try {
const {sources, customSourceUrl} = details;
const expressions = definition.expressions;
const audioSourceDefinition = Array.isArray(expressions) ? expressions[0] : definition;
const {expression, reading} = Array.isArray(expressions) ? expressions[0] : definition;
let fileName = this._createInjectedAudioFileName(audioSourceDefinition);
let fileName = this._createInjectedAudioFileName(expression, reading);
if (fileName === null) { return; }
fileName = this._replaceInvalidFileNameCharacters(fileName);
const {audio: data} = await this._getDefinitionAudio(
audioSourceDefinition,
sources,
expression,
reading,
{
textToSpeechVoice: null,
customSourceUrl,
@ -199,8 +200,7 @@ class AnkiNoteBuilder {
}
}
_createInjectedAudioFileName(definition) {
const {reading, expression} = definition;
_createInjectedAudioFileName(expression, reading) {
if (!reading && !expression) { return null; }
let fileName = 'yomichan';

View File

@ -51,11 +51,11 @@ class AudioUriBuilder {
return url;
}
async getUri(definition, source, details) {
async getUri(source, expression, reading, details) {
const handler = this._getUrlHandlers.get(source);
if (typeof handler === 'function') {
try {
return await handler(definition, details);
return await handler(expression, reading, details);
} catch (e) {
// NOP
}
@ -63,9 +63,9 @@ class AudioUriBuilder {
return null;
}
async _getUriJpod101(definition) {
let kana = definition.reading;
let kanji = definition.expression;
async _getUriJpod101(expression, reading) {
let kana = reading;
let kanji = expression;
if (!kana && jp.isStringEntirelyKana(kanji)) {
kana = kanji;
@ -83,9 +83,9 @@ class AudioUriBuilder {
return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`;
}
async _getUriJpod101Alternate(definition) {
async _getUriJpod101Alternate(expression, reading) {
const fetchUrl = 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post';
const data = `post=dictionary_reference&match_type=exact&search_query=${encodeURIComponent(definition.expression)}&vulgar=true`;
const data = `post=dictionary_reference&match_type=exact&search_query=${encodeURIComponent(expression)}&vulgar=true`;
const response = await this._requestBuilder.fetchAnonymous(fetchUrl, {
method: 'POST',
mode: 'cors',
@ -112,11 +112,11 @@ class AudioUriBuilder {
const url = dom.getAttribute(source, 'src');
if (url === null) { continue; }
const readings = dom.getElementsByClassName('dc-vocab_kana');
if (readings.length === 0) { continue; }
const htmlReadings = dom.getElementsByClassName('dc-vocab_kana');
if (htmlReadings.length === 0) { continue; }
const reading = dom.getTextContent(readings[0]);
if (reading && (!definition.reading || definition.reading === reading)) {
const htmlReading = dom.getTextContent(htmlReadings[0]);
if (htmlReading && (!reading || reading === htmlReading)) {
return this.normalizeUrl(url, 'https://www.japanesepod101.com', '/learningcenter/reference/');
}
} catch (e) {
@ -127,8 +127,8 @@ class AudioUriBuilder {
throw new Error('Failed to find audio URL');
}
async _getUriJisho(definition) {
const fetchUrl = `https://jisho.org/search/${definition.expression}`;
async _getUriJisho(expression, reading) {
const fetchUrl = `https://jisho.org/search/${expression}`;
const response = await this._requestBuilder.fetchAnonymous(fetchUrl, {
method: 'GET',
mode: 'cors',
@ -141,7 +141,7 @@ class AudioUriBuilder {
const dom = new SimpleDOMParser(responseText);
try {
const audio = dom.getElementById(`audio_${definition.expression}:${definition.reading}`);
const audio = dom.getElementById(`audio_${expression}:${reading}`);
if (audio !== null) {
const source = dom.getElementByTagName('source', audio);
if (source !== null) {
@ -158,24 +158,25 @@ class AudioUriBuilder {
throw new Error('Failed to find audio URL');
}
async _getUriTextToSpeech(definition, {textToSpeechVoice}) {
async _getUriTextToSpeech(expression, reading, {textToSpeechVoice}) {
if (!textToSpeechVoice) {
throw new Error('No voice');
}
return `tts:?text=${encodeURIComponent(definition.expression)}&voice=${encodeURIComponent(textToSpeechVoice)}`;
return `tts:?text=${encodeURIComponent(expression)}&voice=${encodeURIComponent(textToSpeechVoice)}`;
}
async _getUriTextToSpeechReading(definition, {textToSpeechVoice}) {
async _getUriTextToSpeechReading(expression, reading, {textToSpeechVoice}) {
if (!textToSpeechVoice) {
throw new Error('No voice');
}
return `tts:?text=${encodeURIComponent(definition.reading || definition.expression)}&voice=${encodeURIComponent(textToSpeechVoice)}`;
return `tts:?text=${encodeURIComponent(reading || expression)}&voice=${encodeURIComponent(textToSpeechVoice)}`;
}
async _getUriCustom(definition, {customSourceUrl}) {
async _getUriCustom(expression, reading, {customSourceUrl}) {
if (typeof customSourceUrl !== 'string') {
throw new Error('No custom URL defined');
}
return customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (hasOwn(definition, m1) ? `${definition[m1]}` : m0));
const data = {expression, reading};
return customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (hasOwn(data, m1) ? `${data[m1]}` : m0));
}
}

View File

@ -508,8 +508,8 @@ class Backend {
return this._runCommand(command, params);
}
async _onApiAudioGetUri({definition, source, details}) {
return await this._audioUriBuilder.getUri(definition, source, details);
async _onApiAudioGetUri({source, expression, reading, details}) {
return await this._audioUriBuilder.getUri(source, expression, reading, details);
}
_onApiScreenshotGet({options}, sender) {
@ -828,8 +828,8 @@ class Backend {
return (tab !== null);
}
async _onApiGetDefinitionAudio({definition, sources, details}) {
return this._getDefinitionAudio(definition, sources, details);
async _onApiGetDefinitionAudio({sources, expression, reading, details}) {
return this._getDefinitionAudio(sources, expression, reading, details);
}
// Command handlers
@ -1637,7 +1637,7 @@ class Backend {
}
}
async _getDefinitionAudio(definition, sources, details) {
return await this._audioSystem.getDefinitionAudio(definition, sources, details);
async _getDefinitionAudio(sources, expression, reading, details) {
return await this._audioSystem.getDefinitionAudio(sources, expression, reading, details);
}
}

View File

@ -93,8 +93,8 @@ const api = (() => {
return this._invoke('templateRender', {data, template, marker});
}
audioGetUri(definition, source, details) {
return this._invoke('audioGetUri', {definition, source, details});
audioGetUri(source, expression, reading, details) {
return this._invoke('audioGetUri', {source, expression, reading, details});
}
commandExec(command, params) {
@ -197,6 +197,10 @@ const api = (() => {
return this._invoke('isTabSearchPopup', {tabId});
}
getDefinitionAudio(sources, expression, reading, details) {
return this._invoke('getDefinitionAudio', {sources, expression, reading, details});
}
// Invoke functions with progress
deleteDictionary(dictionaryName, onProgress) {

View File

@ -78,8 +78,8 @@ class AudioSystem {
}
}
async getDefinitionAudio(definition, sources, details) {
const key = `${definition.expression}:${definition.reading}`;
async getDefinitionAudio(sources, expression, reading, details) {
const key = `${expression}:${reading}`;
const hasCache = (this._cache !== null && !details.disableCache);
if (hasCache) {
@ -95,7 +95,7 @@ class AudioSystem {
for (let i = 0, ii = sources.length; i < ii; ++i) {
const source = sources[i];
const uri = await this._getAudioUri(definition, source, details);
const uri = await this._getAudioUri(source, expression, reading, details);
if (uri === null) { continue; }
try {
@ -129,10 +129,10 @@ class AudioSystem {
// NOP
}
_getAudioUri(definition, source, details) {
_getAudioUri(source, expression, reading, details) {
return (
this._audioUriBuilder !== null ?
this._audioUriBuilder.getUri(definition, source, details) :
this._audioUriBuilder.getUri(source, expression, reading, details) :
null
);
}

View File

@ -42,8 +42,8 @@ class Display extends EventDispatcher {
this._audioFallback = null;
this._audioSystem = new AudioSystem({
audioUriBuilder: {
getUri: async (definition, source, details) => {
return await api.audioGetUri(definition, source, details);
getUri: async (source, expression, reading, details) => {
return await api.audioGetUri(source, expression, reading, details);
}
},
useCache: true
@ -1071,7 +1071,7 @@ class Display extends EventDispatcher {
try {
this.setSpinnerVisible(true);
const expression = expressionIndex === -1 ? definition : definition.expressions[expressionIndex];
const {expression, reading} = expressionIndex === -1 ? definition : definition.expressions[expressionIndex];
this._stopPlayingAudio();
@ -1079,7 +1079,7 @@ class Display extends EventDispatcher {
try {
const {sources, textToSpeechVoice, customSourceUrl} = this._options.audio;
let index;
({audio, index} = await this._audioSystem.getDefinitionAudio(expression, sources, {textToSpeechVoice, customSourceUrl}));
({audio, index} = await this._audioSystem.getDefinitionAudio(sources, expression, reading, {textToSpeechVoice, customSourceUrl}));
info = `From source ${1 + index}: ${sources[index]}`;
} catch (e) {
if (this._audioFallback === null) {