Update:Match author use closest name match by levenshtein distance #2624

This commit is contained in:
advplyr 2024-02-18 13:06:51 -06:00
parent 58598bfcf2
commit acf75abdf1
2 changed files with 56 additions and 8 deletions

View file

@ -2,15 +2,30 @@ const axios = require('axios')
const { levenshteinDistance } = require('../utils/index')
const Logger = require('../Logger')
/**
* @typedef AuthorSearchObj
* @property {string} asin
* @property {string} description
* @property {string} image
* @property {string} name
*/
class Audnexus {
constructor() {
this.baseUrl = 'https://api.audnex.us'
}
/**
*
* @param {string} name
* @param {string} region
* @returns {Promise<{asin:string, name:string}[]>}
*/
authorASINsRequest(name, region) {
name = encodeURIComponent(name)
const regionQuery = region ? `&region=${region}` : ''
const authorRequestUrl = `${this.baseUrl}/authors?name=${name}${regionQuery}`
const searchParams = new URLSearchParams()
searchParams.set('name', name)
if (region) searchParams.set('region', region)
const authorRequestUrl = `${this.baseUrl}/authors?${searchParams.toString()}`
Logger.info(`[Audnexus] Searching for author "${authorRequestUrl}"`)
return axios.get(authorRequestUrl).then((res) => {
return res.data || []
@ -20,6 +35,12 @@ class Audnexus {
})
}
/**
*
* @param {string} asin
* @param {string} region
* @returns {Promise<AuthorSearchObj>}
*/
authorRequest(asin, region) {
asin = encodeURIComponent(asin)
const regionQuery = region ? `?region=${region}` : ''
@ -33,6 +54,12 @@ class Audnexus {
})
}
/**
*
* @param {string} asin
* @param {string} region
* @returns {Promise<AuthorSearchObj>}
*/
async findAuthorByASIN(asin, region) {
const author = await this.authorRequest(asin, region)
if (!author) {
@ -46,14 +73,28 @@ class Audnexus {
}
}
/**
*
* @param {string} name
* @param {string} region
* @param {number} maxLevenshtein
* @returns {Promise<AuthorSearchObj>}
*/
async findAuthorByName(name, region, maxLevenshtein = 3) {
Logger.debug(`[Audnexus] Looking up author by name ${name}`)
const asins = await this.authorASINsRequest(name, region)
const matchingAsin = asins.find(obj => levenshteinDistance(obj.name, name) <= maxLevenshtein)
if (!matchingAsin) {
const authorAsinObjs = await this.authorASINsRequest(name, region)
let closestMatch = null
authorAsinObjs.forEach((authorAsinObj) => {
authorAsinObj.levenshteinDistance = levenshteinDistance(authorAsinObj.name, name)
if (!closestMatch || closestMatch.levenshteinDistance > authorAsinObj.levenshteinDistance) {
closestMatch = authorAsinObj
}
})
if (!closestMatch || closestMatch.levenshteinDistance > maxLevenshtein) {
return null
}
const author = await this.authorRequest(matchingAsin.asin)
const author = await this.authorRequest(closestMatch.asin)
if (!author) {
return null
}