mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-03 00:06:46 +01:00
Fix:Changing author name not updating library item metadata files #3060
This commit is contained in:
parent
8cadaa57f6
commit
56c0124c13
@ -62,6 +62,11 @@ class AuthorController {
|
|||||||
return res.json(authorJson)
|
return res.json(authorJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {import('express').Request} req
|
||||||
|
* @param {import('express').Response} res
|
||||||
|
*/
|
||||||
async update(req, res) {
|
async update(req, res) {
|
||||||
const payload = req.body
|
const payload = req.body
|
||||||
let hasUpdated = false
|
let hasUpdated = false
|
||||||
@ -88,22 +93,36 @@ class AuthorController {
|
|||||||
existingAuthor = author?.getOldAuthor()
|
existingAuthor = author?.getOldAuthor()
|
||||||
}
|
}
|
||||||
if (existingAuthor) {
|
if (existingAuthor) {
|
||||||
|
Logger.info(`[AuthorController] Merging author "${req.author.name}" with "${existingAuthor.name}"`)
|
||||||
const bookAuthorsToCreate = []
|
const bookAuthorsToCreate = []
|
||||||
const itemsWithAuthor = await Database.libraryItemModel.getForAuthor(req.author)
|
const allItemsWithAuthor = await Database.authorModel.getAllLibraryItemsForAuthor(req.author.id)
|
||||||
itemsWithAuthor.forEach((libraryItem) => {
|
|
||||||
|
const oldLibraryItems = []
|
||||||
|
allItemsWithAuthor.forEach((libraryItem) => {
|
||||||
// Replace old author with merging author for each book
|
// Replace old author with merging author for each book
|
||||||
libraryItem.media.metadata.replaceAuthor(req.author, existingAuthor)
|
libraryItem.media.authors = libraryItem.media.authors.filter((au) => au.id !== req.author.id)
|
||||||
|
libraryItem.media.authors.push({
|
||||||
|
id: existingAuthor.id,
|
||||||
|
name: existingAuthor.name
|
||||||
|
})
|
||||||
|
|
||||||
|
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
||||||
|
oldLibraryItems.push(oldLibraryItem)
|
||||||
|
|
||||||
bookAuthorsToCreate.push({
|
bookAuthorsToCreate.push({
|
||||||
bookId: libraryItem.media.id,
|
bookId: libraryItem.media.id,
|
||||||
authorId: existingAuthor.id
|
authorId: existingAuthor.id
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if (itemsWithAuthor.length) {
|
if (oldLibraryItems.length) {
|
||||||
await Database.removeBulkBookAuthors(req.author.id) // Remove all old BookAuthor
|
await Database.removeBulkBookAuthors(req.author.id) // Remove all old BookAuthor
|
||||||
await Database.createBulkBookAuthors(bookAuthorsToCreate) // Create all new BookAuthor
|
await Database.createBulkBookAuthors(bookAuthorsToCreate) // Create all new BookAuthor
|
||||||
|
for (const libraryItem of allItemsWithAuthor) {
|
||||||
|
await libraryItem.saveMetadataFile()
|
||||||
|
}
|
||||||
SocketAuthority.emitter(
|
SocketAuthority.emitter(
|
||||||
'items_updated',
|
'items_updated',
|
||||||
itemsWithAuthor.map((li) => li.toJSONExpanded())
|
oldLibraryItems.map((li) => li.toJSONExpanded())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +133,7 @@ class AuthorController {
|
|||||||
Database.removeAuthorFromFilterData(req.author.libraryId, req.author.id)
|
Database.removeAuthorFromFilterData(req.author.libraryId, req.author.id)
|
||||||
|
|
||||||
// Send updated num books for merged author
|
// Send updated num books for merged author
|
||||||
const numBooks = (await Database.libraryItemModel.getForAuthor(existingAuthor)).length
|
const numBooks = await Database.bookAuthorModel.getCountForAuthor(existingAuthor.id)
|
||||||
SocketAuthority.emitter('author_updated', existingAuthor.toJSONExpanded(numBooks))
|
SocketAuthority.emitter('author_updated', existingAuthor.toJSONExpanded(numBooks))
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
@ -130,22 +149,38 @@ class AuthorController {
|
|||||||
if (hasUpdated) {
|
if (hasUpdated) {
|
||||||
req.author.updatedAt = Date.now()
|
req.author.updatedAt = Date.now()
|
||||||
|
|
||||||
const itemsWithAuthor = await Database.libraryItemModel.getForAuthor(req.author)
|
let numBooksForAuthor = 0
|
||||||
if (authorNameUpdate) {
|
if (authorNameUpdate) {
|
||||||
|
const allItemsWithAuthor = await Database.authorModel.getAllLibraryItemsForAuthor(req.author.id)
|
||||||
|
|
||||||
|
numBooksForAuthor = allItemsWithAuthor.length
|
||||||
|
const oldLibraryItems = []
|
||||||
// Update author name on all books
|
// Update author name on all books
|
||||||
itemsWithAuthor.forEach((libraryItem) => {
|
for (const libraryItem of allItemsWithAuthor) {
|
||||||
libraryItem.media.metadata.updateAuthor(req.author)
|
libraryItem.media.authors = libraryItem.media.authors.map((au) => {
|
||||||
})
|
if (au.id === req.author.id) {
|
||||||
if (itemsWithAuthor.length) {
|
au.name = req.author.name
|
||||||
|
}
|
||||||
|
return au
|
||||||
|
})
|
||||||
|
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
||||||
|
oldLibraryItems.push(oldLibraryItem)
|
||||||
|
|
||||||
|
await libraryItem.saveMetadataFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldLibraryItems.length) {
|
||||||
SocketAuthority.emitter(
|
SocketAuthority.emitter(
|
||||||
'items_updated',
|
'items_updated',
|
||||||
itemsWithAuthor.map((li) => li.toJSONExpanded())
|
oldLibraryItems.map((li) => li.toJSONExpanded())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
numBooksForAuthor = await Database.bookAuthorModel.getCountForAuthor(req.author.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
await Database.updateAuthor(req.author)
|
await Database.updateAuthor(req.author)
|
||||||
SocketAuthority.emitter('author_updated', req.author.toJSONExpanded(itemsWithAuthor.length))
|
SocketAuthority.emitter('author_updated', req.author.toJSONExpanded(numBooksForAuthor))
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
|
@ -120,6 +120,50 @@ class Author extends Model {
|
|||||||
return author
|
return author
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} authorId
|
||||||
|
* @returns {Promise<import('./LibraryItem')[]>}
|
||||||
|
*/
|
||||||
|
static async getAllLibraryItemsForAuthor(authorId) {
|
||||||
|
const author = await this.findByPk(authorId, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: this.sequelize.models.book,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: this.sequelize.models.libraryItem
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: this.sequelize.models.author,
|
||||||
|
through: {
|
||||||
|
attributes: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: this.sequelize.models.series,
|
||||||
|
through: {
|
||||||
|
attributes: ['sequence']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const libraryItems = []
|
||||||
|
if (author.books) {
|
||||||
|
for (const book of author.books) {
|
||||||
|
const libraryItem = book.libraryItem
|
||||||
|
libraryItem.media = book
|
||||||
|
delete book.libraryItem
|
||||||
|
libraryItems.push(libraryItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return libraryItems
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize model
|
* Initialize model
|
||||||
* @param {import('../Database').sequelize} sequelize
|
* @param {import('../Database').sequelize} sequelize
|
||||||
|
@ -23,6 +23,20 @@ class BookAuthor extends Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get number of books for author
|
||||||
|
*
|
||||||
|
* @param {string} authorId
|
||||||
|
* @returns {Promise<number>}
|
||||||
|
*/
|
||||||
|
static getCountForAuthor(authorId) {
|
||||||
|
return this.count({
|
||||||
|
where: {
|
||||||
|
authorId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize model
|
* Initialize model
|
||||||
* @param {import('../Database').sequelize} sequelize
|
* @param {import('../Database').sequelize} sequelize
|
||||||
|
Loading…
Reference in New Issue
Block a user