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:
parent
17ebe6a754
commit
35abd517b9
@ -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';
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user