mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-03 00:06:46 +01:00
Update PluginManager to singleton, update PluginContext, support prompt object in plugin extension
This commit is contained in:
parent
a762e6ca03
commit
50e84fc2d5
@ -7,6 +7,14 @@
|
|||||||
|
|
||||||
<ui-checkbox v-if="checkboxLabel" v-model="checkboxValue" checkbox-bg="bg" :label="checkboxLabel" label-class="pl-2 text-base" class="mb-6 px-1" />
|
<ui-checkbox v-if="checkboxLabel" v-model="checkboxValue" checkbox-bg="bg" :label="checkboxLabel" label-class="pl-2 text-base" class="mb-6 px-1" />
|
||||||
|
|
||||||
|
<div v-if="formFields.length" class="mb-6 space-y-2">
|
||||||
|
<template v-for="field in formFields">
|
||||||
|
<ui-select-input v-if="field.type === 'select'" :key="field.name" v-model="formData[field.name]" :label="field.label" :items="field.options" class="px-1" />
|
||||||
|
<ui-textarea-with-label v-else-if="field.type === 'textarea'" :key="field.name" v-model="formData[field.name]" :label="field.label" class="px-1" />
|
||||||
|
<ui-text-input-with-label v-else-if="field.type === 'text'" :key="field.name" v-model="formData[field.name]" :label="field.label" class="px-1" />
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex px-1 items-center">
|
<div class="flex px-1 items-center">
|
||||||
<ui-btn v-if="isYesNo" color="primary" @click="nevermind">{{ $strings.ButtonCancel }}</ui-btn>
|
<ui-btn v-if="isYesNo" color="primary" @click="nevermind">{{ $strings.ButtonCancel }}</ui-btn>
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
@ -25,7 +33,8 @@ export default {
|
|||||||
return {
|
return {
|
||||||
el: null,
|
el: null,
|
||||||
content: null,
|
content: null,
|
||||||
checkboxValue: false
|
checkboxValue: false,
|
||||||
|
formData: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -61,6 +70,9 @@ export default {
|
|||||||
persistent() {
|
persistent() {
|
||||||
return !!this.confirmPromptOptions.persistent
|
return !!this.confirmPromptOptions.persistent
|
||||||
},
|
},
|
||||||
|
formFields() {
|
||||||
|
return this.confirmPromptOptions.formFields || []
|
||||||
|
},
|
||||||
checkboxLabel() {
|
checkboxLabel() {
|
||||||
return this.confirmPromptOptions.checkboxLabel
|
return this.confirmPromptOptions.checkboxLabel
|
||||||
},
|
},
|
||||||
@ -100,11 +112,31 @@ export default {
|
|||||||
this.show = false
|
this.show = false
|
||||||
},
|
},
|
||||||
confirm() {
|
confirm() {
|
||||||
if (this.callback) this.callback(true, this.checkboxValue)
|
if (this.callback) {
|
||||||
|
if (this.formFields.length) {
|
||||||
|
const formFieldData = {
|
||||||
|
...this.formData
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callback(true, formFieldData)
|
||||||
|
} else {
|
||||||
|
this.callback(true, this.checkboxValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
this.show = false
|
this.show = false
|
||||||
},
|
},
|
||||||
setShow() {
|
setShow() {
|
||||||
this.checkboxValue = this.checkboxDefaultValue
|
this.checkboxValue = this.checkboxDefaultValue
|
||||||
|
|
||||||
|
if (this.formFields.length) {
|
||||||
|
this.formFields.forEach((field) => {
|
||||||
|
let defaultValue = ''
|
||||||
|
if (field.type === 'boolean') defaultValue = false
|
||||||
|
if (field.type === 'select') defaultValue = field.options[0].value
|
||||||
|
this.$set(this.formData, field.name, defaultValue)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.$eventBus.$emit('showing-prompt', true)
|
this.$eventBus.$emit('showing-prompt', true)
|
||||||
document.body.appendChild(this.el)
|
document.body.appendChild(this.el)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -12,10 +12,14 @@
|
|||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
||||||
|
<div class="flex-grow" />
|
||||||
|
|
||||||
|
<a v-if="repositoryUrl" :href="repositoryUrl" target="_blank" class="abs-btn outline-none rounded-md shadow-md relative border border-gray-600 text-center bg-primary text-white px-4 py-1 text-sm inline-flex items-center space-x-2"><span>Source</span><span class="material-symbols text-base">open_in_new</span> </a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="py-4">
|
<div class="py-4">
|
||||||
<p class="mb-4">{{ configDescription }}</p>
|
<p v-if="configDescription" class="mb-4">{{ configDescription }}</p>
|
||||||
|
|
||||||
<form v-if="configFormFields.length" @submit.prevent="handleFormSubmit">
|
<form v-if="configFormFields.length" @submit.prevent="handleFormSubmit">
|
||||||
<template v-for="field in configFormFields">
|
<template v-for="field in configFormFields">
|
||||||
@ -46,7 +50,7 @@ export default {
|
|||||||
console.error('Failed to get plugin config', error)
|
console.error('Failed to get plugin config', error)
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
if (!pluginConfigData?.config) {
|
if (!pluginConfigData) {
|
||||||
redirect('/config/plugins')
|
redirect('/config/plugins')
|
||||||
}
|
}
|
||||||
const pluginManifest = store.state.plugins.find((plugin) => plugin.id === params.id)
|
const pluginManifest = store.state.plugins.find((plugin) => plugin.id === params.id)
|
||||||
@ -84,6 +88,9 @@ export default {
|
|||||||
},
|
},
|
||||||
configFormFields() {
|
configFormFields() {
|
||||||
return this.pluginManifestConfig.formFields || []
|
return this.pluginManifestConfig.formFields || []
|
||||||
|
},
|
||||||
|
repositoryUrl() {
|
||||||
|
return this.pluginManifest.repositoryUrl
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -123,6 +130,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
initializeForm() {
|
initializeForm() {
|
||||||
|
if (!this.pluginConfig) return
|
||||||
this.configFormFields.forEach((field) => {
|
this.configFormFields.forEach((field) => {
|
||||||
if (this.pluginConfig[field.name] === undefined) {
|
if (this.pluginConfig[field.name] === undefined) {
|
||||||
return
|
return
|
||||||
|
@ -12,11 +12,13 @@
|
|||||||
<p v-if="!plugins.length" class="text-gray-300">No plugins installed</p>
|
<p v-if="!plugins.length" class="text-gray-300">No plugins installed</p>
|
||||||
|
|
||||||
<template v-for="plugin in plugins">
|
<template v-for="plugin in plugins">
|
||||||
<nuxt-link :key="plugin.id" :to="`/config/plugins/${plugin.id}`" class="flex items-center bg-primary rounded-md shadow-sm p-4 my-4 space-x-4">
|
<nuxt-link :key="plugin.id" :to="`/config/plugins/${plugin.id}`" class="block w-full rounded bg-primary/40 hover:bg-primary/60 text-gray-300 hover:text-white p-4 my-2">
|
||||||
<p class="text-lg">{{ plugin.name }}</p>
|
<div class="flex items-center space-x-4">
|
||||||
<p class="text-sm text-gray-300">{{ plugin.description }}</p>
|
<p class="text-lg">{{ plugin.name }}</p>
|
||||||
<div class="flex-grow" />
|
<p class="text-sm text-gray-300">{{ plugin.description }}</p>
|
||||||
<span class="material-symbols text-4xl">chevron_right</span>
|
<div class="flex-grow" />
|
||||||
|
<span class="material-symbols">arrow_forward</span>
|
||||||
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -786,13 +786,35 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onPluginAction(pluginId, pluginAction) {
|
onPluginAction(pluginId, pluginAction) {
|
||||||
|
const plugin = this.pluginExtensions.find((p) => p.id === pluginId)
|
||||||
|
const extension = plugin.extensions.find((ext) => ext.name === pluginAction)
|
||||||
|
|
||||||
|
if (extension.prompt) {
|
||||||
|
const payload = {
|
||||||
|
message: extension.prompt.message,
|
||||||
|
formFields: extension.prompt.formFields || [],
|
||||||
|
callback: (confirmed, promptData) => {
|
||||||
|
if (confirmed) {
|
||||||
|
this.sendPluginAction(pluginId, pluginAction, promptData)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type: 'yesNo'
|
||||||
|
}
|
||||||
|
this.$store.commit('globals/setConfirmPrompt', payload)
|
||||||
|
} else {
|
||||||
|
this.sendPluginAction(pluginId, pluginAction)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sendPluginAction(pluginId, pluginAction, promptData = null) {
|
||||||
this.$axios
|
this.$axios
|
||||||
.$post(`/api/plugins/${pluginId}/action`, {
|
.$post(`/api/plugins/${pluginId}/action`, {
|
||||||
pluginAction,
|
pluginAction,
|
||||||
target: 'item.detail.actions',
|
target: 'item.detail.actions',
|
||||||
data: {
|
data: {
|
||||||
entityId: this.libraryItemId,
|
entityId: this.libraryItemId,
|
||||||
entityType: 'libraryItem'
|
entityType: 'libraryItem',
|
||||||
|
userId: this.$store.state.user.user.id,
|
||||||
|
promptData
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
|
@ -940,7 +940,17 @@ class Auth {
|
|||||||
userDefaultLibraryId: user.getDefaultLibraryId(libraryIds),
|
userDefaultLibraryId: user.getDefaultLibraryId(libraryIds),
|
||||||
serverSettings: Database.serverSettings.toJSONForBrowser(),
|
serverSettings: Database.serverSettings.toJSONForBrowser(),
|
||||||
ereaderDevices: Database.emailSettings.getEReaderDevices(user),
|
ereaderDevices: Database.emailSettings.getEReaderDevices(user),
|
||||||
plugins: this.pluginManifests,
|
// TODO: Should be better handled by the PluginManager
|
||||||
|
// restrict plugin extensions that are not allowed for the user type
|
||||||
|
plugins: this.pluginManifests.map((manifest) => {
|
||||||
|
const manifestExtensions = (manifest.extensions || []).filter((ext) => {
|
||||||
|
if (ext.restrictToAccountTypes?.length) {
|
||||||
|
return ext.restrictToAccountTypes.includes(user.type)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return { ...manifest, extensions: manifestExtensions }
|
||||||
|
}),
|
||||||
Source: global.Source
|
Source: global.Source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ const AbMergeManager = require('./managers/AbMergeManager')
|
|||||||
const CacheManager = require('./managers/CacheManager')
|
const CacheManager = require('./managers/CacheManager')
|
||||||
const BackupManager = require('./managers/BackupManager')
|
const BackupManager = require('./managers/BackupManager')
|
||||||
const PlaybackSessionManager = require('./managers/PlaybackSessionManager')
|
const PlaybackSessionManager = require('./managers/PlaybackSessionManager')
|
||||||
const PodcastManager = require('./managers/PodcastManager')
|
|
||||||
const AudioMetadataMangaer = require('./managers/AudioMetadataManager')
|
const AudioMetadataMangaer = require('./managers/AudioMetadataManager')
|
||||||
const RssFeedManager = require('./managers/RssFeedManager')
|
const RssFeedManager = require('./managers/RssFeedManager')
|
||||||
const CronManager = require('./managers/CronManager')
|
const CronManager = require('./managers/CronManager')
|
||||||
@ -70,9 +69,8 @@ class Server {
|
|||||||
this.backupManager = new BackupManager()
|
this.backupManager = new BackupManager()
|
||||||
this.abMergeManager = new AbMergeManager()
|
this.abMergeManager = new AbMergeManager()
|
||||||
this.playbackSessionManager = new PlaybackSessionManager()
|
this.playbackSessionManager = new PlaybackSessionManager()
|
||||||
this.podcastManager = new PodcastManager()
|
|
||||||
this.audioMetadataManager = new AudioMetadataMangaer()
|
this.audioMetadataManager = new AudioMetadataMangaer()
|
||||||
this.cronManager = new CronManager(this.podcastManager, this.playbackSessionManager)
|
this.cronManager = new CronManager(this.playbackSessionManager)
|
||||||
this.apiCacheManager = new ApiCacheManager()
|
this.apiCacheManager = new ApiCacheManager()
|
||||||
this.binaryManager = new BinaryManager()
|
this.binaryManager = new BinaryManager()
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const Scanner = require('../scanner/Scanner')
|
|||||||
const Database = require('../Database')
|
const Database = require('../Database')
|
||||||
const Watcher = require('../Watcher')
|
const Watcher = require('../Watcher')
|
||||||
const RssFeedManager = require('../managers/RssFeedManager')
|
const RssFeedManager = require('../managers/RssFeedManager')
|
||||||
|
const PodcastManager = require('../managers/PodcastManager')
|
||||||
|
|
||||||
const libraryFilters = require('../utils/queries/libraryFilters')
|
const libraryFilters = require('../utils/queries/libraryFilters')
|
||||||
const libraryItemsPodcastFilters = require('../utils/queries/libraryItemsPodcastFilters')
|
const libraryItemsPodcastFilters = require('../utils/queries/libraryItemsPodcastFilters')
|
||||||
@ -219,7 +220,7 @@ class LibraryController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async getEpisodeDownloadQueue(req, res) {
|
async getEpisodeDownloadQueue(req, res) {
|
||||||
const libraryDownloadQueueDetails = this.podcastManager.getDownloadQueueDetails(req.library.id)
|
const libraryDownloadQueueDetails = PodcastManager.getDownloadQueueDetails(req.library.id)
|
||||||
res.json(libraryDownloadQueueDetails)
|
res.json(libraryDownloadQueueDetails)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,7 +1289,7 @@ class LibraryController {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const opmlText = this.podcastManager.generateOPMLFileText(podcasts)
|
const opmlText = PodcastManager.generateOPMLFileText(podcasts)
|
||||||
res.type('application/xml')
|
res.type('application/xml')
|
||||||
res.send(opmlText)
|
res.send(opmlText)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ const RssFeedManager = require('../managers/RssFeedManager')
|
|||||||
const CacheManager = require('../managers/CacheManager')
|
const CacheManager = require('../managers/CacheManager')
|
||||||
const CoverManager = require('../managers/CoverManager')
|
const CoverManager = require('../managers/CoverManager')
|
||||||
const ShareManager = require('../managers/ShareManager')
|
const ShareManager = require('../managers/ShareManager')
|
||||||
|
const PodcastManager = require('../managers/PodcastManager')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef RequestUserObject
|
* @typedef RequestUserObject
|
||||||
@ -59,10 +60,10 @@ class LibraryItemController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (item.mediaType === 'podcast' && includeEntities.includes('downloads')) {
|
if (item.mediaType === 'podcast' && includeEntities.includes('downloads')) {
|
||||||
const downloadsInQueue = this.podcastManager.getEpisodeDownloadsInQueue(req.libraryItem.id)
|
const downloadsInQueue = PodcastManager.getEpisodeDownloadsInQueue(req.libraryItem.id)
|
||||||
item.episodeDownloadsQueued = downloadsInQueue.map((d) => d.toJSONForClient())
|
item.episodeDownloadsQueued = downloadsInQueue.map((d) => d.toJSONForClient())
|
||||||
if (this.podcastManager.currentDownload?.libraryItemId === req.libraryItem.id) {
|
if (PodcastManager.currentDownload?.libraryItemId === req.libraryItem.id) {
|
||||||
item.episodesDownloading = [this.podcastManager.currentDownload.toJSONForClient()]
|
item.episodesDownloading = [PodcastManager.currentDownload.toJSONForClient()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ const { validateUrl } = require('../utils/index')
|
|||||||
|
|
||||||
const Scanner = require('../scanner/Scanner')
|
const Scanner = require('../scanner/Scanner')
|
||||||
const CoverManager = require('../managers/CoverManager')
|
const CoverManager = require('../managers/CoverManager')
|
||||||
|
const PodcastManager = require('../managers/PodcastManager')
|
||||||
|
|
||||||
const LibraryItem = require('../objects/LibraryItem')
|
const LibraryItem = require('../objects/LibraryItem')
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ class PodcastController {
|
|||||||
|
|
||||||
if (payload.episodesToDownload?.length) {
|
if (payload.episodesToDownload?.length) {
|
||||||
Logger.info(`[PodcastController] Podcast created now starting ${payload.episodesToDownload.length} episode downloads`)
|
Logger.info(`[PodcastController] Podcast created now starting ${payload.episodesToDownload.length} episode downloads`)
|
||||||
this.podcastManager.downloadPodcastEpisodes(libraryItem, payload.episodesToDownload)
|
PodcastManager.downloadPodcastEpisodes(libraryItem, payload.episodesToDownload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn on podcast auto download cron if not already on
|
// Turn on podcast auto download cron if not already on
|
||||||
@ -169,7 +170,7 @@ class PodcastController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
feeds: this.podcastManager.getParsedOPMLFileFeeds(req.body.opmlText)
|
feeds: PodcastManager.getParsedOPMLFileFeeds(req.body.opmlText)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +204,7 @@ class PodcastController {
|
|||||||
return res.status(404).send('Folder not found')
|
return res.status(404).send('Folder not found')
|
||||||
}
|
}
|
||||||
const autoDownloadEpisodes = !!req.body.autoDownloadEpisodes
|
const autoDownloadEpisodes = !!req.body.autoDownloadEpisodes
|
||||||
this.podcastManager.createPodcastsFromFeedUrls(rssFeeds, folder, autoDownloadEpisodes, this.cronManager)
|
PodcastManager.createPodcastsFromFeedUrls(rssFeeds, folder, autoDownloadEpisodes, this.cronManager)
|
||||||
|
|
||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
}
|
}
|
||||||
@ -230,7 +231,7 @@ class PodcastController {
|
|||||||
|
|
||||||
const maxEpisodesToDownload = !isNaN(req.query.limit) ? Number(req.query.limit) : 3
|
const maxEpisodesToDownload = !isNaN(req.query.limit) ? Number(req.query.limit) : 3
|
||||||
|
|
||||||
var newEpisodes = await this.podcastManager.checkAndDownloadNewEpisodes(libraryItem, maxEpisodesToDownload)
|
var newEpisodes = await PodcastManager.checkAndDownloadNewEpisodes(libraryItem, maxEpisodesToDownload)
|
||||||
res.json({
|
res.json({
|
||||||
episodes: newEpisodes || []
|
episodes: newEpisodes || []
|
||||||
})
|
})
|
||||||
@ -239,8 +240,6 @@ class PodcastController {
|
|||||||
/**
|
/**
|
||||||
* GET: /api/podcasts/:id/clear-queue
|
* GET: /api/podcasts/:id/clear-queue
|
||||||
*
|
*
|
||||||
* @this {import('../routers/ApiRouter')}
|
|
||||||
*
|
|
||||||
* @param {RequestWithUser} req
|
* @param {RequestWithUser} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
@ -249,22 +248,20 @@ class PodcastController {
|
|||||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempting to clear download queue`)
|
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempting to clear download queue`)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
}
|
}
|
||||||
this.podcastManager.clearDownloadQueue(req.params.id)
|
PodcastManager.clearDownloadQueue(req.params.id)
|
||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET: /api/podcasts/:id/downloads
|
* GET: /api/podcasts/:id/downloads
|
||||||
*
|
*
|
||||||
* @this {import('../routers/ApiRouter')}
|
|
||||||
*
|
|
||||||
* @param {RequestWithUser} req
|
* @param {RequestWithUser} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
getEpisodeDownloads(req, res) {
|
getEpisodeDownloads(req, res) {
|
||||||
var libraryItem = req.libraryItem
|
var libraryItem = req.libraryItem
|
||||||
|
|
||||||
var downloadsInQueue = this.podcastManager.getEpisodeDownloadsInQueue(libraryItem.id)
|
var downloadsInQueue = PodcastManager.getEpisodeDownloadsInQueue(libraryItem.id)
|
||||||
res.json({
|
res.json({
|
||||||
downloads: downloadsInQueue.map((d) => d.toJSONForClient())
|
downloads: downloadsInQueue.map((d) => d.toJSONForClient())
|
||||||
})
|
})
|
||||||
@ -290,8 +287,6 @@ class PodcastController {
|
|||||||
/**
|
/**
|
||||||
* POST: /api/podcasts/:id/download-episodes
|
* POST: /api/podcasts/:id/download-episodes
|
||||||
*
|
*
|
||||||
* @this {import('../routers/ApiRouter')}
|
|
||||||
*
|
|
||||||
* @param {RequestWithUser} req
|
* @param {RequestWithUser} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
@ -306,7 +301,7 @@ class PodcastController {
|
|||||||
return res.sendStatus(400)
|
return res.sendStatus(400)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.podcastManager.downloadPodcastEpisodes(libraryItem, episodes)
|
PodcastManager.downloadPodcastEpisodes(libraryItem, episodes)
|
||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,11 +5,10 @@ const Database = require('../Database')
|
|||||||
const LibraryScanner = require('../scanner/LibraryScanner')
|
const LibraryScanner = require('../scanner/LibraryScanner')
|
||||||
|
|
||||||
const ShareManager = require('./ShareManager')
|
const ShareManager = require('./ShareManager')
|
||||||
|
const PodcastManager = require('./PodcastManager')
|
||||||
|
|
||||||
class CronManager {
|
class CronManager {
|
||||||
constructor(podcastManager, playbackSessionManager) {
|
constructor(playbackSessionManager) {
|
||||||
/** @type {import('./PodcastManager')} */
|
|
||||||
this.podcastManager = podcastManager
|
|
||||||
/** @type {import('./PlaybackSessionManager')} */
|
/** @type {import('./PlaybackSessionManager')} */
|
||||||
this.playbackSessionManager = playbackSessionManager
|
this.playbackSessionManager = playbackSessionManager
|
||||||
|
|
||||||
@ -163,7 +162,7 @@ class CronManager {
|
|||||||
task
|
task
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(`[PodcastManager] Failed to schedule podcast cron ${this.serverSettings.podcastEpisodeSchedule}`, error)
|
Logger.error(`[CronManager] Failed to schedule podcast cron ${this.serverSettings.podcastEpisodeSchedule}`, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +191,7 @@ class CronManager {
|
|||||||
|
|
||||||
// Run episode checks
|
// Run episode checks
|
||||||
for (const libraryItem of libraryItems) {
|
for (const libraryItem of libraryItems) {
|
||||||
const keepAutoDownloading = await this.podcastManager.runEpisodeCheck(libraryItem)
|
const keepAutoDownloading = await PodcastManager.runEpisodeCheck(libraryItem)
|
||||||
if (!keepAutoDownloading) {
|
if (!keepAutoDownloading) {
|
||||||
// auto download was disabled
|
// auto download was disabled
|
||||||
podcastCron.libraryItemIds = podcastCron.libraryItemIds.filter((lid) => lid !== libraryItem.id) // Filter it out
|
podcastCron.libraryItemIds = podcastCron.libraryItemIds.filter((lid) => lid !== libraryItem.id) // Filter it out
|
||||||
|
@ -3,6 +3,9 @@ const Logger = require('../Logger')
|
|||||||
const Database = require('../Database')
|
const Database = require('../Database')
|
||||||
const SocketAuthority = require('../SocketAuthority')
|
const SocketAuthority = require('../SocketAuthority')
|
||||||
const TaskManager = require('../managers/TaskManager')
|
const TaskManager = require('../managers/TaskManager')
|
||||||
|
const ShareManager = require('../managers/ShareManager')
|
||||||
|
const RssFeedManager = require('../managers/RssFeedManager')
|
||||||
|
const PodcastManager = require('../managers/PodcastManager')
|
||||||
const fsExtra = require('../libs/fsExtra')
|
const fsExtra = require('../libs/fsExtra')
|
||||||
const { isUUID, parseSemverStrict } = require('../utils')
|
const { isUUID, parseSemverStrict } = require('../utils')
|
||||||
|
|
||||||
@ -13,6 +16,9 @@ const { isUUID, parseSemverStrict } = require('../utils')
|
|||||||
* @property {import('../SocketAuthority')} SocketAuthority
|
* @property {import('../SocketAuthority')} SocketAuthority
|
||||||
* @property {import('../managers/TaskManager')} TaskManager
|
* @property {import('../managers/TaskManager')} TaskManager
|
||||||
* @property {import('../models/Plugin')} pluginInstance
|
* @property {import('../models/Plugin')} pluginInstance
|
||||||
|
* @property {import('../managers/ShareManager')} ShareManager
|
||||||
|
* @property {import('../managers/RssFeedManager')} RssFeedManager
|
||||||
|
* @property {import('../managers/PodcastManager')} PodcastManager
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,7 +56,10 @@ class PluginManager {
|
|||||||
Database,
|
Database,
|
||||||
SocketAuthority,
|
SocketAuthority,
|
||||||
TaskManager,
|
TaskManager,
|
||||||
pluginInstance
|
pluginInstance,
|
||||||
|
ShareManager,
|
||||||
|
RssFeedManager,
|
||||||
|
PodcastManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,4 +586,4 @@ class PodcastManager {
|
|||||||
Logger.info(`[PodcastManager] createPodcastsFromFeedUrls: Finished OPML import. Created ${numPodcastsAdded} podcasts out of ${rssFeedUrls.length} RSS feed URLs`)
|
Logger.info(`[PodcastManager] createPodcastsFromFeedUrls: Finished OPML import. Created ${numPodcastsAdded} podcasts out of ${rssFeedUrls.length} RSS feed URLs`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = PodcastManager
|
module.exports = new PodcastManager()
|
||||||
|
@ -47,8 +47,6 @@ class ApiRouter {
|
|||||||
this.abMergeManager = Server.abMergeManager
|
this.abMergeManager = Server.abMergeManager
|
||||||
/** @type {import('../managers/BackupManager')} */
|
/** @type {import('../managers/BackupManager')} */
|
||||||
this.backupManager = Server.backupManager
|
this.backupManager = Server.backupManager
|
||||||
/** @type {import('../managers/PodcastManager')} */
|
|
||||||
this.podcastManager = Server.podcastManager
|
|
||||||
/** @type {import('../managers/AudioMetadataManager')} */
|
/** @type {import('../managers/AudioMetadataManager')} */
|
||||||
this.audioMetadataManager = Server.audioMetadataManager
|
this.audioMetadataManager = Server.audioMetadataManager
|
||||||
/** @type {import('../managers/CronManager')} */
|
/** @type {import('../managers/CronManager')} */
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"repositoryUrl": "https://github.com/example/example-plugin",
|
"repositoryUrl": "https://github.com/example/example-plugin",
|
||||||
"documentationUrl": "https://example.com",
|
"documentationUrl": "https://example.com",
|
||||||
"description": "This is an example plugin",
|
"description": "This is an example plugin",
|
||||||
|
"descriptionKey": "ExamplePluginDescription",
|
||||||
"extensions": [
|
"extensions": [
|
||||||
{
|
{
|
||||||
"target": "item.detail.actions",
|
"target": "item.detail.actions",
|
||||||
@ -22,8 +23,7 @@
|
|||||||
"name": "requestAddress",
|
"name": "requestAddress",
|
||||||
"label": "Request Address",
|
"label": "Request Address",
|
||||||
"labelKey": "LabelRequestAddress",
|
"labelKey": "LabelRequestAddress",
|
||||||
"type": "text",
|
"type": "text"
|
||||||
"required": true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "enable",
|
"name": "enable",
|
||||||
@ -34,7 +34,8 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"localization": {
|
"localization": {
|
||||||
"en-us": {
|
"de": {
|
||||||
|
"ExamplePluginDescription": "Dies ist ein Beispiel-Plugin",
|
||||||
"ItemExampleAction": "Item Example Action",
|
"ItemExampleAction": "Item Example Action",
|
||||||
"LabelEnable": "Enable",
|
"LabelEnable": "Enable",
|
||||||
"ExamplePluginConfigurationDescription": "This is a description on how to configure the plugin",
|
"ExamplePluginConfigurationDescription": "This is a description on how to configure the plugin",
|
||||||
@ -46,7 +47,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"changelog": "Initial release",
|
"changelog": "Initial release",
|
||||||
"timestamp": "2022-01-01T00:00:00Z",
|
"timestamp": "2022-01-01T00:00:00Z",
|
||||||
"sourceUrl": ""
|
"downloadUrl": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user