From ae8046823f11a18ee51b51a39f2ace58a7c7c949 Mon Sep 17 00:00:00 2001 From: Keagan Hilliard Date: Sun, 21 Nov 2021 10:59:32 -0800 Subject: [PATCH 1/2] Added support for audible metadata --- client/components/modals/edit-tabs/Match.vue | 30 +++++++++++- package.json | 1 + server/BookFinder.js | 11 +++++ server/providers/Audible.js | 51 ++++++++++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 server/providers/Audible.js diff --git a/client/components/modals/edit-tabs/Match.vue b/client/components/modals/edit-tabs/Match.vue index d2f5ab13..0cb932a2 100644 --- a/client/components/modals/edit-tabs/Match.vue +++ b/client/components/modals/edit-tabs/Match.vue @@ -49,6 +49,10 @@ +
+ + +
@@ -65,6 +69,18 @@
+
+ + +
+
+ + +
+
Update
@@ -96,6 +112,10 @@ export default { { text: 'Open Library', value: 'openlibrary' + }, + { + text: 'Audible', + value: 'audible' } ], provider: 'google', @@ -107,10 +127,13 @@ export default { subtitle: true, cover: true, author: true, + narrator: true, description: true, isbn: true, publisher: true, - publishYear: true + publishYear: true, + series: true, + volumeNumber: true, } } }, @@ -169,10 +192,13 @@ export default { subtitle: true, cover: true, author: true, + narrator: true, description: true, isbn: true, publisher: true, - publishYear: true + publishYear: true, + series: true, + volumeNumber: true, } if (this.audiobook.id !== this.audiobookId) { diff --git a/package.json b/package.json index ab579d13..5fb3a3fc 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "read-chunk": "^3.1.0", "recursive-readdir-async": "^1.1.8", "socket.io": "^4.1.3", + "string-strip-html": "^8.3.0", "watcher": "^1.2.0", "xml2js": "^0.4.23" }, diff --git a/server/BookFinder.js b/server/BookFinder.js index acf00b20..538ae377 100644 --- a/server/BookFinder.js +++ b/server/BookFinder.js @@ -1,6 +1,7 @@ const OpenLibrary = require('./providers/OpenLibrary') const LibGen = require('./providers/LibGen') const GoogleBooks = require('./providers/GoogleBooks') +const Audible = require('./providers/Audible') const Logger = require('./Logger') const { levenshteinDistance } = require('./utils/index') @@ -9,6 +10,7 @@ class BookFinder { this.openLibrary = new OpenLibrary() this.libGen = new LibGen() this.googleBooks = new GoogleBooks() + this.audible = new Audible() this.verbose = false } @@ -156,6 +158,13 @@ class BookFinder { return books } + async getAudibleResults(title, author, maxTitleDistance, maxAuthorDistance) { + var books = await this.audible.search(title, author); + if (this.verbose) Logger.debug(`Audible Book Search Results: ${books.length || 0}`) + if (!books) return [] + return books + } + async search(provider, title, author, options = {}) { var books = [] var maxTitleDistance = !isNaN(options.titleDistance) ? Number(options.titleDistance) : 4 @@ -164,6 +173,8 @@ class BookFinder { if (provider === 'google') { return this.getGoogleBooksResults(title, author, maxTitleDistance, maxAuthorDistance) + } else if (provider === 'audible') { + return this.getAudibleResults(title, author, maxTitleDistance, maxAuthorDistance) } else if (provider === 'libgen') { books = await this.getLibGenResults(title, author, maxTitleDistance, maxAuthorDistance) } else if (provider === 'openlibrary') { diff --git a/server/providers/Audible.js b/server/providers/Audible.js new file mode 100644 index 00000000..9138ce22 --- /dev/null +++ b/server/providers/Audible.js @@ -0,0 +1,51 @@ +const axios = require('axios') +const {stripHtml} = require('string-strip-html') +const Logger = require('../Logger') + +class Audible { + constructor() { } + + cleanResult(item) { + var { title, subtitle, asin, authors, narrators, publisher_name, publisher_summary, release_date, series, product_images } = item; + + var firstSeries = series && series.length > 0 ? series[0] : null; + + return { + title, + subtitle: subtitle || null, + author: authors ? authors.map(({ name }) => name).join(', ') : null, + narrator: narrators ? narrators.map(({ name }) => name).join(', ') : null, + publisher: publisher_name, + publishYear: release_date ? release_date.split('-')[0] : null, + description: stripHtml(publisher_summary).result, + cover: this.getBestImageLink(product_images), + asin, + series: firstSeries ? firstSeries.title : null, + volumeNumber: firstSeries ? firstSeries.sequence : null + } + } + + getBestImageLink(images) { + var keys = Object.keys(images); + return images[keys[keys.length - 1]]; + } + + async search(title, author) { + var queryString = `response_groups=rating,series,contributors,product_desc,media,product_extended_attrs` + + `&image_sizes=500,1024,2000&num_results=25&products_sort_by=Relevance&title=${title}`; + if (author) queryString += `&author=${author}` + var url = `https://api.audible.com/1.0/catalog/products?${queryString}` + Logger.debug(`[Audible] Search url: ${url}`) + var items = await axios.get(url).then((res) => { + if (!res || !res.data || !res.data.products) return [] + return res.data.products + }).catch(error => { + Logger.error('[Audible] search error', error) + return [] + }) + Logger.debug(JSON.stringify(items.map(item => this.cleanResult(item)))) + return items.map(item => this.cleanResult(item)) + } +} + +module.exports = Audible \ No newline at end of file From d2503143ecfedecf728be6fac86af32192dad8b6 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 21 Nov 2021 15:28:57 -0600 Subject: [PATCH 2/2] Removing debug log --- package-lock.json | 114 +++++++++++++++++++++++++++++++++++- package.json | 2 +- server/providers/Audible.js | 3 +- 3 files changed, 115 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4cec1e7..1e880a98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,17 @@ { "name": "audiobookshelf", - "version": "1.6.21", + "version": "1.6.23", "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/runtime": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz", + "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, "@sindresorhus/is": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", @@ -812,6 +820,11 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "optional": true }, + "html-entities": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", + "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==" + }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -1024,6 +1037,11 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -1074,11 +1092,21 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "lodash.trim": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", + "integrity": "sha1-NkJefukL5KpeJ7zruFt9EepHqlc=" + }, "lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" }, + "lodash.without": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.without/-/lodash.without-4.4.0.tgz", + "integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=" + }, "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -1468,6 +1496,44 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, + "ranges-apply": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ranges-apply/-/ranges-apply-5.1.0.tgz", + "integrity": "sha512-VF3a0XUuYS/BQHv2RaIyX1K7S1hbfrs64hkGKgPVk0Y7p4XFwSucjTTttrBqmkcmB/PZx5ISTZdxErRZi/89aQ==", + "requires": { + "@babel/runtime": "^7.14.0", + "ranges-merge": "^7.1.0" + } + }, + "ranges-merge": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ranges-merge/-/ranges-merge-7.1.0.tgz", + "integrity": "sha512-coTHcyAEIhoEdsBs9f5f+q0rmy7UHvS/5nfuXzuj5oLX/l/tbqM5uxRb6eh8WMdetXia3lK67ZO4tarH4ieulQ==", + "requires": { + "@babel/runtime": "^7.14.0", + "ranges-push": "^5.1.0", + "ranges-sort": "^4.1.0" + } + }, + "ranges-push": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ranges-push/-/ranges-push-5.1.0.tgz", + "integrity": "sha512-vqGcaGq7GWV1zBa9w83E+dzYkOvE9/3pIRUPvLf12c+mGQCf1nesrkBI7Ob8taN2CC9V1HDSJx0KAQl0SgZftA==", + "requires": { + "@babel/runtime": "^7.14.0", + "ranges-merge": "^7.1.0", + "string-collapse-leading-whitespace": "^5.1.0", + "string-trim-spaces-only": "^3.1.0" + } + }, + "ranges-sort": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ranges-sort/-/ranges-sort-4.1.0.tgz", + "integrity": "sha512-GOQgk6UtsrfKFeYa53YLiBVnLINwYmOk5l2QZG1csZpT6GdImUwooh+/cRrp7b+fYawZX/rnyA3Ul+pdgQBIzA==", + "requires": { + "@babel/runtime": "^7.14.0" + } + }, "raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", @@ -1523,6 +1589,11 @@ "resolved": "https://registry.npmjs.org/recursive-readdir-async/-/recursive-readdir-async-1.1.8.tgz", "integrity": "sha512-Iqosi7g1iTx2MkOYKQo5UmncQWBcKUPdbwBLizeZ9MXiCLKeaTLc/Mt2vUdBpmcEMIQGR8bOUT5sS/o19ufwrA==" }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, "resolve-alpn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.0.tgz", @@ -1727,11 +1798,52 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, + "string-collapse-leading-whitespace": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/string-collapse-leading-whitespace/-/string-collapse-leading-whitespace-5.1.0.tgz", + "integrity": "sha512-mYz9/Kb5uvRB4DZj46zILwI4y9lD9JsvXG9Xb7zjbwm0I/R40G7oFfMsqJ28l2d7gWMTLJL569NfJQVLQbnHCw==", + "requires": { + "@babel/runtime": "^7.14.0" + } + }, "string-indexes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/string-indexes/-/string-indexes-1.0.0.tgz", "integrity": "sha512-RUlx+2YydZJNlRAvoh1siPYWj/Xfk6t1sQLkA5n1tMGRCKkRLzkRtJhHk4qRmKergEBh8R3pWhsUsDqia/bolw==" }, + "string-left-right": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-left-right/-/string-left-right-4.1.0.tgz", + "integrity": "sha512-ic/WvfNVUygWWsgg8akzSzp2NuttfhrdbH7QmSnda5b5RFmT9aCEDiS/M+gmTJwtFy7+b/2AXU4Z6vejcePQqQ==", + "requires": { + "@babel/runtime": "^7.14.0", + "lodash.clonedeep": "^4.5.0", + "lodash.isplainobject": "^4.0.6" + } + }, + "string-strip-html": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/string-strip-html/-/string-strip-html-8.3.0.tgz", + "integrity": "sha512-1+rjTPt0JjpFr1w0bfNL1S6O0I9fJDqM+P3pFTpC6eEEpIXhmBvPLnaQoEuWarswiH219qCefDSxTLxGQyHKUg==", + "requires": { + "@babel/runtime": "^7.14.0", + "html-entities": "^2.3.2", + "lodash.isplainobject": "^4.0.6", + "lodash.trim": "^4.5.1", + "lodash.without": "^4.4.0", + "ranges-apply": "^5.1.0", + "ranges-push": "^5.1.0", + "string-left-right": "^4.1.0" + } + }, + "string-trim-spaces-only": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-trim-spaces-only/-/string-trim-spaces-only-3.1.0.tgz", + "integrity": "sha512-AW7RSi3+QtE6wR+4m/kmwlyy39neBbCIzrzzu1/RGzNRiPKQOeB3rGzr4ubg4UIQgYtr2w0PrxhKPXgyqJ0vaQ==", + "requires": { + "@babel/runtime": "^7.14.0" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", diff --git a/package.json b/package.json index 5fb3a3fc..523912bf 100644 --- a/package.json +++ b/package.json @@ -50,4 +50,4 @@ "xml2js": "^0.4.23" }, "devDependencies": {} -} \ No newline at end of file +} diff --git a/server/providers/Audible.js b/server/providers/Audible.js index 9138ce22..bc12a92b 100644 --- a/server/providers/Audible.js +++ b/server/providers/Audible.js @@ -1,5 +1,5 @@ const axios = require('axios') -const {stripHtml} = require('string-strip-html') +const { stripHtml } = require('string-strip-html') const Logger = require('../Logger') class Audible { @@ -43,7 +43,6 @@ class Audible { Logger.error('[Audible] search error', error) return [] }) - Logger.debug(JSON.stringify(items.map(item => this.cleanResult(item)))) return items.map(item => this.cleanResult(item)) } }