From 6cbfd8679b66016472eed5219852ef01a4370272 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 24 Jul 2022 12:00:36 -0500 Subject: [PATCH] Update:Changing author name to match another authors name will merge the authors #487 --- .../components/modals/authors/EditModal.vue | 3 + server/controllers/AuthorController.js | 72 +++++++++++++------ server/objects/metadata/BookMetadata.js | 8 +++ 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/client/components/modals/authors/EditModal.vue b/client/components/modals/authors/EditModal.vue index 84c20399..2a6bd5ea 100644 --- a/client/components/modals/authors/EditModal.vue +++ b/client/components/modals/authors/EditModal.vue @@ -116,6 +116,9 @@ export default { if (result.updated) { this.$toast.success('Author updated') this.show = false + } else if (result.merged) { + this.$toast.success('Author merged') + this.show = false } else this.$toast.info('No updates were needed') } this.processing = false diff --git a/server/controllers/AuthorController.js b/server/controllers/AuthorController.js index 419f2477..856e20ab 100644 --- a/server/controllers/AuthorController.js +++ b/server/controllers/AuthorController.js @@ -82,31 +82,59 @@ class AuthorController { var authorNameUpdate = payload.name !== undefined && payload.name !== req.author.name - var hasUpdated = req.author.update(payload) - - if (hasUpdated) { - if (authorNameUpdate) { // Update author name on all books - var itemsWithAuthor = this.db.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasAuthor(req.author.id)) - itemsWithAuthor.forEach(libraryItem => { - libraryItem.media.metadata.updateAuthor(req.author) - }) - if (itemsWithAuthor.length) { - await this.db.updateLibraryItems(itemsWithAuthor) - this.emitter('items_updated', itemsWithAuthor.map(li => li.toJSONExpanded())) - } + // Check if author name matches another author and merge the authors + var existingAuthor = authorNameUpdate ? this.db.authors.find(au => au.id !== req.author.id && payload.name === au.name) : false + if (existingAuthor) { + var itemsWithAuthor = this.db.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasAuthor(req.author.id)) + itemsWithAuthor.forEach(libraryItem => { // Replace old author with merging author for each book + libraryItem.media.metadata.replaceAuthor(req.author, existingAuthor) + }) + if (itemsWithAuthor.length) { + await this.db.updateLibraryItems(itemsWithAuthor) + this.emitter('items_updated', itemsWithAuthor.map(li => li.toJSONExpanded())) } - await this.db.updateEntity('author', req.author) - var numBooks = this.db.libraryItems.filter(li => { - return li.media.metadata.hasAuthor && li.media.metadata.hasAuthor(req.author.id) - }).length - this.emitter('author_updated', req.author.toJSONExpanded(numBooks)) - } + // Remove old author + await this.db.removeEntity('author', req.author.id) + this.emitter('author_removed', req.author.toJSON()) - res.json({ - author: req.author.toJSON(), - updated: hasUpdated - }) + // Send updated num books for merged author + var numBooks = this.db.libraryItems.filter(li => { + return li.media.metadata.hasAuthor && li.media.metadata.hasAuthor(existingAuthor.id) + }).length + this.emitter('author_updated', existingAuthor.toJSONExpanded(numBooks)) + + res.json({ + author: existingAuthor.toJSON(), + merged: true + }) + } else { // Regular author update + var hasUpdated = req.author.update(payload) + + if (hasUpdated) { + if (authorNameUpdate) { // Update author name on all books + var itemsWithAuthor = this.db.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasAuthor(req.author.id)) + itemsWithAuthor.forEach(libraryItem => { + libraryItem.media.metadata.updateAuthor(req.author) + }) + if (itemsWithAuthor.length) { + await this.db.updateLibraryItems(itemsWithAuthor) + this.emitter('items_updated', itemsWithAuthor.map(li => li.toJSONExpanded())) + } + } + + await this.db.updateEntity('author', req.author) + var numBooks = this.db.libraryItems.filter(li => { + return li.media.metadata.hasAuthor && li.media.metadata.hasAuthor(req.author.id) + }).length + this.emitter('author_updated', req.author.toJSONExpanded(numBooks)) + } + + res.json({ + author: req.author.toJSON(), + updated: hasUpdated + }) + } } async search(req, res) { diff --git a/server/objects/metadata/BookMetadata.js b/server/objects/metadata/BookMetadata.js index 19ee3aa6..9a4a1db6 100644 --- a/server/objects/metadata/BookMetadata.js +++ b/server/objects/metadata/BookMetadata.js @@ -191,6 +191,14 @@ class BookMetadata { return true } + replaceAuthor(oldAuthor, newAuthor) { + this.authors = this.authors.filter(au => au.id !== oldAuthor.id) // Remove old author + this.authors.push({ + id: newAuthor.id, + name: newAuthor.name + }) + } + setData(scanMediaData = {}) { this.title = scanMediaData.title || null this.subtitle = scanMediaData.subtitle || null