mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +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