mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-02-08 11:19:40 +00:00
Add:Schedule podcast new episode checks
This commit is contained in:
parent
a690dfe671
commit
46668854ad
7 changed files with 315 additions and 85 deletions
|
|
@ -1,5 +1,4 @@
|
|||
const fs = require('../libs/fsExtra')
|
||||
const cron = require('../libs/nodeCron')
|
||||
const axios = require('axios')
|
||||
|
||||
const { parsePodcastRssFeedXml } = require('../utils/podcastUtils')
|
||||
|
|
@ -23,22 +22,14 @@ class PodcastManager {
|
|||
this.downloadQueue = []
|
||||
this.currentDownload = null
|
||||
|
||||
this.episodeScheduleTask = null
|
||||
this.failedCheckMap = {},
|
||||
this.MaxFailedEpisodeChecks = 24
|
||||
this.failedCheckMap = {}
|
||||
this.MaxFailedEpisodeChecks = 24
|
||||
}
|
||||
|
||||
get serverSettings() {
|
||||
return this.db.serverSettings || {}
|
||||
}
|
||||
|
||||
init() {
|
||||
var podcastsWithAutoDownload = this.db.libraryItems.some(li => li.mediaType === 'podcast' && li.media.autoDownloadEpisodes)
|
||||
if (podcastsWithAutoDownload) {
|
||||
this.schedulePodcastEpisodeCron()
|
||||
}
|
||||
}
|
||||
|
||||
getEpisodeDownloadsInQueue(libraryItemId) {
|
||||
return this.downloadQueue.filter(d => d.libraryItemId === libraryItemId)
|
||||
}
|
||||
|
|
@ -189,73 +180,45 @@ class PodcastManager {
|
|||
return newAudioFile
|
||||
}
|
||||
|
||||
schedulePodcastEpisodeCron() {
|
||||
try {
|
||||
Logger.debug(`[PodcastManager] Scheduled podcast episode check cron "${this.serverSettings.podcastEpisodeSchedule}"`)
|
||||
this.episodeScheduleTask = cron.schedule(this.serverSettings.podcastEpisodeSchedule, () => {
|
||||
Logger.debug(`[PodcastManager] Running cron`)
|
||||
this.checkForNewEpisodes()
|
||||
})
|
||||
} catch (error) {
|
||||
Logger.error(`[PodcastManager] Failed to schedule podcast cron ${this.serverSettings.podcastEpisodeSchedule}`, error)
|
||||
}
|
||||
}
|
||||
// Returns false if auto download episodes was disabled (disabled if reaches max failed checks)
|
||||
async runEpisodeCheck(libraryItem) {
|
||||
const lastEpisodeCheckDate = new Date(libraryItem.media.lastEpisodeCheck || 0)
|
||||
const latestEpisodePublishedAt = libraryItem.media.latestEpisodePublished
|
||||
Logger.info(`[PodcastManager] runEpisodeCheck: "${libraryItem.media.metadata.title}" | Last check: ${lastEpisodeCheckDate} | ${latestEpisodePublishedAt ? `Latest episode pubDate: ${new Date(latestEpisodePublishedAt)}` : 'No latest episode'}`)
|
||||
|
||||
cancelCron() {
|
||||
Logger.debug(`[PodcastManager] Canceled new podcast episode check cron`)
|
||||
if (this.episodeScheduleTask) {
|
||||
this.episodeScheduleTask.destroy()
|
||||
this.episodeScheduleTask = null
|
||||
}
|
||||
}
|
||||
// Use latest episode pubDate if exists OR fallback to using lastEpisodeCheckDate
|
||||
// lastEpisodeCheckDate will be the current time when adding a new podcast
|
||||
const dateToCheckForEpisodesAfter = latestEpisodePublishedAt || lastEpisodeCheckDate
|
||||
Logger.debug(`[PodcastManager] runEpisodeCheck: "${libraryItem.media.metadata.title}" checking for episodes after ${new Date(dateToCheckForEpisodesAfter)}`)
|
||||
|
||||
async checkForNewEpisodes() {
|
||||
var podcastsWithAutoDownload = this.db.libraryItems.filter(li => li.mediaType === 'podcast' && li.media.autoDownloadEpisodes)
|
||||
if (!podcastsWithAutoDownload.length) {
|
||||
Logger.info(`[PodcastManager] checkForNewEpisodes - No podcasts with auto download set`)
|
||||
this.cancelCron()
|
||||
return
|
||||
}
|
||||
Logger.debug(`[PodcastManager] checkForNewEpisodes - Checking ${podcastsWithAutoDownload.length} Podcasts`)
|
||||
var newEpisodes = await this.checkPodcastForNewEpisodes(libraryItem, dateToCheckForEpisodesAfter)
|
||||
Logger.debug(`[PodcastManager] runEpisodeCheck: ${newEpisodes ? newEpisodes.length : 'N/A'} episodes found`)
|
||||
|
||||
for (const libraryItem of podcastsWithAutoDownload) {
|
||||
const lastEpisodeCheckDate = new Date(libraryItem.media.lastEpisodeCheck || 0)
|
||||
const latestEpisodePublishedAt = libraryItem.media.latestEpisodePublished
|
||||
Logger.info(`[PodcastManager] checkForNewEpisodes: "${libraryItem.media.metadata.title}" | Last check: ${lastEpisodeCheckDate} | ${latestEpisodePublishedAt ? `Latest episode pubDate: ${new Date(latestEpisodePublishedAt)}` : 'No latest episode'}`)
|
||||
|
||||
// Use latest episode pubDate if exists OR fallback to using lastEpisodeCheckDate
|
||||
// lastEpisodeCheckDate will be the current time when adding a new podcast
|
||||
const dateToCheckForEpisodesAfter = latestEpisodePublishedAt || lastEpisodeCheckDate
|
||||
Logger.debug(`[PodcastManager] checkForNewEpisodes: "${libraryItem.media.metadata.title}" checking for episodes after ${new Date(dateToCheckForEpisodesAfter)}`)
|
||||
|
||||
var newEpisodes = await this.checkPodcastForNewEpisodes(libraryItem, dateToCheckForEpisodesAfter)
|
||||
Logger.debug(`[PodcastManager] checkForNewEpisodes checked result ${newEpisodes ? newEpisodes.length : 'N/A'}`)
|
||||
|
||||
if (!newEpisodes) { // Failed
|
||||
// Allow up to 3 failed attempts before disabling auto download
|
||||
if (!this.failedCheckMap[libraryItem.id]) this.failedCheckMap[libraryItem.id] = 0
|
||||
this.failedCheckMap[libraryItem.id]++
|
||||
if (this.failedCheckMap[libraryItem.id] >= this.MaxFailedEpisodeChecks) {
|
||||
Logger.error(`[PodcastManager] checkForNewEpisodes ${this.failedCheckMap[libraryItem.id]} failed attempts at checking episodes for "${libraryItem.media.metadata.title}" - disabling auto download`)
|
||||
libraryItem.media.autoDownloadEpisodes = false
|
||||
delete this.failedCheckMap[libraryItem.id]
|
||||
} else {
|
||||
Logger.warn(`[PodcastManager] checkForNewEpisodes ${this.failedCheckMap[libraryItem.id]} failed attempts at checking episodes for "${libraryItem.media.metadata.title}"`)
|
||||
}
|
||||
} else if (newEpisodes.length) {
|
||||
if (!newEpisodes) { // Failed
|
||||
// Allow up to MaxFailedEpisodeChecks failed attempts before disabling auto download
|
||||
if (!this.failedCheckMap[libraryItem.id]) this.failedCheckMap[libraryItem.id] = 0
|
||||
this.failedCheckMap[libraryItem.id]++
|
||||
if (this.failedCheckMap[libraryItem.id] >= this.MaxFailedEpisodeChecks) {
|
||||
Logger.error(`[PodcastManager] runEpisodeCheck ${this.failedCheckMap[libraryItem.id]} failed attempts at checking episodes for "${libraryItem.media.metadata.title}" - disabling auto download`)
|
||||
libraryItem.media.autoDownloadEpisodes = false
|
||||
delete this.failedCheckMap[libraryItem.id]
|
||||
Logger.info(`[PodcastManager] Found ${newEpisodes.length} new episodes for podcast "${libraryItem.media.metadata.title}" - starting download`)
|
||||
this.downloadPodcastEpisodes(libraryItem, newEpisodes, true)
|
||||
} else {
|
||||
delete this.failedCheckMap[libraryItem.id]
|
||||
Logger.debug(`[PodcastManager] No new episodes for "${libraryItem.media.metadata.title}"`)
|
||||
Logger.warn(`[PodcastManager] runEpisodeCheck ${this.failedCheckMap[libraryItem.id]} failed attempts at checking episodes for "${libraryItem.media.metadata.title}"`)
|
||||
}
|
||||
|
||||
libraryItem.media.lastEpisodeCheck = Date.now()
|
||||
libraryItem.updatedAt = Date.now()
|
||||
await this.db.updateLibraryItem(libraryItem)
|
||||
this.emitter('item_updated', libraryItem.toJSONExpanded())
|
||||
} else if (newEpisodes.length) {
|
||||
delete this.failedCheckMap[libraryItem.id]
|
||||
Logger.info(`[PodcastManager] Found ${newEpisodes.length} new episodes for podcast "${libraryItem.media.metadata.title}" - starting download`)
|
||||
this.downloadPodcastEpisodes(libraryItem, newEpisodes, true)
|
||||
} else {
|
||||
delete this.failedCheckMap[libraryItem.id]
|
||||
Logger.debug(`[PodcastManager] No new episodes for "${libraryItem.media.metadata.title}"`)
|
||||
}
|
||||
|
||||
libraryItem.media.lastEpisodeCheck = Date.now()
|
||||
libraryItem.updatedAt = Date.now()
|
||||
await this.db.updateLibraryItem(libraryItem)
|
||||
this.emitter('item_updated', libraryItem.toJSONExpanded())
|
||||
return libraryItem.media.autoDownloadEpisodes
|
||||
}
|
||||
|
||||
async checkPodcastForNewEpisodes(podcastLibraryItem, dateToCheckForEpisodesAfter) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue