mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-22 00:07:52 +01:00
Add:Quick match podcast button
This commit is contained in:
parent
872d5178e6
commit
9a87e4af73
@ -12,11 +12,11 @@
|
|||||||
|
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
|
|
||||||
<ui-tooltip v-if="mediaType == 'book'" :disabled="!!quickMatching" :text="`(Root User Only) Populate empty book details & cover with first book result from '${libraryProvider}'. Does not overwrite details.`" direction="bottom" class="mr-2 md:mr-4">
|
<ui-tooltip :disabled="!!quickMatching" :text="`Populate empty ${mediaType} details & cover with first ${mediaType} result from '${libraryProvider}'. Does not overwrite details unless 'Prefer matched metadata' server setting is enabled.`" direction="bottom" class="mr-2 md:mr-4">
|
||||||
<ui-btn v-if="userIsAdminOrUp" :loading="quickMatching" color="bg" type="button" class="h-full" small @click.stop.prevent="quickMatch">Quick Match</ui-btn>
|
<ui-btn v-if="userIsAdminOrUp" :loading="quickMatching" color="bg" type="button" class="h-full" small @click.stop.prevent="quickMatch">Quick Match</ui-btn>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
||||||
<ui-tooltip :disabled="!!libraryScan" text="(Root User Only) Rescan audiobook including metadata" direction="bottom" class="mr-2 md:mr-4">
|
<ui-tooltip :disabled="!!libraryScan" text="Rescan library item including metadata" direction="bottom" class="mr-2 md:mr-4">
|
||||||
<ui-btn v-if="userIsAdminOrUp && !isFile" :loading="rescanning" :disabled="!!libraryScan" color="bg" type="button" class="h-full" small @click.stop.prevent="rescan">Re-Scan</ui-btn>
|
<ui-btn v-if="userIsAdminOrUp && !isFile" :loading="rescanning" :disabled="!!libraryScan" color="bg" type="button" class="h-full" small @click.stop.prevent="rescan">Re-Scan</ui-btn>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ const { ScanResult, LogLevel } = require('../utils/constants')
|
|||||||
|
|
||||||
const MediaFileScanner = require('./MediaFileScanner')
|
const MediaFileScanner = require('./MediaFileScanner')
|
||||||
const BookFinder = require('../finders/BookFinder')
|
const BookFinder = require('../finders/BookFinder')
|
||||||
|
const PodcastFinder = require('../finders/PodcastFinder')
|
||||||
const LibraryItem = require('../objects/LibraryItem')
|
const LibraryItem = require('../objects/LibraryItem')
|
||||||
const LibraryScan = require('./LibraryScan')
|
const LibraryScan = require('./LibraryScan')
|
||||||
const ScanOptions = require('./ScanOptions')
|
const ScanOptions = require('./ScanOptions')
|
||||||
@ -33,6 +34,7 @@ class Scanner {
|
|||||||
this.scanningFilesChanged = false
|
this.scanningFilesChanged = false
|
||||||
|
|
||||||
this.bookFinder = new BookFinder()
|
this.bookFinder = new BookFinder()
|
||||||
|
this.podcastFinder = new PodcastFinder()
|
||||||
}
|
}
|
||||||
|
|
||||||
isLibraryScanning(libraryId) {
|
isLibraryScanning(libraryId) {
|
||||||
@ -672,16 +674,6 @@ class Scanner {
|
|||||||
var provider = options.provider || 'google'
|
var provider = options.provider || 'google'
|
||||||
var searchTitle = options.title || libraryItem.media.metadata.title
|
var searchTitle = options.title || libraryItem.media.metadata.title
|
||||||
var searchAuthor = options.author || libraryItem.media.metadata.authorName
|
var searchAuthor = options.author || libraryItem.media.metadata.authorName
|
||||||
var searchISBN = options.isbn || libraryItem.media.metadata.isbn
|
|
||||||
var searchASIN = options.asin || libraryItem.media.metadata.asin
|
|
||||||
|
|
||||||
var results = await this.bookFinder.search(provider, searchTitle, searchAuthor, searchISBN, searchASIN)
|
|
||||||
if (!results.length) {
|
|
||||||
return {
|
|
||||||
warning: `No ${provider} match found`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var matchData = results[0]
|
|
||||||
|
|
||||||
// Set to override existing metadata if scannerPreferMatchedMetadata setting is true
|
// Set to override existing metadata if scannerPreferMatchedMetadata setting is true
|
||||||
if (this.db.serverSettings.scannerPreferMatchedMetadata) {
|
if (this.db.serverSettings.scannerPreferMatchedMetadata) {
|
||||||
@ -689,18 +681,110 @@ class Scanner {
|
|||||||
options.overrideDetails = true
|
options.overrideDetails = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update cover if not set OR overrideCover flag
|
var updatePayload = {}
|
||||||
var hasUpdated = false
|
var hasUpdated = false
|
||||||
if (matchData.cover && (!libraryItem.media.coverPath || options.overrideCover)) {
|
|
||||||
Logger.debug(`[Scanner] Updating cover "${matchData.cover}"`)
|
if (libraryItem.mediaType === 'book') {
|
||||||
var coverResult = await this.coverManager.downloadCoverFromUrl(libraryItem, matchData.cover)
|
var searchISBN = options.isbn || libraryItem.media.metadata.isbn
|
||||||
if (!coverResult || coverResult.error || !coverResult.cover) {
|
var searchASIN = options.asin || libraryItem.media.metadata.asin
|
||||||
Logger.warn(`[Scanner] Match cover "${matchData.cover}" failed to use: ${coverResult ? coverResult.error : 'Unknown Error'}`)
|
|
||||||
} else {
|
var results = await this.bookFinder.search(provider, searchTitle, searchAuthor, searchISBN, searchASIN)
|
||||||
|
if (!results.length) {
|
||||||
|
return {
|
||||||
|
warning: `No ${provider} match found`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var matchData = results[0]
|
||||||
|
|
||||||
|
// Update cover if not set OR overrideCover flag
|
||||||
|
if (matchData.cover && (!libraryItem.media.coverPath || options.overrideCover)) {
|
||||||
|
Logger.debug(`[Scanner] Updating cover "${matchData.cover}"`)
|
||||||
|
var coverResult = await this.coverManager.downloadCoverFromUrl(libraryItem, matchData.cover)
|
||||||
|
if (!coverResult || coverResult.error || !coverResult.cover) {
|
||||||
|
Logger.warn(`[Scanner] Match cover "${matchData.cover}" failed to use: ${coverResult ? coverResult.error : 'Unknown Error'}`)
|
||||||
|
} else {
|
||||||
|
hasUpdated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePayload = await this.quickMatchBookBuildUpdatePayload(libraryItem, matchData, options)
|
||||||
|
} else { // Podcast quick match
|
||||||
|
var results = await this.podcastFinder.search(searchTitle)
|
||||||
|
if (!results.length) {
|
||||||
|
return {
|
||||||
|
warning: `No ${provider} match found`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var matchData = results[0]
|
||||||
|
|
||||||
|
// Update cover if not set OR overrideCover flag
|
||||||
|
if (matchData.cover && (!libraryItem.media.coverPath || options.overrideCover)) {
|
||||||
|
Logger.debug(`[Scanner] Updating cover "${matchData.cover}"`)
|
||||||
|
var coverResult = await this.coverManager.downloadCoverFromUrl(libraryItem, matchData.cover)
|
||||||
|
if (!coverResult || coverResult.error || !coverResult.cover) {
|
||||||
|
Logger.warn(`[Scanner] Match cover "${matchData.cover}" failed to use: ${coverResult ? coverResult.error : 'Unknown Error'}`)
|
||||||
|
} else {
|
||||||
|
hasUpdated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePayload = this.quickMatchPodcastBuildUpdatePayload(libraryItem, matchData, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(updatePayload).length) {
|
||||||
|
Logger.debug('[Scanner] Updating details', updatePayload)
|
||||||
|
if (libraryItem.media.update(updatePayload)) {
|
||||||
hasUpdated = true
|
hasUpdated = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasUpdated) {
|
||||||
|
await this.db.updateLibraryItem(libraryItem)
|
||||||
|
this.emitter('item_updated', libraryItem.toJSONExpanded())
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
updated: hasUpdated,
|
||||||
|
libraryItem: libraryItem.toJSONExpanded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quickMatchPodcastBuildUpdatePayload(libraryItem, matchData, options) {
|
||||||
|
const updatePayload = {}
|
||||||
|
updatePayload.metadata = {}
|
||||||
|
|
||||||
|
const matchDataTransformed = {
|
||||||
|
title: matchData.title || null,
|
||||||
|
author: matchData.artistName || null,
|
||||||
|
genres: matchData.genres || [],
|
||||||
|
itunesId: matchData.id || null,
|
||||||
|
itunesPageUrl: matchData.pageUrl || null,
|
||||||
|
itunesArtistId: matchData.artistId || null,
|
||||||
|
releaseDate: matchData.releaseDate || null,
|
||||||
|
imageUrl: matchData.cover || null,
|
||||||
|
description: matchData.descriptionPlain || null
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key in matchDataTransformed) {
|
||||||
|
if (matchDataTransformed[key]) {
|
||||||
|
if (key === 'genres') {
|
||||||
|
if ((!libraryItem.media.metadata.genres || options.overrideDetails)) {
|
||||||
|
updatePayload.metadata[key] = matchDataTransformed[key].split(',').map(v => v.trim()).filter(v => !!v)
|
||||||
|
}
|
||||||
|
} else if (!libraryItem.media.metadata[key] || options.overrideDetails) {
|
||||||
|
updatePayload.metadata[key] = matchDataTransformed[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Object.keys(updatePayload.metadata).length) {
|
||||||
|
delete updatePayload.metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
async quickMatchBookBuildUpdatePayload(libraryItem, matchData, options) {
|
||||||
// Update media metadata if not set OR overrideDetails flag
|
// Update media metadata if not set OR overrideDetails flag
|
||||||
const detailKeysToUpdate = ['title', 'subtitle', 'description', 'narrator', 'publisher', 'publishedYear', 'genres', 'tags', 'language', 'explicit', 'asin', 'isbn']
|
const detailKeysToUpdate = ['title', 'subtitle', 'description', 'narrator', 'publisher', 'publishedYear', 'genres', 'tags', 'language', 'explicit', 'asin', 'isbn']
|
||||||
const updatePayload = {}
|
const updatePayload = {}
|
||||||
@ -763,22 +847,11 @@ class Scanner {
|
|||||||
updatePayload.metadata.series = seriesPayload
|
updatePayload.metadata.series = seriesPayload
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(updatePayload).length) {
|
if (!Object.keys(updatePayload.metadata).length) {
|
||||||
Logger.debug('[Scanner] Updating details', updatePayload)
|
delete updatePayload.metadata
|
||||||
if (libraryItem.media.update(updatePayload)) {
|
|
||||||
hasUpdated = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasUpdated) {
|
return updatePayload
|
||||||
await this.db.updateLibraryItem(libraryItem)
|
|
||||||
this.emitter('item_updated', libraryItem.toJSONExpanded())
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
updated: hasUpdated,
|
|
||||||
libraryItem: libraryItem.toJSONExpanded()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async matchLibraryItems(library) {
|
async matchLibraryItems(library) {
|
||||||
|
Loading…
Reference in New Issue
Block a user