mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-04 02:05:06 +02:00
Add:Podcast episode match tab and find episode by title api route
This commit is contained in:
parent
f702c02859
commit
516c5c3308
8 changed files with 391 additions and 104 deletions
|
@ -164,6 +164,25 @@ class PodcastController {
|
|||
})
|
||||
}
|
||||
|
||||
async findEpisode(req, res) {
|
||||
const rssFeedUrl = req.libraryItem.media.metadata.feedUrl
|
||||
if (!rssFeedUrl) {
|
||||
Logger.error(`[PodcastController] findEpisode: Podcast has no feed url`)
|
||||
return res.status(500).send('Podcast does not have an RSS feed URL')
|
||||
}
|
||||
|
||||
var searchTitle = req.query.title
|
||||
if (!searchTitle) {
|
||||
return res.sendStatus(500)
|
||||
}
|
||||
searchTitle = searchTitle.toLowerCase().trim()
|
||||
|
||||
const episodes = await this.podcastManager.findEpisode(rssFeedUrl, searchTitle)
|
||||
res.json({
|
||||
episodes: episodes || []
|
||||
})
|
||||
}
|
||||
|
||||
async downloadEpisodes(req, res) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user attempted to download episodes`, req.user)
|
||||
|
@ -185,7 +204,7 @@ class PodcastController {
|
|||
|
||||
var episodeId = req.params.episodeId
|
||||
if (!libraryItem.media.checkHasEpisode(episodeId)) {
|
||||
return res.status(500).send('Episode not found')
|
||||
return res.status(404).send('Episode not found')
|
||||
}
|
||||
|
||||
var wasUpdated = libraryItem.media.updateEpisode(episodeId, req.body)
|
||||
|
|
|
@ -6,6 +6,7 @@ const { parsePodcastRssFeedXml } = require('../utils/podcastUtils')
|
|||
const Logger = require('../Logger')
|
||||
|
||||
const { downloadFile } = require('../utils/fileUtils')
|
||||
const { levenshteinDistance } = require('../utils/index')
|
||||
const opmlParser = require('../utils/parsers/parseOPML')
|
||||
const prober = require('../utils/prober')
|
||||
const LibraryFile = require('../objects/files/LibraryFile')
|
||||
|
@ -259,6 +260,37 @@ class PodcastManager {
|
|||
return newEpisodes
|
||||
}
|
||||
|
||||
async findEpisode(rssFeedUrl, searchTitle) {
|
||||
const feed = await this.getPodcastFeed(rssFeedUrl).catch(() => {
|
||||
return null
|
||||
})
|
||||
if (!feed || !feed.episodes) {
|
||||
return null
|
||||
}
|
||||
|
||||
const matches = []
|
||||
feed.episodes.forEach(ep => {
|
||||
if (!ep.title) return
|
||||
|
||||
const epTitle = ep.title.toLowerCase().trim()
|
||||
if (epTitle === searchTitle) {
|
||||
matches.push({
|
||||
episode: ep,
|
||||
levenshtein: 0
|
||||
})
|
||||
} else {
|
||||
const levenshtein = levenshteinDistance(searchTitle, epTitle, true)
|
||||
if (levenshtein <= 6 && epTitle.length > levenshtein) {
|
||||
matches.push({
|
||||
episode: ep,
|
||||
levenshtein
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return matches.sort((a, b) => a.levenshtein - b.levenshtein)
|
||||
}
|
||||
|
||||
getPodcastFeed(feedUrl, excludeEpisodeMetadata = false) {
|
||||
Logger.debug(`[PodcastManager] getPodcastFeed for "${feedUrl}"`)
|
||||
return axios.get(feedUrl, { timeout: 5000 }).then(async (data) => {
|
||||
|
@ -273,7 +305,7 @@ class PodcastManager {
|
|||
}
|
||||
return payload.podcast
|
||||
}).catch((error) => {
|
||||
console.error('Failed', error)
|
||||
Logger.error('[PodcastManager] getPodcastFeed Error', error)
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
|
|
@ -189,6 +189,7 @@ class ApiRouter {
|
|||
this.router.get('/podcasts/:id/checknew', PodcastController.middleware.bind(this), PodcastController.checkNewEpisodes.bind(this))
|
||||
this.router.get('/podcasts/:id/downloads', PodcastController.middleware.bind(this), PodcastController.getEpisodeDownloads.bind(this))
|
||||
this.router.get('/podcasts/:id/clear-queue', PodcastController.middleware.bind(this), PodcastController.clearEpisodeDownloadQueue.bind(this))
|
||||
this.router.get('/podcasts/:id/search-episode', PodcastController.middleware.bind(this), PodcastController.findEpisode.bind(this))
|
||||
this.router.post('/podcasts/:id/download-episodes', PodcastController.middleware.bind(this), PodcastController.downloadEpisodes.bind(this))
|
||||
this.router.patch('/podcasts/:id/episode/:episodeId', PodcastController.middleware.bind(this), PodcastController.updateEpisode.bind(this))
|
||||
this.router.delete('/podcasts/:id/episode/:episodeId', PodcastController.middleware.bind(this), PodcastController.removeEpisode.bind(this))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue