mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-28 16:59:21 +01:00
Update recent-episodes API route to load from db
This commit is contained in:
parent
f21d69339f
commit
8d451217a3
@ -59,6 +59,16 @@ class Database {
|
||||
return this.models.libraryItem
|
||||
}
|
||||
|
||||
/** @type {typeof import('./models/PodcastEpisode')} */
|
||||
get podcastEpisodeModel() {
|
||||
return this.models.podcastEpisode
|
||||
}
|
||||
|
||||
/** @type {typeof import('./models/MediaProgress')} */
|
||||
get mediaProgressModel() {
|
||||
return this.models.mediaProgress
|
||||
}
|
||||
|
||||
async checkHasDb() {
|
||||
if (!await fs.pathExists(this.dbPath)) {
|
||||
Logger.info(`[Database] absdatabase.sqlite not found at ${this.dbPath}`)
|
||||
|
@ -16,6 +16,7 @@ const naturalSort = createNewSortInstance({
|
||||
|
||||
const Database = require('../Database')
|
||||
const libraryFilters = require('../utils/queries/libraryFilters')
|
||||
const libraryItemsPodcastFilters = require('../utils/queries/libraryItemsPodcastFilters')
|
||||
|
||||
class LibraryController {
|
||||
constructor() { }
|
||||
@ -1024,7 +1025,12 @@ class LibraryController {
|
||||
Logger.info('[LibraryController] Scan complete')
|
||||
}
|
||||
|
||||
// GET: api/libraries/:id/recent-episode
|
||||
/**
|
||||
* GET: /api/libraries/:id/recent-episodes
|
||||
* Used for latest page
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async getRecentEpisodes(req, res) {
|
||||
if (!req.library.isPodcast) {
|
||||
return res.sendStatus(404)
|
||||
@ -1032,35 +1038,12 @@ class LibraryController {
|
||||
|
||||
const payload = {
|
||||
episodes: [],
|
||||
total: 0,
|
||||
limit: req.query.limit && !isNaN(req.query.limit) ? Number(req.query.limit) : 0,
|
||||
page: req.query.page && !isNaN(req.query.page) ? Number(req.query.page) : 0,
|
||||
}
|
||||
|
||||
var allUnfinishedEpisodes = []
|
||||
for (const libraryItem of req.libraryItems) {
|
||||
const unfinishedEpisodes = libraryItem.media.episodes.filter(ep => {
|
||||
const userProgress = req.user.getMediaProgress(libraryItem.id, ep.id)
|
||||
return !userProgress || !userProgress.isFinished
|
||||
}).map(_ep => {
|
||||
const ep = _ep.toJSONExpanded()
|
||||
ep.podcast = libraryItem.media.toJSONMinified()
|
||||
ep.libraryItemId = libraryItem.id
|
||||
ep.libraryId = libraryItem.libraryId
|
||||
return ep
|
||||
})
|
||||
allUnfinishedEpisodes.push(...unfinishedEpisodes)
|
||||
}
|
||||
|
||||
payload.total = allUnfinishedEpisodes.length
|
||||
|
||||
allUnfinishedEpisodes = sort(allUnfinishedEpisodes).desc(ep => ep.publishedAt)
|
||||
|
||||
if (payload.limit) {
|
||||
var startIndex = payload.page * payload.limit
|
||||
allUnfinishedEpisodes = allUnfinishedEpisodes.slice(startIndex, startIndex + payload.limit)
|
||||
}
|
||||
payload.episodes = allUnfinishedEpisodes
|
||||
const offset = payload.page * payload.limit
|
||||
payload.episodes = await libraryItemsPodcastFilters.getRecentEpisodes(req.user, req.library, payload.limit, offset)
|
||||
res.json(payload)
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ class Podcast extends Model {
|
||||
|
||||
static getOldPodcast(libraryItemExpanded) {
|
||||
const podcastExpanded = libraryItemExpanded.media
|
||||
const podcastEpisodes = podcastExpanded.podcastEpisodes?.map(ep => ep.getOldPodcastEpisode(libraryItemExpanded.id)).sort((a, b) => a.index - b.index)
|
||||
const podcastEpisodes = podcastExpanded.podcastEpisodes?.map(ep => ep.getOldPodcastEpisode(libraryItemExpanded.id).toJSON()).sort((a, b) => a.index - b.index)
|
||||
return {
|
||||
id: podcastExpanded.id,
|
||||
libraryItemId: libraryItemExpanded.id,
|
||||
|
@ -1,4 +1,5 @@
|
||||
const { DataTypes, Model } = require('sequelize')
|
||||
const oldPodcastEpisode = require('../objects/entities/PodcastEpisode')
|
||||
|
||||
class PodcastEpisode extends Model {
|
||||
constructor(values, options) {
|
||||
@ -44,6 +45,10 @@ class PodcastEpisode extends Model {
|
||||
this.updatedAt
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} libraryItemId
|
||||
* @returns {oldPodcastEpisode}
|
||||
*/
|
||||
getOldPodcastEpisode(libraryItemId = null) {
|
||||
let enclosure = null
|
||||
if (this.enclosureURL) {
|
||||
@ -53,7 +58,7 @@ class PodcastEpisode extends Model {
|
||||
length: this.enclosureSize !== null ? String(this.enclosureSize) : null
|
||||
}
|
||||
}
|
||||
return {
|
||||
return new oldPodcastEpisode({
|
||||
libraryItemId: libraryItemId || null,
|
||||
podcastId: this.podcastId,
|
||||
id: this.id,
|
||||
@ -72,7 +77,7 @@ class PodcastEpisode extends Model {
|
||||
publishedAt: this.publishedAt?.valueOf() || null,
|
||||
addedAt: this.createdAt.valueOf(),
|
||||
updatedAt: this.updatedAt.valueOf()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static createFromOld(oldEpisode) {
|
||||
|
@ -94,7 +94,7 @@ class ApiRouter {
|
||||
this.router.delete('/libraries/:id/narrators/:narratorId', LibraryController.middlewareNew.bind(this), LibraryController.removeNarrator.bind(this))
|
||||
this.router.get('/libraries/:id/matchall', LibraryController.middlewareNew.bind(this), LibraryController.matchAll.bind(this))
|
||||
this.router.post('/libraries/:id/scan', LibraryController.middlewareNew.bind(this), LibraryController.scan.bind(this))
|
||||
this.router.get('/libraries/:id/recent-episodes', LibraryController.middleware.bind(this), LibraryController.getRecentEpisodes.bind(this))
|
||||
this.router.get('/libraries/:id/recent-episodes', LibraryController.middlewareNew.bind(this), LibraryController.getRecentEpisodes.bind(this))
|
||||
this.router.get('/libraries/:id/opml', LibraryController.middleware.bind(this), LibraryController.getOPMLFile.bind(this))
|
||||
this.router.post('/libraries/order', LibraryController.reorder.bind(this))
|
||||
|
||||
|
@ -283,7 +283,7 @@ module.exports = {
|
||||
const podcast = ep.podcast.toJSON()
|
||||
delete podcast.libraryItem
|
||||
libraryItem.media = podcast
|
||||
libraryItem.recentEpisode = ep.getOldPodcastEpisode(libraryItem.id)
|
||||
libraryItem.recentEpisode = ep.getOldPodcastEpisode(libraryItem.id).toJSON()
|
||||
return libraryItem
|
||||
})
|
||||
|
||||
@ -396,5 +396,64 @@ module.exports = {
|
||||
podcast: itemMatches,
|
||||
tags: tagMatches
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Most recent podcast episodes not finished
|
||||
* @param {import('../../objects/user/User')} oldUser
|
||||
* @param {import('../../objects/Library')} oldLibrary
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @returns {Promise<object[]>}
|
||||
*/
|
||||
async getRecentEpisodes(oldUser, oldLibrary, limit, offset) {
|
||||
const userPermissionPodcastWhere = this.getUserPermissionPodcastWhereQuery(oldUser)
|
||||
|
||||
const episodes = await Database.podcastEpisodeModel.findAll({
|
||||
where: {
|
||||
'$mediaProgresses.isFinished$': {
|
||||
[Sequelize.Op.or]: [null, false]
|
||||
}
|
||||
},
|
||||
replacements: userPermissionPodcastWhere.replacements,
|
||||
include: [
|
||||
{
|
||||
model: Database.podcastModel,
|
||||
where: userPermissionPodcastWhere.podcastWhere,
|
||||
required: true,
|
||||
include: {
|
||||
model: Database.libraryItemModel,
|
||||
where: {
|
||||
libraryId: oldLibrary.id
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
model: Database.mediaProgressModel,
|
||||
where: {
|
||||
userId: oldUser.id
|
||||
},
|
||||
required: false
|
||||
}
|
||||
],
|
||||
order: [
|
||||
['publishedAt', 'DESC']
|
||||
],
|
||||
subQuery: false,
|
||||
limit,
|
||||
offset
|
||||
})
|
||||
|
||||
const episodeResults = episodes.map((ep) => {
|
||||
const libraryItem = ep.podcast.libraryItem
|
||||
libraryItem.media = ep.podcast
|
||||
const oldPodcast = Database.podcastModel.getOldPodcast(libraryItem)
|
||||
const oldPodcastEpisode = ep.getOldPodcastEpisode(libraryItem.id).toJSONExpanded()
|
||||
oldPodcastEpisode.podcast = oldPodcast
|
||||
oldPodcastEpisode.libraryId = libraryItem.libraryId
|
||||
return oldPodcastEpisode
|
||||
})
|
||||
|
||||
return episodeResults
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user