mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-03-03 22:49:42 +00:00
feat: add library-wide consolidation status update tool and improve consolidation robustness
This commit is contained in:
parent
2c77f1fc5a
commit
c2693e2460
8 changed files with 118 additions and 11 deletions
|
|
@ -1374,6 +1374,39 @@ class LibraryController {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* POST: /api/libraries/:id/update-consolidation
|
||||
* Update isNotConsolidated flag for all items in library
|
||||
*
|
||||
* @param {LibraryControllerRequest} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateConsolidationStatus(req, res) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-admin user "${req.user.username}" attempted to update consolidation status`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
const items = await Database.libraryItemModel.findAllExpandedWhere({
|
||||
libraryId: req.library.id
|
||||
})
|
||||
|
||||
let updatedCount = 0
|
||||
for (const item of items) {
|
||||
const isNotConsolidated = item.checkIsNotConsolidated()
|
||||
if (item.isNotConsolidated !== isNotConsolidated) {
|
||||
item.isNotConsolidated = isNotConsolidated
|
||||
await item.save()
|
||||
updatedCount++
|
||||
}
|
||||
}
|
||||
|
||||
Logger.info(`[LibraryController] Updated consolidation status for ${updatedCount} items in library "${req.library.name}"`)
|
||||
res.json({
|
||||
updated: updatedCount
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* GET: /api/libraries/:id/podcast-titles
|
||||
*
|
||||
|
|
|
|||
|
|
@ -58,19 +58,22 @@ async function handleMoveLibraryItem(libraryItem, targetLibrary, targetFolder, n
|
|||
|
||||
// Check if destination already exists
|
||||
const destinationExists = await fs.pathExists(newPath)
|
||||
if (destinationExists) {
|
||||
const isSamePath = oldPath === newPath
|
||||
if (destinationExists && !isSamePath) {
|
||||
throw new Error(`Destination already exists: ${newPath}`)
|
||||
}
|
||||
|
||||
try {
|
||||
Watcher.addIgnoreDir(oldPath)
|
||||
Watcher.addIgnoreDir(newPath)
|
||||
if (!isSamePath) Watcher.addIgnoreDir(newPath)
|
||||
|
||||
const oldRelPath = libraryItem.relPath
|
||||
|
||||
// Move files on disk
|
||||
Logger.info(`[LibraryItemController] Moving item "${libraryItem.media.title}" from "${oldPath}" to "${newPath}"`)
|
||||
await fs.move(oldPath, newPath)
|
||||
if (!isSamePath) {
|
||||
Logger.info(`[LibraryItemController] Moving item "${libraryItem.media.title}" from "${oldPath}" to "${newPath}"`)
|
||||
await fs.move(oldPath, newPath)
|
||||
}
|
||||
|
||||
// Update database within a transaction
|
||||
const transaction = await Database.sequelize.transaction()
|
||||
|
|
@ -276,7 +279,7 @@ async function handleMoveLibraryItem(libraryItem, targetLibrary, targetFolder, n
|
|||
throw error
|
||||
} finally {
|
||||
Watcher.removeIgnoreDir(oldPath)
|
||||
Watcher.removeIgnoreDir(newPath)
|
||||
if (typeof isSamePath !== 'undefined' && !isSamePath) Watcher.removeIgnoreDir(newPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -927,7 +927,12 @@ class LibraryItem extends Model {
|
|||
const title = this.title || 'Unknown Title'
|
||||
const folderName = LibraryItem.getConsolidatedFolderName(author, title)
|
||||
const currentFolderName = Path.basename(this.path.replace(/[\/\\]$/, ''))
|
||||
return currentFolderName !== folderName
|
||||
if (currentFolderName !== folderName) return true
|
||||
|
||||
// Check if it is in a subfolder
|
||||
const relPathPOSIX = (this.relPath || '').replace(/\\/g, '/')
|
||||
const cleanRelPath = relPathPOSIX.replace(/\/$/, '')
|
||||
return cleanRelPath !== currentFolderName
|
||||
}
|
||||
|
||||
static getConsolidatedFolderName(author, title) {
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ class ApiRouter {
|
|||
this.router.get('/libraries/:id/opml', LibraryController.middleware.bind(this), LibraryController.getOPMLFile.bind(this))
|
||||
this.router.post('/libraries/order', LibraryController.reorder.bind(this))
|
||||
this.router.post('/libraries/:id/remove-metadata', LibraryController.middleware.bind(this), LibraryController.removeAllMetadataFiles.bind(this))
|
||||
this.router.post('/libraries/:id/update-consolidation', LibraryController.middleware.bind(this), LibraryController.updateConsolidationStatus.bind(this))
|
||||
this.router.get('/libraries/:id/podcast-titles', LibraryController.middleware.bind(this), LibraryController.getPodcastTitles.bind(this))
|
||||
this.router.get('/libraries/:id/download', LibraryController.middleware.bind(this), LibraryController.downloadMultiple.bind(this))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue