Update:Matching authors uses the ASIN if set #572, Fix:Purge author image cache when updating author

This commit is contained in:
advplyr 2022-05-13 18:11:54 -05:00
parent eaa383b6d8
commit f78d287b59
7 changed files with 43 additions and 79 deletions

View File

@ -65,6 +65,9 @@ export default {
name() { name() {
return this._author.name || '' return this._author.name || ''
}, },
asin() {
return this._author.asin || ''
},
numBooks() { numBooks() {
return this._author.numBooks || 0 return this._author.numBooks || 0
}, },
@ -81,7 +84,11 @@ export default {
}, },
async searchAuthor() { async searchAuthor() {
this.searching = true this.searching = true
var response = await this.$axios.$post(`/api/authors/${this.authorId}/match`, { q: this.name }).catch((error) => { const payload = {}
if (this.asin) payload.asin = this.asin
else payload.q = this.name
var response = await this.$axios.$post(`/api/authors/${this.authorId}/match`, payload).catch((error) => {
console.error('Failed', error) console.error('Failed', error)
return null return null
}) })

View File

@ -1,73 +0,0 @@
<template>
<div>
<form @submit.prevent="submitSearch">
<div class="flex items-center justify-start -mx-1 h-20">
<!-- <div class="w-40 px-1">
<ui-dropdown v-model="provider" :items="providers" label="Provider" small />
</div> -->
<div class="flex-grow px-1">
<ui-text-input-with-label v-model="searchAuthor" label="Author" />
</div>
<ui-btn class="mt-5 ml-1" type="submit">Search</ui-btn>
</div>
</form>
</div>
</template>
<script>
export default {
props: {
authorName: String
},
data() {
return {
searchAuthor: null,
lastSearch: null,
isProcessing: false,
provider: 'audnexus',
providers: [
{
text: 'Audnexus',
value: 'audnexus'
}
]
}
},
watch: {
authorName: {
immediate: true,
handler(newVal) {
this.searchAuthor = newVal
}
}
},
computed: {},
methods: {
getSearchQuery() {
return `q=${this.searchAuthor}`
},
submitSearch() {
if (!this.searchAuthor) {
this.$toast.warning('Author name is required')
return
}
this.runSearch()
},
async runSearch() {
var searchQuery = this.getSearchQuery()
if (this.lastSearch === searchQuery) return
this.isProcessing = true
this.lastSearch = searchQuery
var result = await this.$axios.$get(`/api/authors/search?${searchQuery}`).catch((error) => {
console.error('Failed', error)
return []
})
this.isProcessing = false
if (result) {
this.$emit('match', result)
}
}
},
mounted() {}
}
</script>

View File

@ -139,12 +139,17 @@ export default {
this.processing = false this.processing = false
}, },
async searchAuthor() { async searchAuthor() {
if (!this.authorCopy.name) { if (!this.authorCopy.name && !this.authorCopy.asin) {
this.$toast.error('Must enter an author name') this.$toast.error('Must enter an author name')
return return
} }
this.processing = true this.processing = true
var response = await this.$axios.$post(`/api/authors/${this.authorId}/match`, { q: this.authorCopy.name }).catch((error) => {
const payload = {}
if (this.authorCopy.asin) payload.asin = this.authorCopy.asin
else payload.q = this.authorCopy.name
var response = await this.$axios.$post(`/api/authors/${this.authorId}/match`, payload).catch((error) => {
console.error('Failed', error) console.error('Failed', error)
return null return null
}) })

View File

@ -107,11 +107,16 @@ class AuthorController {
} }
async match(req, res) { async match(req, res) {
var authorData = await this.authorFinder.findAuthorByName(req.body.q) var authorData = null
if (req.body.asin) {
authorData = await this.authorFinder.findAuthorByASIN(req.body.asin)
} else {
authorData = await this.authorFinder.findAuthorByName(req.body.q)
}
if (!authorData) { if (!authorData) {
return res.status(404).send('Author not found') return res.status(404).send('Author not found')
} }
Logger.debug(`[AuthorController] match author with "${req.body.q}"`, authorData) Logger.debug(`[AuthorController] match author with "${req.body.q || req.body.asin}"`, authorData)
var hasUpdates = false var hasUpdates = false
if (authorData.asin && req.author.asin !== authorData.asin) { if (authorData.asin && req.author.asin !== authorData.asin) {
@ -121,6 +126,8 @@ class AuthorController {
// Only updates image if there was no image before or the author ASIN was updated // Only updates image if there was no image before or the author ASIN was updated
if (authorData.image && (!req.author.imagePath || hasUpdates)) { if (authorData.image && (!req.author.imagePath || hasUpdates)) {
this.cacheManager.purgeImageCache(req.author.id)
var imageData = await this.authorFinder.saveAuthorImage(req.author.id, authorData.image) var imageData = await this.authorFinder.saveAuthorImage(req.author.id, authorData.image)
if (imageData) { if (imageData) {
req.author.imagePath = imageData.path req.author.imagePath = imageData.path

View File

@ -19,6 +19,11 @@ class AuthorFinder {
}) })
} }
findAuthorByASIN(asin) {
if (!asin) return null
return this.audnexus.findAuthorByASIN(asin)
}
async findAuthorByName(name, options = {}) { async findAuthorByName(name, options = {}) {
if (!name) return null if (!name) return null
const maxLevenshtein = !isNaN(options.maxLevenshtein) ? Number(options.maxLevenshtein) : 3 const maxLevenshtein = !isNaN(options.maxLevenshtein) ? Number(options.maxLevenshtein) : 3

View File

@ -37,7 +37,7 @@ class Author {
imagePath: this.imagePath, imagePath: this.imagePath,
relImagePath: this.relImagePath, relImagePath: this.relImagePath,
addedAt: this.addedAt, addedAt: this.addedAt,
lastUpdate: this.updatedAt updatedAt: this.updatedAt
} }
} }

View File

@ -27,6 +27,19 @@ class Audnexus {
}) })
} }
async findAuthorByASIN(asin) {
var author = await this.authorRequest(asin)
if (!author) {
return null
}
return {
asin: author.asin,
description: author.description,
image: author.image,
name: author.name
}
}
async findAuthorByName(name, maxLevenshtein = 3) { async findAuthorByName(name, maxLevenshtein = 3) {
Logger.debug(`[Audnexus] Looking up author by name ${name}`) Logger.debug(`[Audnexus] Looking up author by name ${name}`)
var asins = await this.authorASINsRequest(name) var asins = await this.authorASINsRequest(name)