Remove invalid file name characters from Anki media files (#496)

* Replace invalid file name characters

* Replace "filename" with "fileName"
This commit is contained in:
toasted-nutbread 2020-05-06 19:25:56 -04:00 committed by GitHub
parent a88501ff10
commit ac2f743b76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 15 deletions

View File

@ -76,8 +76,9 @@ class AnkiNoteBuilder {
const expressions = definition.expressions; const expressions = definition.expressions;
const audioSourceDefinition = Array.isArray(expressions) ? expressions[0] : definition; const audioSourceDefinition = Array.isArray(expressions) ? expressions[0] : definition;
const filename = this._createInjectedAudioFileName(audioSourceDefinition); let fileName = this._createInjectedAudioFileName(audioSourceDefinition);
if (filename === null) { return; } if (fileName === null) { return; }
fileName = AnkiNoteBuilder.replaceInvalidFileNameCharacters(fileName);
const {audio} = await this._audioSystem.getDefinitionAudio( const {audio} = await this._audioSystem.getDefinitionAudio(
audioSourceDefinition, audioSourceDefinition,
@ -91,9 +92,9 @@ class AnkiNoteBuilder {
); );
const data = AnkiNoteBuilder.arrayBufferToBase64(audio); const data = AnkiNoteBuilder.arrayBufferToBase64(audio);
await this._anki.storeMediaFile(filename, data); await this._anki.storeMediaFile(fileName, data);
definition.audioFileName = filename; definition.audioFileName = fileName;
} catch (e) { } catch (e) {
// NOP // NOP
} }
@ -103,28 +104,29 @@ class AnkiNoteBuilder {
if (!this._containsMarker(fields, 'screenshot')) { return; } if (!this._containsMarker(fields, 'screenshot')) { return; }
const now = new Date(Date.now()); const now = new Date(Date.now());
const filename = `yomichan_browser_screenshot_${definition.reading}_${this._dateToString(now)}.${screenshot.format}`; let fileName = `yomichan_browser_screenshot_${definition.reading}_${this._dateToString(now)}.${screenshot.format}`;
fileName = AnkiNoteBuilder.replaceInvalidFileNameCharacters(fileName);
const data = screenshot.dataUrl.replace(/^data:[\w\W]*?,/, ''); const data = screenshot.dataUrl.replace(/^data:[\w\W]*?,/, '');
try { try {
await this._anki.storeMediaFile(filename, data); await this._anki.storeMediaFile(fileName, data);
} catch (e) { } catch (e) {
return; return;
} }
definition.screenshotFileName = filename; definition.screenshotFileName = fileName;
} }
_createInjectedAudioFileName(definition) { _createInjectedAudioFileName(definition) {
const {reading, expression} = definition; const {reading, expression} = definition;
if (!reading && !expression) { return null; } if (!reading && !expression) { return null; }
let filename = 'yomichan'; let fileName = 'yomichan';
if (reading) { filename += `_${reading}`; } if (reading) { fileName += `_${reading}`; }
if (expression) { filename += `_${expression}`; } if (expression) { fileName += `_${expression}`; }
filename += '.mp3'; fileName += '.mp3';
filename = filename.replace(/\]/g, ''); fileName = fileName.replace(/\]/g, '');
return filename; return fileName;
} }
_dateToString(date) { _dateToString(date) {
@ -147,6 +149,11 @@ class AnkiNoteBuilder {
return false; return false;
} }
static replaceInvalidFileNameCharacters(fileName) {
// eslint-disable-next-line no-control-regex
return fileName.replace(/[<>:"/\\|?*\x00-\x1F]/g, '-');
}
static arrayBufferToBase64(arrayBuffer) { static arrayBufferToBase64(arrayBuffer) {
return window.btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); return window.btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
} }

View File

@ -79,12 +79,12 @@ class AnkiConnect {
return await this._invoke('guiBrowse', {query}); return await this._invoke('guiBrowse', {query});
} }
async storeMediaFile(filename, dataBase64) { async storeMediaFile(fileName, dataBase64) {
if (!this._enabled) { if (!this._enabled) {
throw new Error('AnkiConnect not enabled'); throw new Error('AnkiConnect not enabled');
} }
await this._checkVersion(); await this._checkVersion();
return await this._invoke('storeMediaFile', {filename, data: dataBase64}); return await this._invoke('storeMediaFile', {filename: fileName, data: dataBase64});
} }
async findNoteIds(notes, duplicateScope) { async findNoteIds(notes, duplicateScope) {