Handle podcasts which use html lists and also have html tags in the chapter titles

This commit is contained in:
Harry Rose 2026-03-16 20:59:00 +00:00
parent 4907e70a48
commit 6e05484307
2 changed files with 20 additions and 4 deletions

View file

@ -1,3 +1,4 @@
const sanitizeHtml = require('../../libs/sanitizeHtml')
const Logger = require('../../Logger')
/**
@ -27,13 +28,16 @@ module.exports.parse = (podcastDescription, audioDurationSecs) => {
const timestampRegex = /\b(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?\b/
const chapterTitleRegex = /\b\d{1,2}:\d{1,2}(?::\d{1,2})?\b(?:\s+|\))(.+)$/
const descriptionLineSplitRegex = /\<\s*\/\s*p\s*\>|\<\s*br\s*\s*\/\>|\n/
// Split on "</p>", "<br />", "\n", </li>
const descriptionLineSplitRegex = /\<\s*\/\s*p\s*\>|\<\s*br\s*\/\>|\n|\<\s*\/\s*li\s*\>/
var descriptionLines = podcastDescription.split(descriptionLineSplitRegex)
var newChapters = []
for (let i = 0; i < descriptionLines.length; i++) {
let line = descriptionLines[i]
// Strip all HTML tags out
let line = sanitizeHtml(descriptionLines[i], { allowedTags: [] })
let match = timestampRegex.exec(line)
if (match == null) continue
@ -85,7 +89,7 @@ module.exports.parse = (podcastDescription, audioDurationSecs) => {
newChapters[newChapters.length - 1].end = audioDurationSecs
}
Logger.info(`[PodcastEpisode] Successfully generated ${newChapters.length} chapters`)
Logger.info(`Successfully generated ${newChapters.length} chapters`)
if (newChapters.length == 1) {
throw new Error('Only one chapter found, treating as invalid description')

View file

@ -1,5 +1,4 @@
const chai = require('chai')
const PodcastEpisode = require('../../../../server/models/PodcastEpisode')
const expect = chai.expect
const parsePodcastDescriptionForChapters = require('../../../../server/utils/parsers/parsePodcastDescriptionForChapters')
@ -69,6 +68,19 @@ describe('parsePodcastDescriptionForChapters', () => {
{ title: 'Chapter 7', id: 7, start: 2492, end: 2803 },
{ title: 'Chapter 8', id: 8, start: 2803, end: 3060 }
]
},
{
testName: 'Should handle html lists and chapters with html tags in the title',
description: '<p>Introduction</p><p><br /></p><p><br /></p>Chapters<ul><li><strong>00:00:00</strong> Intro</li><li><strong>00:03:55</strong> Chapter 1</li><li><strong>00:09:52</strong> Chapter 2 </li><li><strong>00:16:11</strong> Chapter 3</li><li><strong>00:20:03</strong> Chapter 4</li><li><strong>00:24:08</strong> Chapter 5</li>',
audioDuration: 4000,
expectedChapters: [
{ title: 'Intro', id: 1, start: 0, end: 235 },
{ title: 'Chapter 1', id: 2, start: 235, end: 592 },
{ title: 'Chapter 2', id: 3, start: 592, end: 971 },
{ title: 'Chapter 3', id: 4, start: 971, end: 1203 },
{ title: 'Chapter 4', id: 5, start: 1203, end: 1448 },
{ title: 'Chapter 5', id: 6, start: 1448, end: 4000 }
]
}
]
testCasesTestingSuccess.forEach(function (testCase) {