mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-22 11:49:37 +00:00
Add:RSS feed for series & cleanup empty series from db #1265
This commit is contained in:
parent
a364fe5031
commit
70ba2f7850
14 changed files with 282 additions and 32 deletions
|
|
@ -375,6 +375,9 @@ class LibraryController {
|
|||
// api/libraries/:id/series
|
||||
async getAllSeriesForLibrary(req, res) {
|
||||
const libraryItems = req.libraryItems
|
||||
|
||||
const include = (req.query.include || '').split(',').map(v => v.trim().toLowerCase()).filter(v => !!v)
|
||||
|
||||
const payload = {
|
||||
results: [],
|
||||
total: 0,
|
||||
|
|
@ -383,7 +386,8 @@ class LibraryController {
|
|||
sortBy: req.query.sort,
|
||||
sortDesc: req.query.desc === '1',
|
||||
filterBy: req.query.filter,
|
||||
minified: req.query.minified === '1'
|
||||
minified: req.query.minified === '1',
|
||||
include: include.join(',')
|
||||
}
|
||||
|
||||
let series = libraryHelpers.getSeriesFromBooks(libraryItems, this.db.series, null, payload.filterBy, req.user, payload.minified)
|
||||
|
|
@ -408,10 +412,19 @@ class LibraryController {
|
|||
payload.total = series.length
|
||||
|
||||
if (payload.limit) {
|
||||
var startIndex = payload.page * payload.limit
|
||||
const startIndex = payload.page * payload.limit
|
||||
series = series.slice(startIndex, startIndex + payload.limit)
|
||||
}
|
||||
|
||||
// add rssFeed when "include=rssfeed" is in query string
|
||||
if (include.includes('rssfeed')) {
|
||||
series = series.map((se) => {
|
||||
const feedData = this.rssFeedManager.findFeedForEntityId(se.id)
|
||||
se.rssFeed = feedData?.toJSONMinified() || null
|
||||
return se
|
||||
})
|
||||
}
|
||||
|
||||
payload.results = series
|
||||
res.json(payload)
|
||||
}
|
||||
|
|
@ -442,7 +455,7 @@ class LibraryController {
|
|||
|
||||
if (include.includes('rssfeed')) {
|
||||
const feedData = this.rssFeedManager.findFeedForEntityId(c.id)
|
||||
expanded.rssFeed = feedData ? feedData.toJSONMinified() : null
|
||||
expanded.rssFeed = feedData?.toJSONMinified() || null
|
||||
}
|
||||
|
||||
return expanded
|
||||
|
|
|
|||
|
|
@ -92,10 +92,23 @@ class LibraryItemController {
|
|||
}
|
||||
}
|
||||
|
||||
// Book specific - Get all series being removed from this item
|
||||
let seriesRemoved = []
|
||||
if (libraryItem.isBook && mediaPayload.metadata?.series) {
|
||||
const seriesIdsInUpdate = (mediaPayload.metadata?.series || []).map(se => se.id)
|
||||
seriesRemoved = libraryItem.media.metadata.series.filter(se => !seriesIdsInUpdate.includes(se.id))
|
||||
}
|
||||
|
||||
const hasUpdates = libraryItem.media.update(mediaPayload)
|
||||
if (hasUpdates) {
|
||||
libraryItem.updatedAt = Date.now()
|
||||
|
||||
if (seriesRemoved.length) {
|
||||
// Check remove empty series
|
||||
Logger.debug(`[LibraryItemController] Series was removed from book. Check if series is now empty.`)
|
||||
await this.checkRemoveEmptySeries(seriesRemoved)
|
||||
}
|
||||
|
||||
if (isPodcastAutoDownloadUpdated) {
|
||||
this.cronManager.checkUpdatePodcastCron(libraryItem)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,41 @@ class RSSFeedController {
|
|||
})
|
||||
}
|
||||
|
||||
// POST: api/feeds/series/:seriesId/open
|
||||
async openRSSFeedForSeries(req, res) {
|
||||
const options = req.body || {}
|
||||
|
||||
const series = this.db.series.find(se => se.id === req.params.seriesId)
|
||||
if (!series) return res.sendStatus(404)
|
||||
|
||||
// Check request body options exist
|
||||
if (!options.serverAddress || !options.slug) {
|
||||
Logger.error(`[RSSFeedController] Invalid request body to open RSS feed`)
|
||||
return res.status(400).send('Invalid request body')
|
||||
}
|
||||
|
||||
// Check that this slug is not being used for another feed (slug will also be the Feed id)
|
||||
if (this.rssFeedManager.feeds[options.slug]) {
|
||||
Logger.error(`[RSSFeedController] Cannot open RSS feed because slug "${options.slug}" is already in use`)
|
||||
return res.status(400).send('Slug already in use')
|
||||
}
|
||||
|
||||
const seriesJson = series.toJSON()
|
||||
// Get books in series that have audio tracks
|
||||
seriesJson.books = this.db.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasSeries(series.id) && li.media.tracks.length)
|
||||
|
||||
// Check series has audio tracks
|
||||
if (!seriesJson.books.length) {
|
||||
Logger.error(`[RSSFeedController] Cannot open RSS feed for series "${seriesJson.name}" because it has no audio tracks`)
|
||||
return res.status(400).send('Series has no audio tracks')
|
||||
}
|
||||
|
||||
const feed = await this.rssFeedManager.openFeedForSeries(req.user, seriesJson, req.body)
|
||||
res.json({
|
||||
feed: feed.toJSONMinified()
|
||||
})
|
||||
}
|
||||
|
||||
// POST: api/feeds/:id/close
|
||||
async closeRSSFeed(req, res) {
|
||||
await this.rssFeedManager.closeRssFeed(req.params.id)
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@ class SeriesController {
|
|||
constructor() { }
|
||||
|
||||
async findOne(req, res) {
|
||||
var include = (req.query.include || '').split(',')
|
||||
const include = (req.query.include || '').split(',').map(v => v.trim()).filter(v => !!v)
|
||||
|
||||
var seriesJson = req.series.toJSON()
|
||||
const seriesJson = req.series.toJSON()
|
||||
|
||||
// Add progress map with isFinished flag
|
||||
if (include.includes('progress')) {
|
||||
var libraryItemsInSeries = this.db.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasSeries(seriesJson.id))
|
||||
var libraryItemsFinished = libraryItemsInSeries.filter(li => {
|
||||
var mediaProgress = req.user.getMediaProgress(li.id)
|
||||
const libraryItemsInSeries = this.db.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasSeries(seriesJson.id))
|
||||
const libraryItemsFinished = libraryItemsInSeries.filter(li => {
|
||||
const mediaProgress = req.user.getMediaProgress(li.id)
|
||||
return mediaProgress && mediaProgress.isFinished
|
||||
})
|
||||
seriesJson.progress = {
|
||||
|
|
@ -23,6 +23,11 @@ class SeriesController {
|
|||
}
|
||||
}
|
||||
|
||||
if (include.includes('rssfeed')) {
|
||||
const feedObj = this.rssFeedManager.findFeedForEntityId(seriesJson.id)
|
||||
seriesJson.rssFeed = feedObj?.toJSONMinified() || null
|
||||
}
|
||||
|
||||
return res.json(seriesJson)
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +52,7 @@ class SeriesController {
|
|||
}
|
||||
|
||||
middleware(req, res, next) {
|
||||
var series = this.db.series.find(se => se.id === req.params.id)
|
||||
const series = this.db.series.find(se => se.id === req.params.id)
|
||||
if (!series) return res.sendStatus(404)
|
||||
|
||||
if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue