mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Update scanner to load library items from db
This commit is contained in:
		
							parent
							
								
									a98942a361
								
							
						
					
					
						commit
						1ebe8a6f4c
					
				| @ -486,6 +486,10 @@ class LibraryItem extends Model { | |||||||
|             } |             } | ||||||
|           ] |           ] | ||||||
|         } |         } | ||||||
|  |       ], | ||||||
|  |       order: [ | ||||||
|  |         [this.sequelize.models.book, this.sequelize.models.author, this.sequelize.models.bookAuthor, 'createdAt', 'ASC'], | ||||||
|  |         [this.sequelize.models.book, this.sequelize.models.series, 'bookSeries', 'createdAt', 'ASC'] | ||||||
|       ] |       ] | ||||||
|     }) |     }) | ||||||
|     if (!libraryItem) return null |     if (!libraryItem) return null | ||||||
| @ -735,6 +739,50 @@ class LibraryItem extends Model { | |||||||
|     return (await this.count({ where: { id: libraryItemId } })) > 0 |     return (await this.count({ where: { id: libraryItemId } })) > 0 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    *  | ||||||
|  |    * @param {WhereOptions} where  | ||||||
|  |    * @returns {Object} oldLibraryItem | ||||||
|  |    */ | ||||||
|  |   static async findOneOld(where) { | ||||||
|  |     const libraryItem = await this.findOne({ | ||||||
|  |       where, | ||||||
|  |       include: [ | ||||||
|  |         { | ||||||
|  |           model: this.sequelize.models.book, | ||||||
|  |           include: [ | ||||||
|  |             { | ||||||
|  |               model: this.sequelize.models.author, | ||||||
|  |               through: { | ||||||
|  |                 attributes: [] | ||||||
|  |               } | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               model: this.sequelize.models.series, | ||||||
|  |               through: { | ||||||
|  |                 attributes: ['sequence'] | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |           ] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           model: this.sequelize.models.podcast, | ||||||
|  |           include: [ | ||||||
|  |             { | ||||||
|  |               model: this.sequelize.models.podcastEpisode | ||||||
|  |             } | ||||||
|  |           ] | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       order: [ | ||||||
|  |         [this.sequelize.models.book, this.sequelize.models.author, this.sequelize.models.bookAuthor, 'createdAt', 'ASC'], | ||||||
|  |         [this.sequelize.models.book, this.sequelize.models.series, 'bookSeries', 'createdAt', 'ASC'] | ||||||
|  |       ] | ||||||
|  |     }) | ||||||
|  |     if (!libraryItem) return null | ||||||
|  |     return this.getOldLibraryItem(libraryItem) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   getMedia(options) { |   getMedia(options) { | ||||||
|     if (!this.mediaType) return Promise.resolve(null) |     if (!this.mediaType) return Promise.resolve(null) | ||||||
|     const mixinMethodName = `get${this.sequelize.uppercaseFirst(this.mediaType)}` |     const mixinMethodName = `get${this.sequelize.uppercaseFirst(this.mediaType)}` | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | const Sequelize = require('sequelize') | ||||||
| const fs = require('../libs/fsExtra') | const fs = require('../libs/fsExtra') | ||||||
| const Path = require('path') | const Path = require('path') | ||||||
| const Logger = require('../Logger') | const Logger = require('../Logger') | ||||||
| @ -589,28 +590,49 @@ class Scanner { | |||||||
|     //    Test Case: Moving audio files from library item folder to author folder should trigger a re-scan of the item
 |     //    Test Case: Moving audio files from library item folder to author folder should trigger a re-scan of the item
 | ||||||
|     const updateGroup = { ...fileUpdateGroup } |     const updateGroup = { ...fileUpdateGroup } | ||||||
|     for (const itemDir in updateGroup) { |     for (const itemDir in updateGroup) { | ||||||
|       if (itemDir == fileUpdateGroup[itemDir]) continue; // Media in root path
 |       if (itemDir == fileUpdateGroup[itemDir]) continue // Media in root path
 | ||||||
| 
 | 
 | ||||||
|       const itemDirNestedFiles = fileUpdateGroup[itemDir].filter(b => b.includes('/')) |       const itemDirNestedFiles = fileUpdateGroup[itemDir].filter(b => b.includes('/')) | ||||||
|       if (!itemDirNestedFiles.length) continue; |       if (!itemDirNestedFiles.length) continue | ||||||
| 
 | 
 | ||||||
|       const firstNest = itemDirNestedFiles[0].split('/').shift() |       const firstNest = itemDirNestedFiles[0].split('/').shift() | ||||||
|       const altDir = `${itemDir}/${firstNest}` |       const altDir = `${itemDir}/${firstNest}` | ||||||
| 
 | 
 | ||||||
|       const fullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), itemDir) |       const fullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), itemDir) | ||||||
|       const childLibraryItem = Database.libraryItems.find(li => li.path !== fullPath && li.path.startsWith(fullPath)) |       const childLibraryItem = await Database.models.libraryItem.findOne({ | ||||||
|  |         attributes: ['id', 'path'], | ||||||
|  |         where: { | ||||||
|  |           path: { | ||||||
|  |             [Sequelize.Op.not]: fullPath | ||||||
|  |           }, | ||||||
|  |           path: { | ||||||
|  |             [Sequelize.Op.startsWith]: fullPath | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|       if (!childLibraryItem) { |       if (!childLibraryItem) { | ||||||
|         continue |         continue | ||||||
|       } |       } | ||||||
|  | 
 | ||||||
|       const altFullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), altDir) |       const altFullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), altDir) | ||||||
|       const altChildLibraryItem = Database.libraryItems.find(li => li.path !== altFullPath && li.path.startsWith(altFullPath)) |       const altChildLibraryItem = await Database.models.libraryItem.findOne({ | ||||||
|  |         attributes: ['id', 'path'], | ||||||
|  |         where: { | ||||||
|  |           path: { | ||||||
|  |             [Sequelize.Op.not]: altFullPath | ||||||
|  |           }, | ||||||
|  |           path: { | ||||||
|  |             [Sequelize.Op.startsWith]: altFullPath | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|       if (altChildLibraryItem) { |       if (altChildLibraryItem) { | ||||||
|         continue |         continue | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       delete fileUpdateGroup[itemDir] |       delete fileUpdateGroup[itemDir] | ||||||
|       fileUpdateGroup[altDir] = itemDirNestedFiles.map((f) => f.split('/').slice(1).join('/')) |       fileUpdateGroup[altDir] = itemDirNestedFiles.map((f) => f.split('/').slice(1).join('/')) | ||||||
|       Logger.warn(`[Scanner] Some files were modified in a parent directory of a library item "${childLibraryItem.title}" - ignoring`) |       Logger.warn(`[Scanner] Some files were modified in a parent directory of a library item "${childLibraryItem.path}" - ignoring`) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Second pass: Check for new/updated/removed items
 |     // Second pass: Check for new/updated/removed items
 | ||||||
| @ -619,10 +641,21 @@ class Scanner { | |||||||
|       const fullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), itemDir) |       const fullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), itemDir) | ||||||
|       const dirIno = await getIno(fullPath) |       const dirIno = await getIno(fullPath) | ||||||
| 
 | 
 | ||||||
|  |       const itemDirParts = itemDir.split('/').slice(0, -1) | ||||||
|  |       const potentialChildDirs = [] | ||||||
|  |       for (let i = 0; i < itemDirParts.length; i++) { | ||||||
|  |         potentialChildDirs.push(Path.posix.join(filePathToPOSIX(folder.fullPath), itemDir.split('/').slice(0, -1 - i).join('/'))) | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       // Check if book dir group is already an item
 |       // Check if book dir group is already an item
 | ||||||
|       let existingLibraryItem = Database.libraryItems.find(li => fullPath.startsWith(li.path)) |       let existingLibraryItem = await Database.models.libraryItem.findOneOld({ | ||||||
|  |         path: potentialChildDirs | ||||||
|  |       }) | ||||||
|  | 
 | ||||||
|       if (!existingLibraryItem) { |       if (!existingLibraryItem) { | ||||||
|         existingLibraryItem = Database.libraryItems.find(li => li.ino === dirIno) |         existingLibraryItem = await Database.models.libraryItem.findOneOld({ | ||||||
|  |           ino: dirIno | ||||||
|  |         }) | ||||||
|         if (existingLibraryItem) { |         if (existingLibraryItem) { | ||||||
|           Logger.debug(`[Scanner] scanFolderUpdates: Library item found by inode value=${dirIno}. "${existingLibraryItem.relPath} => ${itemDir}"`) |           Logger.debug(`[Scanner] scanFolderUpdates: Library item found by inode value=${dirIno}. "${existingLibraryItem.relPath} => ${itemDir}"`) | ||||||
|           // Update library item paths for scan and all library item paths will get updated in LibraryItem.checkScanData
 |           // Update library item paths for scan and all library item paths will get updated in LibraryItem.checkScanData
 | ||||||
| @ -655,9 +688,16 @@ class Scanner { | |||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Check if a library item is a subdirectory of this dir
 |       // Check if a library item is a subdirectory of this dir
 | ||||||
|       var childItem = Database.libraryItems.find(li => (li.path + '/').startsWith(fullPath + '/')) |       const childItem = await Database.models.libraryItem.findOne({ | ||||||
|  |         attributes: ['id', 'path'], | ||||||
|  |         where: { | ||||||
|  |           path: { | ||||||
|  |             [Sequelize.Op.startsWith]: fullPath | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|       if (childItem) { |       if (childItem) { | ||||||
|         Logger.warn(`[Scanner] Files were modified in a parent directory of a library item "${childItem.media.metadata.title}" - ignoring`) |         Logger.warn(`[Scanner] Files were modified in a parent directory of a library item "${childItem.path}" - ignoring`) | ||||||
|         itemGroupingResults[itemDir] = ScanResult.NOTHING |         itemGroupingResults[itemDir] = ScanResult.NOTHING | ||||||
|         continue |         continue | ||||||
|       } |       } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user