Updated logic for checkAudioBookRemoved

This commit is contained in:
Jason Axley 2025-08-21 11:48:59 -07:00
parent ebdd5549ba
commit aae808544e
3 changed files with 84 additions and 21 deletions

View File

@ -45,6 +45,7 @@ const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilter
* @typedef AudioFileObject
* @property {number} index
* @property {string} ino
* @property {string} deviceId
* @property {{filename:string, ext:string, path:string, relPath:string, size:number, mtimeMs:number, ctimeMs:number, birthtimeMs:number}} metadata
* @property {number} addedAt
* @property {number} updatedAt

View File

@ -332,7 +332,7 @@ class LibraryItemScanData {
return true
}
// Fallback to check inode value
return this.audioLibraryFilesRemoved.some((af) => af.ino === existingAudioFile.ino)
return this.audioLibraryFilesRemoved.some((af) => af.ino === existingAudioFile.ino && af.deviceId === existingAudioFile.deviceId)
}
/**

View File

@ -38,6 +38,52 @@ describe('compareUpdateLibraryFileWithDeviceId', () => {
})
})
describe('checkAudioFileRemoved', function () {
this.timeout(0)
it('doesNotDetectFileRemovedWhenInodeIsSameButDeviceIdDiffers', () => {
const lisd = new LibraryItemScanData(buildFileProperties('/library/book/file.mp3', '1', '1000'))
lisd.libraryFilesRemoved.push(buildLibraryFileObject('/library/book/file.mp3', '1', '1000'))
const af_obj = buildAudioFileObject('/library/someotherbook/chapter1.mp3', '1', '200')
const fileRemoved = lisd.checkAudioFileRemoved(af_obj)
expect(fileRemoved).to.be.false
})
it('detectsFileRemovedWhenNameDoesNotMatchButInodeAndDeviceIdMatch', () => {
const lisd = new LibraryItemScanData(buildFileProperties('/library/book/file.mp3', '1', '1000'))
lisd.libraryFilesRemoved.push(buildLibraryFileObject('/library/book/file.mp3', '1', '1000'))
const af_obj = buildAudioFileObject('/library/someotherbook/chapter1.mp3', '1', '1000')
expect(lisd.path).to.not.equal(af_obj.metadata.path)
const fileRemoved = lisd.checkAudioFileRemoved(af_obj)
expect(fileRemoved).to.be.true
})
})
// checkEbookFileRemoved
// libraryItemObject()
/*
new LibraryItemScanData({
libraryFolderId: folder.id,
libraryId: library.id,
mediaType: library.mediaType,
ino: libraryItemStats.ino,
deviceId: libraryItemStats.dev,
mtimeMs: libraryItemStats.mtimeMs || 0,
ctimeMs: libraryItemStats.ctimeMs || 0,
birthtimeMs: libraryItemStats.birthtimeMs || 0,
path: libraryItemData.path,
relPath: libraryItemData.relPath,
isFile: isSingleMediaItem,
mediaMetadata: libraryItemData.mediaMetadata || null,
libraryFiles
})
*/
/**
* @returns {import('../../../server/models/LibraryItem').LibraryFileObject}
* @param {string} [path]
@ -63,24 +109,40 @@ function buildLibraryFileObject(path, ino, deviceId) {
}
}
}
// checkEbookFileRemoved
// checkAudioFileRemoved
// libraryItemObject()
/*
new LibraryItemScanData({
libraryFolderId: folder.id,
libraryId: library.id,
mediaType: library.mediaType,
ino: libraryItemStats.ino,
deviceId: libraryItemStats.dev,
mtimeMs: libraryItemStats.mtimeMs || 0,
ctimeMs: libraryItemStats.ctimeMs || 0,
birthtimeMs: libraryItemStats.birthtimeMs || 0,
path: libraryItemData.path,
relPath: libraryItemData.relPath,
isFile: isSingleMediaItem,
mediaMetadata: libraryItemData.mediaMetadata || null,
libraryFiles
})
*/
/** @returns {import('../../../server/models/Book').AudioFileObject} */
function buildAudioFileObject(path = '/library/somebook/file.mp3', ino = '1', deviceId = '1000') {
return {
index: 0,
ino: ino,
deviceId: deviceId,
metadata: {
filename: Path.basename(path),
ext: Path.extname(path),
path: path,
relPath: path,
size: 0,
mtimeMs: 0,
ctimeMs: 0,
birthtimeMs: 0
},
addedAt: 0,
updatedAt: 0,
trackNumFromMeta: 0,
discNumFromMeta: 0,
trackNumFromFilename: 0,
discNumFromFilename: 0,
manuallyVerified: false,
format: '',
duration: 0,
bitRate: 0,
language: '',
codec: '',
timeBase: '',
channels: 0,
channelLayout: '',
chapters: [],
metaTags: undefined,
mimeType: ''
}
}