Support rich text book descriptions

This commit is contained in:
mikiher 2025-01-22 08:53:23 +02:00
parent 66b90e0841
commit 286185329d
14 changed files with 136 additions and 83 deletions

View file

@ -8,6 +8,7 @@ const AudiobookCovers = require('../providers/AudiobookCovers')
const CustomProviderAdapter = require('../providers/CustomProviderAdapter')
const Logger = require('../Logger')
const { levenshteinDistance, escapeRegExp } = require('../utils/index')
const htmlSanitizer = require('../utils/htmlSanitizer')
class BookFinder {
#providerResponseTimeout = 30000
@ -463,6 +464,12 @@ class BookFinder {
} else {
books = await this.getGoogleBooksResults(title, author)
}
books.forEach((book) => {
if (book.description) {
book.description = htmlSanitizer.sanitize(book.description)
book.descriptionPlain = htmlSanitizer.stripAllTags(book.description)
}
})
return books
}

View file

@ -2,6 +2,7 @@ const { DataTypes, Model } = require('sequelize')
const Logger = require('../Logger')
const { getTitlePrefixAtEnd, getTitleIgnorePrefix } = require('../utils')
const parseNameString = require('../utils/parsers/parseNameString')
const htmlSanitizer = require('../utils/htmlSanitizer')
/**
* @typedef EBookFileObject
@ -343,6 +344,7 @@ class Book extends Model {
publishedDate: this.publishedDate,
publisher: this.publisher,
description: this.description,
descriptionPlain: this.description ? htmlSanitizer.stripAllTags(this.description) : null,
isbn: this.isbn,
asin: this.asin,
language: this.language,
@ -542,6 +544,7 @@ class Book extends Model {
publishedDate: this.publishedDate,
publisher: this.publisher,
description: this.description,
descriptionPlain: this.description ? htmlSanitizer.stripAllTags(this.description) : null,
isbn: this.isbn,
asin: this.asin,
language: this.language,
@ -564,6 +567,7 @@ class Book extends Model {
publishedDate: this.publishedDate,
publisher: this.publisher,
description: this.description,
descriptionPlain: this.description ? htmlSanitizer.stripAllTags(this.description) : null,
isbn: this.isbn,
asin: this.asin,
language: this.language,

View file

@ -1,5 +1,4 @@
const axios = require('axios').default
const htmlSanitizer = require('../utils/htmlSanitizer')
const Logger = require('../Logger')
const { isValidASIN } = require('../utils/index')
@ -68,7 +67,7 @@ class Audible {
narrator: narrators ? narrators.map(({ name }) => name).join(', ') : null,
publisher: publisherName,
publishedYear: releaseDate ? releaseDate.split('-')[0] : null,
description: summary ? htmlSanitizer.stripAllTags(summary) : null,
description: summary || null,
cover: image,
asin,
genres: genresFiltered.length ? genresFiltered : null,

View file

@ -112,7 +112,7 @@ class iTunes {
artistId: data.artistId,
title: data.collectionName,
author,
description: htmlSanitizer.stripAllTags(data.description || ''),
description: data.description || null,
publishedYear: data.releaseDate ? data.releaseDate.split('-')[0] : null,
genres: data.primaryGenreName ? [data.primaryGenreName] : null,
cover: this.getCoverArtwork(data)

View file

@ -1,11 +1,9 @@
const sanitizeHtml = require('../libs/sanitizeHtml')
const { entities } = require("./htmlEntities");
const { entities } = require('./htmlEntities')
function sanitize(html) {
const sanitizerOptions = {
allowedTags: [
'p', 'ol', 'ul', 'li', 'a', 'strong', 'em', 'del', 'br'
],
allowedTags: ['p', 'ol', 'ul', 'li', 'a', 'strong', 'em', 'del', 'br', 'b', 'i'],
disallowedTagsMode: 'discard',
allowedAttributes: {
a: ['href', 'name', 'target']
@ -34,6 +32,6 @@ function decodeHTMLEntities(strToDecode) {
if (entity in entities) {
return entities[entity]
}
return entity;
return entity
})
}