mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-31 02:17:01 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			93 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const Path = require('path')
 | |
| const Logger = require('../../Logger')
 | |
| const fsExtra = require('../../libs/fsExtra')
 | |
| const fileUtils = require('../fileUtils')
 | |
| const LibraryFile = require('../../objects/files/LibraryFile')
 | |
| 
 | |
| /**
 | |
|  * 
 | |
|  * @param {import('../../models/LibraryItem')} libraryItem 
 | |
|  * @returns {Promise<boolean>} false if failed
 | |
|  */
 | |
| async function writeMetadataFileForItem(libraryItem) {
 | |
|   const storeMetadataWithItem = global.ServerSettings.storeMetadataWithItem && !libraryItem.isFile
 | |
|   const metadataPath = storeMetadataWithItem ? libraryItem.path : Path.join(global.MetadataPath, 'items', libraryItem.id)
 | |
|   const metadataFilepath = fileUtils.filePathToPOSIX(Path.join(metadataPath, 'metadata.json'))
 | |
|   if ((await fsExtra.pathExists(metadataFilepath))) {
 | |
|     // Metadata file already exists do nothing
 | |
|     return null
 | |
|   }
 | |
|   Logger.info(`[absMetadataMigration] metadata file not found at "${metadataFilepath}" - creating`)
 | |
| 
 | |
|   if (!storeMetadataWithItem) {
 | |
|     // Ensure /metadata/items/<lid> dir
 | |
|     await fsExtra.ensureDir(metadataPath)
 | |
|   }
 | |
| 
 | |
|   const metadataJson = libraryItem.media.getAbsMetadataJson()
 | |
| 
 | |
|   // Save to file
 | |
|   const success = await fsExtra.writeFile(metadataFilepath, JSON.stringify(metadataJson, null, 2)).then(() => true).catch((error) => {
 | |
|     Logger.error(`[absMetadataMigration] failed to save metadata file at "${metadataFilepath}"`, error.message || error)
 | |
|     return false
 | |
|   })
 | |
| 
 | |
|   if (!success) return false
 | |
|   if (!storeMetadataWithItem) return true // No need to do anything else
 | |
| 
 | |
|   // Safety check to make sure library file with the same path isnt already there
 | |
|   libraryItem.libraryFiles = libraryItem.libraryFiles.filter(lf => lf.metadata.path !== metadataFilepath)
 | |
| 
 | |
|   // Put new library file in library item
 | |
|   const newLibraryFile = new LibraryFile()
 | |
|   await newLibraryFile.setDataFromPath(metadataFilepath, 'metadata.json')
 | |
|   libraryItem.libraryFiles.push(newLibraryFile.toJSON())
 | |
| 
 | |
|   // Update library item timestamps and total size
 | |
|   const libraryItemDirTimestamps = await fileUtils.getFileTimestampsWithIno(libraryItem.path)
 | |
|   if (libraryItemDirTimestamps) {
 | |
|     libraryItem.mtime = libraryItemDirTimestamps.mtimeMs
 | |
|     libraryItem.ctime = libraryItemDirTimestamps.ctimeMs
 | |
|     let size = 0
 | |
|     libraryItem.libraryFiles.forEach((lf) => size += (!isNaN(lf.metadata.size) ? Number(lf.metadata.size) : 0))
 | |
|     libraryItem.size = size
 | |
|   }
 | |
| 
 | |
|   libraryItem.changed('libraryFiles', true)
 | |
|   return libraryItem.save().then(() => true).catch((error) => {
 | |
|     Logger.error(`[absMetadataMigration] failed to save libraryItem "${libraryItem.id}"`, error.message || error)
 | |
|     return false
 | |
|   })
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 
 | |
|  * @param {import('../../Database')} Database 
 | |
|  * @param {number} [offset=0]
 | |
|  * @param {number} [totalCreated=0]
 | |
|  */
 | |
| async function runMigration(Database, offset = 0, totalCreated = 0) {
 | |
|   const libraryItems = await Database.libraryItemModel.getLibraryItemsIncrement(offset, 500, { isMissing: false })
 | |
|   if (!libraryItems.length) return totalCreated
 | |
| 
 | |
|   let numCreated = 0
 | |
|   for (const libraryItem of libraryItems) {
 | |
|     const success = await writeMetadataFileForItem(libraryItem)
 | |
|     if (success) numCreated++
 | |
|   }
 | |
| 
 | |
|   if (libraryItems.length < 500) {
 | |
|     return totalCreated + numCreated
 | |
|   }
 | |
|   return runMigration(Database, offset + libraryItems.length, totalCreated + numCreated)
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 
 | |
|  * @param {import('../../Database')} Database 
 | |
|  */
 | |
| module.exports.migrate = async (Database) => {
 | |
|   Logger.info(`[absMetadataMigration] Starting metadata.json migration`)
 | |
|   const totalCreated = await runMigration(Database)
 | |
|   Logger.info(`[absMetadataMigration] Finished metadata.json migration (${totalCreated} files created)`)
 | |
| } |