From 975984e8d1b05d4c084e385b50159e0b1016bb9e Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 5 Dec 2021 11:29:42 -0600 Subject: [PATCH] Add:forceRescan rescans existing audio files,Fix:False positives for if an audio file was updated --- server/objects/AudioFile.js | 14 +++++----- server/objects/Audiobook.js | 15 ++++++++--- server/scanner/AudioFileScanner.js | 2 -- server/scanner/AudioProbeData.js | 2 +- server/scanner/Scanner.js | 41 ++++++++++++++++++++++-------- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/server/objects/AudioFile.js b/server/objects/AudioFile.js index 6c2c0333..99edac14 100644 --- a/server/objects/AudioFile.js +++ b/server/objects/AudioFile.js @@ -96,9 +96,9 @@ class AudioFile { this.exclude = !!data.exclude this.error = data.error || null - this.trackNumFromMeta = data.trackNumFromMeta || null - this.trackNumFromFilename = data.trackNumFromFilename || null - this.cdNumFromFilename = data.cdNumFromFilename || null + this.trackNumFromMeta = data.trackNumFromMeta + this.trackNumFromFilename = data.trackNumFromFilename + this.cdNumFromFilename = data.cdNumFromFilename this.format = data.format this.duration = data.duration @@ -130,9 +130,9 @@ class AudioFile { this.fullPath = data.fullPath this.addedAt = Date.now() - this.trackNumFromMeta = data.trackNumFromMeta || null - this.trackNumFromFilename = data.trackNumFromFilename || null - this.cdNumFromFilename = data.cdNumFromFilename || null + this.trackNumFromMeta = data.trackNumFromMeta + this.trackNumFromFilename = data.trackNumFromFilename + this.cdNumFromFilename = data.cdNumFromFilename this.manuallyVerified = !!data.manuallyVerified this.invalid = !!data.invalid @@ -302,9 +302,9 @@ class AudioFile { hasUpdated = true } } else if (this[key] !== newjson[key]) { + // console.log(this.filename, 'key', key, 'updated', this[key], newjson[key]) this[key] = newjson[key] hasUpdated = true - // console.log('key', key, 'updated', this[key], newjson[key]) } } return hasUpdated diff --git a/server/objects/Audiobook.js b/server/objects/Audiobook.js index 5fbfa8ab..419efc79 100644 --- a/server/objects/Audiobook.js +++ b/server/objects/Audiobook.js @@ -542,10 +542,9 @@ class Audiobook { var alreadyHasDescTxt = otherFilenamesAlreadyInBook.includes('desc.txt') var alreadyHasReaderTxt = otherFilenamesAlreadyInBook.includes('reader.txt') + // Filter out other files no longer in directory var newOtherFilePaths = newOtherFiles.map(f => f.path) this.otherFiles = this.otherFiles.filter(f => newOtherFilePaths.includes(f.path)) - - // Some files are not there anymore and filtered out if (currOtherFileNum !== this.otherFiles.length) { Logger.debug(`[Audiobook] ${currOtherFileNum - this.otherFiles.length} other files were removed for "${this.title}"`) hasUpdates = true @@ -937,6 +936,8 @@ class Audiobook { var newAudioFileData = [] var newOtherFileData = [] + var existingAudioFileData = [] + var existingOtherFileData = [] dataFound.audioFiles.forEach((af) => { var audioFileFoundCheck = this.checkFileFound(af, true) @@ -944,6 +945,9 @@ class Audiobook { newAudioFileData.push(af) } else if (audioFileFoundCheck) { hasUpdated = true + existingAudioFileData.push(af) + } else { + existingAudioFileData.push(af) } }) @@ -953,6 +957,9 @@ class Audiobook { newOtherFileData.push(otherFileData) } else if (fileFoundCheck) { hasUpdated = true + existingOtherFileData.push(otherFileData) + } else { + existingOtherFileData.push(otherFileData) } }) @@ -1010,7 +1017,9 @@ class Audiobook { newAudioFileData, newOtherFileData, audioFilesRemoved, - otherFilesRemoved + otherFilesRemoved, + existingAudioFileData, // Existing file data may get re-scanned if forceRescan is set + existingOtherFileData } } } diff --git a/server/scanner/AudioFileScanner.js b/server/scanner/AudioFileScanner.js index 718dcb65..c217f661 100644 --- a/server/scanner/AudioFileScanner.js +++ b/server/scanner/AudioFileScanner.js @@ -139,12 +139,10 @@ class AudioFileScanner { } if (existingAF) { if (audiobook.updateAudioFile(newAF)) { - // console.log('update dauido file') hasUpdated = true } } else { audiobook.addAudioFile(newAF) - // console.log('added auido file') hasUpdated = true } } diff --git a/server/scanner/AudioProbeData.js b/server/scanner/AudioProbeData.js index c6513ace..82efa6fa 100644 --- a/server/scanner/AudioProbeData.js +++ b/server/scanner/AudioProbeData.js @@ -35,7 +35,7 @@ class AudioProbeData { setData(data) { var audioStream = this.getDefaultAudioStream(data.audio_streams) - this.embeddedCoverArt = data.video_stream ? this.getEmbeddedCoverArt(data.video_stream) : false + this.embeddedCoverArt = data.video_stream ? this.getEmbeddedCoverArt(data.video_stream) : null this.format = data.format this.duration = data.duration this.size = data.size diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js index d5bd38d0..63eb6c27 100644 --- a/server/scanner/Scanner.js +++ b/server/scanner/Scanner.js @@ -305,9 +305,11 @@ class Scanner { return this.rescanAudiobook(abd, libraryScan) })) audiobooksUpdated = audiobooksUpdated.filter(ab => ab) // Filter out nulls - libraryScan.resultsUpdated += audiobooksUpdated.length - await this.db.updateEntities('audiobook', audiobooksUpdated) - this.emitter('audiobooks_updated', audiobooksUpdated.map(ab => ab.toJSONExpanded())) + if (audiobooksUpdated.length) { + libraryScan.resultsUpdated += audiobooksUpdated.length + await this.db.updateEntities('audiobook', audiobooksUpdated) + this.emitter('audiobooks_updated', audiobooksUpdated.map(ab => ab.toJSONExpanded())) + } } async scanNewAudiobookDataChunk(newAudiobookDataToScan, libraryScan) { @@ -321,24 +323,38 @@ class Scanner { } async rescanAudiobook(audiobookCheckData, libraryScan) { - const { newAudioFileData, newOtherFileData, audiobook, bookScanData } = audiobookCheckData + const { newAudioFileData, newOtherFileData, audiobook, bookScanData, updated, existingAudioFileData, existingOtherFileData } = audiobookCheckData libraryScan.addLog(LogLevel.DEBUG, `Library "${libraryScan.libraryName}" Re-scanning "${audiobook.path}"`) + var hasUpdated = updated // Sync other files first to use local images as cover before extracting audio file cover if (newOtherFileData.length || libraryScan.scanOptions.forceRescan) { // TODO: Cleanup other file sync - var allOtherFiles = newOtherFileData.concat(audiobook._otherFiles) - await audiobook.syncOtherFiles(allOtherFiles, this.MetadataPath, libraryScan.preferOpfMetadata) + var allOtherFiles = newOtherFileData.concat(existingOtherFileData) + if (await audiobook.syncOtherFiles(allOtherFiles, this.MetadataPath, libraryScan.preferOpfMetadata)) { + hasUpdated = true + } } + // forceRescan all existing audio files - will probe and update ID3 tag metadata + if (libraryScan.scanOptions.forceRescan && existingAudioFileData.length) { + if (await AudioFileScanner.scanAudioFiles(existingAudioFileData, bookScanData, audiobook, libraryScan.preferAudioMetadata, libraryScan)) { + hasUpdated = true + } + } + // Scan new audio files + if (newAudioFileData.length) { + if (await AudioFileScanner.scanAudioFiles(newAudioFileData, bookScanData, audiobook, libraryScan.preferAudioMetadata, libraryScan)) { + hasUpdated = true + } + } + // If an audio file has embedded cover art and no cover is set yet, extract & use it if (newAudioFileData.length || libraryScan.scanOptions.forceRescan) { - await AudioFileScanner.scanAudioFiles(newAudioFileData, bookScanData, audiobook, libraryScan.preferAudioMetadata, libraryScan) - - // Extract embedded cover art if cover is not already in directory if (audiobook.hasEmbeddedCoverArt && !audiobook.cover) { var outputCoverDirs = this.getCoverDirectory(audiobook) var relativeDir = await audiobook.saveEmbeddedCoverArt(outputCoverDirs.fullPath, outputCoverDirs.relPath) if (relativeDir) { + hasUpdated = true libraryScan.addLog(LogLevel.DEBUG, `Saved embedded cover art "${relativeDir}"`) } } @@ -346,17 +362,20 @@ class Scanner { if (!audiobook.audioFilesToInclude.length && !audiobook.ebooks.length) { // Audiobook is invalid audiobook.setInvalid() + hasUpdated = true } else if (audiobook.isInvalid) { audiobook.isInvalid = false + hasUpdated = true } - // Scan for cover if enabled and has no cover + // Scan for cover if enabled and has no cover (and author or title has changed OR has been 7 days since last lookup) if (audiobook && libraryScan.findCovers && !audiobook.cover && audiobook.book.shouldSearchForCover) { var updatedCover = await this.searchForCover(audiobook, libraryScan) audiobook.book.updateLastCoverSearch(updatedCover) + hasUpdated = true } - return audiobook + return hasUpdated ? audiobook : null } async scanNewAudiobook(audiobookData, preferAudioMetadata, preferOpfMetadata, findCovers, libraryScan = null) {