mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-21 11:19:37 +00:00
Added support for deviceId
This commit is contained in:
parent
aae808544e
commit
423f2d311e
9 changed files with 369 additions and 222 deletions
|
|
@ -8,10 +8,11 @@ const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilter
|
|||
/**
|
||||
* @typedef EBookFileObject
|
||||
* @property {string} ino
|
||||
* @property {string} deviceId
|
||||
* @property {string} ebookFormat
|
||||
* @property {number} addedAt
|
||||
* @property {number} updatedAt
|
||||
* @property {{filename:string, ext:string, path:string, relPath:strFing, size:number, mtimeMs:number, ctimeMs:number, birthtimeMs:number}} metadata
|
||||
* @property {{filename:string, ext:string, path:string, relPath:string, size:number, mtimeMs:number, ctimeMs:number, birthtimeMs:number}} metadata
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ const packageJson = require('../../package.json')
|
|||
const { LogLevel } = require('../utils/constants')
|
||||
const LibraryItem = require('../models/LibraryItem')
|
||||
const globals = require('../utils/globals')
|
||||
const LibraryFile = require('../objects/files/LibraryFile')
|
||||
const LibraryScan = require('./LibraryScan')
|
||||
const ScanLogger = require('./ScanLogger')
|
||||
|
||||
class LibraryItemScanData {
|
||||
/**
|
||||
|
|
@ -226,13 +229,7 @@ class LibraryItemScanData {
|
|||
|
||||
for (const existingLibraryFile of existingLibraryItem.libraryFiles) {
|
||||
// Find matching library file using path first and fallback to using inode value
|
||||
let matchingLibraryFile = this.libraryFiles.find((lf) => lf.metadata.path === existingLibraryFile.metadata.path)
|
||||
if (!matchingLibraryFile) {
|
||||
matchingLibraryFile = this.libraryFiles.find((lf) => lf.ino === existingLibraryFile.ino)
|
||||
if (matchingLibraryFile) {
|
||||
libraryScan.addLog(LogLevel.INFO, `Library file with path "${existingLibraryFile.metadata.path}" not found, but found file with matching inode value "${existingLibraryFile.ino}" at path "${matchingLibraryFile.metadata.path}"`)
|
||||
}
|
||||
}
|
||||
let matchingLibraryFile = this.findMatchingLibraryFileByPathOrInodeAndDeviceId(existingLibraryFile, libraryScan)
|
||||
|
||||
if (!matchingLibraryFile) {
|
||||
// Library file removed
|
||||
|
|
@ -278,10 +275,9 @@ class LibraryItemScanData {
|
|||
existingLibraryItem.changed('libraryFiles', true)
|
||||
}
|
||||
await existingLibraryItem.save()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return this.hasChanges
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -320,6 +316,23 @@ class LibraryItemScanData {
|
|||
return hasChanges
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {LibraryFile | undefined} if [existingLibraryFile] matches an existing libraryFile
|
||||
* @param {LibraryItem.LibraryFileObject} [existingLibraryFile]
|
||||
* @param {LibraryScan | ScanLogger} [libraryScan]
|
||||
*/
|
||||
findMatchingLibraryFileByPathOrInodeAndDeviceId(existingLibraryFile, libraryScan) {
|
||||
if (!existingLibraryFile) return
|
||||
let matchingLibraryFile = this.libraryFiles.find((lf) => lf.metadata.path === existingLibraryFile.metadata.path)
|
||||
if (!matchingLibraryFile) {
|
||||
matchingLibraryFile = this.libraryFiles.find((lf) => lf.ino === existingLibraryFile.ino && lf.deviceId === existingLibraryFile.deviceId)
|
||||
if (matchingLibraryFile) {
|
||||
libraryScan && libraryScan.addLog(LogLevel.INFO, `Library file with path "${existingLibraryFile.metadata.path}" not found, but found file with matching inode value "${existingLibraryFile.ino}" at path "${matchingLibraryFile.metadata.path}"`)
|
||||
}
|
||||
}
|
||||
return matchingLibraryFile
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if existing audio file on Book was removed
|
||||
* @param {import('../models/Book').AudioFileObject} existingAudioFile
|
||||
|
|
@ -341,13 +354,13 @@ class LibraryItemScanData {
|
|||
* @returns {boolean} true if ebook file was removed
|
||||
*/
|
||||
checkEbookFileRemoved(ebookFile) {
|
||||
if (!this.ebookLibraryFiles.length) return true
|
||||
if (!this.ebookLibraryFilesRemoved.length) return false
|
||||
|
||||
if (this.ebookLibraryFiles.some((lf) => lf.metadata.path === ebookFile.metadata.path)) {
|
||||
return false
|
||||
if (this.ebookLibraryFilesRemoved.some((lf) => lf.metadata.path === ebookFile.metadata.path)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return !this.ebookLibraryFiles.some((lf) => lf.ino === ebookFile.ino)
|
||||
return this.ebookLibraryFilesRemoved.some((lf) => lf.ino === ebookFile.ino && lf.deviceId === ebookFile.deviceId)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -344,23 +344,7 @@ class LibraryScanner {
|
|||
continue
|
||||
}
|
||||
|
||||
items.push(
|
||||
new LibraryItemScanData({
|
||||
libraryFolderId: folder.id,
|
||||
libraryId: folder.libraryId,
|
||||
mediaType: library.mediaType,
|
||||
ino: libraryItemFolderStats.ino,
|
||||
deviceId: libraryItemFolderStats.dev,
|
||||
mtimeMs: libraryItemFolderStats.mtimeMs || 0,
|
||||
ctimeMs: libraryItemFolderStats.ctimeMs || 0,
|
||||
birthtimeMs: libraryItemFolderStats.birthtimeMs || 0,
|
||||
path: libraryItemData.path,
|
||||
relPath: libraryItemData.relPath,
|
||||
isFile,
|
||||
mediaMetadata: libraryItemData.mediaMetadata || null,
|
||||
libraryFiles: fileObjs
|
||||
})
|
||||
)
|
||||
items.push(createLibraryItemScanData(folder, library, libraryItemFolderStats, libraryItemData, isFile, fileObjs))
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
|
@ -754,3 +738,30 @@ async function findLibraryItemByFileToItemInoMatch(libraryId, fullPath, isSingle
|
|||
if (existingLibraryItem) Logger.debug(`[LibraryScanner] Found library item with inode matching one of "${itemFileInos.join(',')}" at path "${existingLibraryItem.path}"`)
|
||||
return existingLibraryItem
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ id: any; libraryId: any; }} folder
|
||||
* @param {{ mediaType: any; }} library
|
||||
* @param {{ ino: any; dev: any; mtimeMs: any; ctimeMs: any; birthtimeMs: any; }} libraryItemFolderStats
|
||||
* @param {{ path: any; relPath: any; mediaMetadata: any; }} libraryItemData
|
||||
* @param {any} isFile
|
||||
* @param {any} fileObjs
|
||||
* @returns {LibraryItemScanData} new object
|
||||
*/
|
||||
function createLibraryItemScanData(folder, library, libraryItemFolderStats, libraryItemData, isFile, fileObjs) {
|
||||
return new LibraryItemScanData({
|
||||
libraryFolderId: folder.id,
|
||||
libraryId: folder.libraryId,
|
||||
mediaType: library.mediaType,
|
||||
ino: libraryItemFolderStats.ino,
|
||||
deviceId: libraryItemFolderStats.dev,
|
||||
mtimeMs: libraryItemFolderStats.mtimeMs || 0,
|
||||
ctimeMs: libraryItemFolderStats.ctimeMs || 0,
|
||||
birthtimeMs: libraryItemFolderStats.birthtimeMs || 0,
|
||||
path: libraryItemData.path,
|
||||
relPath: libraryItemData.relPath,
|
||||
isFile,
|
||||
mediaMetadata: libraryItemData.mediaMetadata || null,
|
||||
libraryFiles: fileObjs
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ class PodcastScanner {
|
|||
* @param {PodcastEpisode[]} podcastEpisodes Not the models for new podcasts
|
||||
* @param {import('./LibraryItemScanData')} libraryItemData
|
||||
* @param {import('./LibraryScan')} libraryScan
|
||||
* @param {string} [existingLibraryItemId]
|
||||
* @param {string | null} [existingLibraryItemId]
|
||||
* @returns {Promise<PodcastMetadataObject>}
|
||||
*/
|
||||
async getPodcastMetadataFromScanData(podcastEpisodes, libraryItemData, libraryScan, existingLibraryItemId = null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue