From e41a90463b64b479169b65f50d95a7c962424f5d Mon Sep 17 00:00:00 2001 From: Conor Meyers Date: Tue, 18 Oct 2022 04:25:18 +0100 Subject: [PATCH] Fix:Unescaped characters in description causing issues with m4b merging --- server/managers/AbMergeManager.js | 2 +- server/utils/stringEscaper.js | 5 +++ server/utils/toneHelpers.js | 62 +++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 server/utils/stringEscaper.js diff --git a/server/managers/AbMergeManager.js b/server/managers/AbMergeManager.js index 1b3801c04..77b28e9b4 100644 --- a/server/managers/AbMergeManager.js +++ b/server/managers/AbMergeManager.js @@ -131,7 +131,7 @@ class AbMergeManager { } } - const toneMetadataObject = toneHelpers.getToneMetadataObject(libraryItem, chaptersFilePath) + const toneMetadataObject = toneHelpers.getEscapedToneMetadataObject(libraryItem, chaptersFilePath) toneMetadataObject.TrackNumber = 1 task.data.toneMetadataObject = toneMetadataObject diff --git a/server/utils/stringEscaper.js b/server/utils/stringEscaper.js new file mode 100644 index 000000000..e8510af0f --- /dev/null +++ b/server/utils/stringEscaper.js @@ -0,0 +1,5 @@ +function escapeString(string) { + return string.replace(/[.*"+?^${}()|[\]\\]/g, '\\$&'); +} + +module.exports.escapeString = escapeString \ No newline at end of file diff --git a/server/utils/toneHelpers.js b/server/utils/toneHelpers.js index fc88c169b..fc01503df 100644 --- a/server/utils/toneHelpers.js +++ b/server/utils/toneHelpers.js @@ -2,6 +2,7 @@ const tone = require('node-tone') const fs = require('../libs/fsExtra') const Logger = require('../Logger') const { secondsToTimestamp } = require('./index') +const stringEscaper = require('./stringEscaper') module.exports.writeToneChaptersFile = (chapters, filePath) => { var chaptersTxt = '' @@ -72,6 +73,67 @@ module.exports.getToneMetadataObject = (libraryItem, chaptersFile) => { return metadataObject } +module.exports.getEscapedToneMetadataObject = (libraryItem, chaptersFile) => { + const coverPath = libraryItem.media.coverPath + const bookMetadata = libraryItem.media.metadata + + const metadataObject = { + 'Title': bookMetadata.title || '', + 'Album': bookMetadata.title || '', + 'TrackTotal': libraryItem.media.tracks.length + } + const additionalFields = [] + + if (bookMetadata.subtitle) { + metadataObject['Subtitle'] = bookMetadata.subtitle + } + if (bookMetadata.authorName) { + metadataObject['Artist'] = bookMetadata.authorName + metadataObject['AlbumArtist'] = bookMetadata.authorName + } + if (bookMetadata.description) { + metadataObject['Comment'] = stringEscaper.escapeString(bookMetadata.description) + metadataObject['Description'] = stringEscaper.escapeString(bookMetadata.description) + } + if (bookMetadata.narratorName) { + metadataObject['Narrator'] = bookMetadata.narratorName + metadataObject['Composer'] = bookMetadata.narratorName + } + if (bookMetadata.firstSeriesName) { + metadataObject['MovementName'] = bookMetadata.firstSeriesName + } + if (bookMetadata.firstSeriesSequence) { + metadataObject['Movement'] = bookMetadata.firstSeriesSequence + } + if (bookMetadata.genres.length) { + metadataObject['Genre'] = bookMetadata.genres.join('/') + } + if (bookMetadata.publisher) { + metadataObject['Publisher'] = bookMetadata.publisher + } + if (bookMetadata.asin) { + additionalFields.push(`ASIN=${bookMetadata.asin}`) + } + if (bookMetadata.isbn) { + additionalFields.push(`ISBN=${bookMetadata.isbn}`) + } + if (coverPath) { + metadataObject['CoverFile'] = coverPath + } + if (parsePublishedYear(bookMetadata.publishedYear)) { + metadataObject['PublishingDate'] = parsePublishedYear(bookMetadata.publishedYear) + } + if (chaptersFile) { + metadataObject['ChaptersFile'] = chaptersFile + } + + if (additionalFields.length) { + metadataObject['AdditionalFields'] = additionalFields + } + + return metadataObject +} + module.exports.tagAudioFile = (filePath, payload) => { return tone.tag(filePath, payload).then((data) => { return true