Fix:Changing author name not updating library item metadata files #3060

This commit is contained in:
advplyr 2024-06-27 16:32:38 -05:00
parent 8cadaa57f6
commit 56c0124c13
3 changed files with 106 additions and 13 deletions

View File

@ -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({

View File

@ -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

View File

@ -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