1
0
mirror of https://github.com/advplyr/audiobookshelf.git synced 2025-03-05 00:18:30 +01:00

Scanner update check for mismatched inode and update

This commit is contained in:
Mark Cooper 2021-10-01 14:52:10 -05:00
parent 47c6c1aaad
commit 0db34dcab5
4 changed files with 64 additions and 10 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "audiobookshelf-client", "name": "audiobookshelf-client",
"version": "1.3.1", "version": "1.3.2",
"description": "Audiobook manager and player", "description": "Audiobook manager and player",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
{ {
"name": "audiobookshelf", "name": "audiobookshelf",
"version": "1.3.1", "version": "1.3.2",
"description": "Self-hosted audiobook server for managing and playing audiobooks", "description": "Self-hosted audiobook server for managing and playing audiobooks",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -60,10 +60,59 @@ class Scanner {
return audiobookDataAudioFiles.filter(abdFile => !!abdFile.ino) return audiobookDataAudioFiles.filter(abdFile => !!abdFile.ino)
} }
// Only updates audio files with matching paths
syncAudiobookInodeValues(audiobook, { audioFiles, otherFiles }) {
var filesUpdated = 0
// Sync audio files & audio tracks with updated inodes
audiobook._audioFiles.forEach((audioFile) => {
var matchingAudioFile = audioFiles.find(af => af.ino !== audioFile.ino && af.path === audioFile.path)
if (matchingAudioFile) {
// Audio Track should always have the same ino as the equivalent audio file (not all audio files have a track)
var audioTrack = audiobook.tracks.find(t => t.ino === audioFile.ino)
if (audioTrack) {
Logger.debug(`[Scanner] Found audio file & track with mismatched inode "${audioFile.filename}" - updating it`)
audioTrack.ino = matchingAudioFile.ino
filesUpdated++
} else {
Logger.debug(`[Scanner] Found audio file with mismatched inode "${audioFile.filename}" - updating it`)
}
audioFile.ino = matchingAudioFile.ino
filesUpdated++
}
})
// Sync other files with updated inodes
audiobook._otherFiles.forEach((otherFile) => {
var matchingOtherFile = otherFiles.find(of => of.ino !== otherFile.ino && of.path === otherFile.path)
if (matchingOtherFile) {
Logger.debug(`[Scanner] Found other file with mismatched inode "${otherFile.filename}" - updating it`)
otherFile.ino = matchingOtherFile.ino
filesUpdated++
}
})
return filesUpdated
}
async scanAudiobookData(audiobookData, forceAudioFileScan = false) { async scanAudiobookData(audiobookData, forceAudioFileScan = false) {
var existingAudiobook = this.audiobooks.find(a => a.ino === audiobookData.ino) var existingAudiobook = this.audiobooks.find(a => a.ino === audiobookData.ino)
// Logger.debug(`[Scanner] Scanning "${audiobookData.title}" (${audiobookData.ino}) - ${!!existingAudiobook ? 'Exists' : 'New'}`)
// inode value may change when using shared drives, update inode if matching path is found
// Note: inode will not change on rename
var hasUpdatedIno = false
if (!existingAudiobook) {
// check an audiobook exists with matching path, then update inodes
existingAudiobook = this.audiobooks.find(a => a.path === audiobookData.path)
if (existingAudiobook) {
hasUpdatedIno = true
var filesUpdated = this.syncAudiobookInodeValues(existingAudiobook, audiobookData)
Logger.info(`[Scanner] Updating inode value for "${existingAudiobook.title}" - ${filesUpdated} files updated`)
}
}
// Logger.debug(`[Scanner] Scanning "${audiobookData.title}" (${audiobookData.ino}) - ${!!existingAudiobook ? 'Exists' : 'New'}`)
if (existingAudiobook) { if (existingAudiobook) {
// TEMP: Check if is older audiobook and needs force rescan // TEMP: Check if is older audiobook and needs force rescan
@ -158,7 +207,7 @@ class Scanner {
return ScanResult.REMOVED return ScanResult.REMOVED
} }
var hasUpdates = removedAudioFiles.length || removedAudioTracks.length || newAudioFiles.length || hasUpdatedAudioFiles var hasUpdates = hasUpdatedIno || removedAudioFiles.length || removedAudioTracks.length || newAudioFiles.length || hasUpdatedAudioFiles
// Check that audio tracks are in sequential order with no gaps // Check that audio tracks are in sequential order with no gaps
if (existingAudiobook.checkUpdateMissingParts()) { if (existingAudiobook.checkUpdateMissingParts()) {
@ -177,12 +226,14 @@ class Scanner {
hasUpdates = true hasUpdates = true
} }
// If audiobook was missing before, it is now found
if (existingAudiobook.isMissing) { if (existingAudiobook.isMissing) {
existingAudiobook.isMissing = false existingAudiobook.isMissing = false
hasUpdates = true hasUpdates = true
Logger.info(`[Scanner] "${existingAudiobook.title}" was missing but now it is found`) Logger.info(`[Scanner] "${existingAudiobook.title}" was missing but now it is found`)
} }
// Save changes and notify users
if (hasUpdates) { if (hasUpdates) {
existingAudiobook.setChapters() existingAudiobook.setChapters()

View File

@ -105,23 +105,26 @@ class Audiobook {
} }
get invalidParts() { get invalidParts() {
return (this.audioFiles || []).filter(af => af.invalid).map(af => ({ filename: af.filename, error: af.error || 'Unknown Error' })) return this._audioFiles.filter(af => af.invalid).map(af => ({ filename: af.filename, error: af.error || 'Unknown Error' }))
} }
get _audioFiles() { return this.audioFiles || [] }
get _otherFiles() { return this.otherFiles || [] }
get ebooks() { get ebooks() {
return this.otherFiles.filter(file => file.filetype === 'ebook') return this.otherFiles.filter(file => file.filetype === 'ebook')
} }
get hasMissingIno() { get hasMissingIno() {
return !this.ino || (this.audioFiles || []).find(abf => !abf.ino) || (this.otherFiles || []).find(f => !f.ino) || (this.tracks || []).find(t => !t.ino) return !this.ino || this._audioFiles.find(abf => !abf.ino) || this._otherFiles.find(f => !f.ino) || (this.tracks || []).find(t => !t.ino)
} }
get hasEmbeddedCoverArt() { get hasEmbeddedCoverArt() {
return !!(this.audioFiles || []).find(af => af.embeddedCoverArt) return !!this._audioFiles.find(af => af.embeddedCoverArt)
} }
get hasDescriptionTextFile() { get hasDescriptionTextFile() {
return !!(this.otherFiles || []).find(of => of.filename === 'desc.txt') return !!this._otherFiles.find(of => of.filename === 'desc.txt')
} }
bookToJSON() { bookToJSON() {
@ -148,8 +151,8 @@ class Audiobook {
tags: this.tags, tags: this.tags,
book: this.bookToJSON(), book: this.bookToJSON(),
tracks: this.tracksToJSON(), tracks: this.tracksToJSON(),
audioFiles: (this.audioFiles || []).map(audioFile => audioFile.toJSON()), audioFiles: this._audioFiles.map(audioFile => audioFile.toJSON()),
otherFiles: (this.otherFiles || []).map(otherFile => otherFile.toJSON()), otherFiles: this._otherFiles.map(otherFile => otherFile.toJSON()),
chapters: this.chapters || [], chapters: this.chapters || [],
isMissing: !!this.isMissing isMissing: !!this.isMissing
} }