add rating support on custom metadata

This commit is contained in:
danny.rich 2025-11-03 16:03:36 -05:00
parent e7d0771261
commit ec27323a64
3 changed files with 25 additions and 4 deletions

View File

@ -128,6 +128,12 @@ components:
type: integer
format: int64
description: Duration in seconds
rating:
type: number
format: float
minimum: 0
maximum: 5
description: Star rating (0-5, typically 0.5 increments)
SeriesMetadata:
type: object

View File

@ -92,7 +92,7 @@ class CustomProviderAdapter {
// re-map keys to throw out
return matches.map((match) => {
const { title, subtitle, author, narrator, publisher, publishedYear, description, cover, isbn, asin, genres, tags, series, language, duration } = match
const { title, subtitle, author, narrator, publisher, publishedYear, description, cover, isbn, asin, genres, tags, series, language, duration, rating } = match
const payload = {
title: toStringOrUndefined(title),
@ -109,7 +109,8 @@ class CustomProviderAdapter {
tags: toStringOrUndefined(tags),
series: validateSeriesArray(series),
language: toStringOrUndefined(language),
duration: !isNaN(duration) && duration !== null ? Number(duration) : undefined
duration: !isNaN(duration) && duration !== null ? Number(duration) : undefined,
rating: rating !== undefined && rating !== null ? (!isNaN(Number(rating)) && Number(rating) > 0 ? Number(rating) : undefined) : undefined
}
// Remove undefined values

View File

@ -193,11 +193,11 @@ class Scanner {
*/
async quickMatchBookBuildUpdatePayload(apiRouterCtx, libraryItem, matchData, options) {
// Update media metadata if not set OR overrideDetails flag
const detailKeysToUpdate = ['title', 'subtitle', 'description', 'narrator', 'publisher', 'publishedYear', 'genres', 'tags', 'language', 'explicit', 'abridged', 'asin', 'isbn']
const detailKeysToUpdate = ['title', 'subtitle', 'description', 'narrator', 'publisher', 'publishedYear', 'genres', 'tags', 'language', 'explicit', 'abridged', 'asin', 'isbn', 'rating']
const updatePayload = {}
for (const key in matchData) {
if (matchData[key] && detailKeysToUpdate.includes(key)) {
if ((matchData[key] || key === 'rating') && detailKeysToUpdate.includes(key)) {
if (key === 'narrator') {
if (!libraryItem.media.narrators?.length || options.overrideDetails) {
updatePayload.narrators = matchData[key]
@ -230,6 +230,20 @@ class Scanner {
.filter((v) => !!v)
updatePayload[key] = tagsArray
}
} else if (key === 'rating') {
// Normalize rating: convert object with average to number, or number to number
let ratingValue = matchData[key]
if (ratingValue && typeof ratingValue === 'object' && ratingValue.average) {
ratingValue = Number(ratingValue.average) || null
} else if (ratingValue !== undefined && ratingValue !== null) {
ratingValue = Number(ratingValue) || null
}
if (ratingValue === 0) ratingValue = null
if ((!libraryItem.media.rating || options.overrideDetails) && ratingValue !== null && !isNaN(ratingValue) && ratingValue > 0) {
updatePayload[key] = ratingValue
} else if (ratingValue === null && libraryItem.media.rating && options.overrideDetails) {
updatePayload[key] = null
}
} else if (!libraryItem.media[key] || options.overrideDetails) {
updatePayload[key] = matchData[key]
}