From 6056c14926787c94c6a633b99b084e9cfbdf52ec Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 12 Aug 2023 17:29:08 -0500 Subject: [PATCH] Update podcast controller to load library items from db --- server/controllers/LibraryItemController.js | 41 ++++++++++---------- server/controllers/PlaylistController.js | 2 +- server/controllers/PodcastController.js | 41 +++++++++++++------- server/models/Collection.js | 42 --------------------- server/models/LibraryItem.js | 7 ++-- server/models/Playlist.js | 42 +++++++++++++++++++++ 6 files changed, 95 insertions(+), 80 deletions(-) diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js index 9c0be842..2aa361f1 100644 --- a/server/controllers/LibraryItemController.js +++ b/server/controllers/LibraryItemController.js @@ -309,18 +309,22 @@ class LibraryItemController { const hardDelete = req.query.hard == 1 // Delete files from filesystem const { libraryItemIds } = req.body - if (!libraryItemIds || !libraryItemIds.length) { - return res.sendStatus(500) + if (!libraryItemIds?.length) { + return res.status(400).send('Invalid request body') } - const itemsToDelete = Database.libraryItems.filter(li => libraryItemIds.includes(li.id)) + const itemsToDelete = await Database.models.libraryItem.getAllOldLibraryItems({ + id: libraryItemIds + }) + if (!itemsToDelete.length) { return res.sendStatus(404) } - for (let i = 0; i < itemsToDelete.length; i++) { - const libraryItemPath = itemsToDelete[i].path - Logger.info(`[LibraryItemController] Deleting Library Item "${itemsToDelete[i].media.metadata.title}"`) - await this.handleDeleteLibraryItem(itemsToDelete[i]) + + for (const libraryItem of itemsToDelete) { + const libraryItemPath = libraryItem.path + Logger.info(`[LibraryItemController] Deleting Library Item "${libraryItem.media.metadata.title}"`) + await this.handleDeleteLibraryItem(libraryItem) if (hardDelete) { Logger.info(`[LibraryItemController] Deleting library item from file system at "${libraryItemPath}"`) await fs.remove(libraryItemPath).catch((error) => { @@ -333,22 +337,21 @@ class LibraryItemController { // POST: api/items/batch/update async batchUpdate(req, res) { - var updatePayloads = req.body - if (!updatePayloads || !updatePayloads.length) { + const updatePayloads = req.body + if (!updatePayloads?.length) { return res.sendStatus(500) } - var itemsUpdated = 0 + let itemsUpdated = 0 - for (let i = 0; i < updatePayloads.length; i++) { - var mediaPayload = updatePayloads[i].mediaPayload - var libraryItem = Database.libraryItems.find(_li => _li.id === updatePayloads[i].id) + for (const updatePayload of updatePayloads) { + const mediaPayload = updatePayload.mediaPayload + const libraryItem = await Database.models.libraryItem.getOldById(updatePayload.id) if (!libraryItem) return null await this.createAuthorsAndSeriesForItemUpdate(mediaPayload, libraryItem.libraryId) - var hasUpdates = libraryItem.media.update(mediaPayload) - if (hasUpdates) { + if (libraryItem.media.update(mediaPayload)) { Logger.debug(`[LibraryItemController] Updated library item media ${libraryItem.media.metadata.title}`) await Database.updateLibraryItem(libraryItem) SocketAuthority.emitter('item_updated', libraryItem.toJSONExpanded()) @@ -368,13 +371,11 @@ class LibraryItemController { if (!libraryItemIds.length) { return res.status(403).send('Invalid payload') } - const libraryItems = [] - libraryItemIds.forEach((lid) => { - const li = Database.libraryItems.find(_li => _li.id === lid) - if (li) libraryItems.push(li.toJSONExpanded()) + const libraryItems = await Database.models.libraryItem.getAllOldLibraryItems({ + id: libraryItemIds }) res.json({ - libraryItems + libraryItems: libraryItems.map(li => li.toJSONExpanded()) }) } diff --git a/server/controllers/PlaylistController.js b/server/controllers/PlaylistController.js index a7c8a9c3..2bef354c 100644 --- a/server/controllers/PlaylistController.js +++ b/server/controllers/PlaylistController.js @@ -133,7 +133,7 @@ class PlaylistController { const itemsToAdd = req.body.items let hasUpdated = false - let order = playlist.items.length + let order = playlist.items.length + 1 const playlistMediaItems = [] for (const item of itemsToAdd) { if (!item.libraryItemId) { diff --git a/server/controllers/PodcastController.js b/server/controllers/PodcastController.js index a7d8f3ce..76781516 100644 --- a/server/controllers/PodcastController.js +++ b/server/controllers/PodcastController.js @@ -34,9 +34,13 @@ class PodcastController { const podcastPath = filePathToPOSIX(payload.path) // Check if a library item with this podcast folder exists already - const existingLibraryItem = Database.libraryItems.find(li => li.path === podcastPath && li.libraryId === library.id) + const existingLibraryItem = (await Database.models.libraryItem.count({ + where: { + path: podcastPath + } + })) > 0 if (existingLibraryItem) { - Logger.error(`[PodcastController] Podcast already exists with name "${existingLibraryItem.media.metadata.title}" at path "${podcastPath}"`) + Logger.error(`[PodcastController] Podcast already exists at path "${podcastPath}"`) return res.status(400).send('Podcast already exists') } @@ -268,18 +272,27 @@ class PodcastController { } // Update/remove playlists that had this podcast episode - const playlistsWithEpisode = await Database.models.playlist.getPlaylistsForMediaItemIds([episodeId]) - for (const playlist of playlistsWithEpisode) { - playlist.removeItem(libraryItem.id, episodeId) + const playlistMediaItems = await Database.models.playlistMediaItem.findAll({ + where: { + mediaItemId: episodeId + }, + include: { + model: Database.models.playlist, + include: Database.models.playlistMediaItem + } + }) + for (const pmi of playlistMediaItems) { + const numItems = pmi.playlist.playlistMediaItems.length - 1 - // If playlist is now empty then remove it - if (!playlist.items.length) { + if (!numItems) { Logger.info(`[PodcastController] Playlist "${playlist.name}" has no more items - removing it`) - await Database.removePlaylist(playlist.id) - SocketAuthority.clientEmitter(playlist.userId, 'playlist_removed', playlist.toJSONExpanded(Database.libraryItems)) + const jsonExpanded = await pmi.playlist.getOldJsonExpanded() + SocketAuthority.clientEmitter(pmi.playlist.userId, 'playlist_removed', jsonExpanded) + await pmi.playlist.destroy() } else { - await Database.updatePlaylist(playlist) - SocketAuthority.clientEmitter(playlist.userId, 'playlist_updated', playlist.toJSONExpanded(Database.libraryItems)) + await pmi.destroy() + const jsonExpanded = await pmi.playlist.getOldJsonExpanded() + SocketAuthority.clientEmitter(pmi.playlist.userId, 'playlist_updated', jsonExpanded) } } @@ -298,9 +311,9 @@ class PodcastController { res.json(libraryItem.toJSON()) } - middleware(req, res, next) { - const item = Database.libraryItems.find(li => li.id === req.params.id) - if (!item || !item.media) return res.sendStatus(404) + async middleware(req, res, next) { + const item = await Database.models.libraryItem.getOldById(req.params.id) + if (!item?.media) return res.sendStatus(404) if (!item.isPodcast) { return res.sendStatus(500) diff --git a/server/models/Collection.js b/server/models/Collection.js index 78b7c7c6..f4aa9b46 100644 --- a/server/models/Collection.js +++ b/server/models/Collection.js @@ -205,48 +205,6 @@ module.exports = (sequelize) => { return this.create(collection) } - static async fullUpdateFromOld(oldCollection, collectionBooks) { - const existingCollection = await this.findByPk(oldCollection.id, { - include: sequelize.models.collectionBook - }) - if (!existingCollection) return false - - let hasUpdates = false - const collection = this.getFromOld(oldCollection) - - for (const cb of collectionBooks) { - const existingCb = existingCollection.collectionBooks.find(i => i.bookId === cb.bookId) - if (!existingCb) { - await sequelize.models.collectionBook.create(cb) - hasUpdates = true - } else if (existingCb.order != cb.order) { - await existingCb.update({ order: cb.order }) - hasUpdates = true - } - } - for (const cb of existingCollection.collectionBooks) { - // collectionBook was removed - if (!collectionBooks.some(i => i.bookId === cb.bookId)) { - await cb.destroy() - hasUpdates = true - } - } - - let hasCollectionUpdates = false - for (const key in collection) { - let existingValue = existingCollection[key] - if (existingValue instanceof Date) existingValue = existingValue.valueOf() - if (!areEquivalent(collection[key], existingValue)) { - hasCollectionUpdates = true - } - } - if (hasCollectionUpdates) { - existingCollection.update(collection) - hasUpdates = true - } - return hasUpdates - } - static getFromOld(oldCollection) { return { id: oldCollection.id, diff --git a/server/models/LibraryItem.js b/server/models/LibraryItem.js index f96d38cb..ce56590b 100644 --- a/server/models/LibraryItem.js +++ b/server/models/LibraryItem.js @@ -1,4 +1,4 @@ -const { DataTypes, Model } = require('sequelize') +const { DataTypes, Model, WhereOptions } = require('sequelize') const Logger = require('../Logger') const oldLibraryItem = require('../objects/LibraryItem') const libraryFilters = require('../utils/queries/libraryFilters') @@ -102,11 +102,12 @@ module.exports = (sequelize) => { /** * Currently unused because this is too slow and uses too much mem - * + * @param {[WhereOptions]} where * @returns {Array} old library items */ - static async getAllOldLibraryItems() { + static async getAllOldLibraryItems(where = null) { let libraryItems = await this.findAll({ + where, include: [ { model: sequelize.models.book, diff --git a/server/models/Playlist.js b/server/models/Playlist.js index bb471ba2..7531f758 100644 --- a/server/models/Playlist.js +++ b/server/models/Playlist.js @@ -54,6 +54,48 @@ module.exports = (sequelize) => { }) } + /** + * Get old playlist toJSONExpanded + * @param {[string[]]} include + * @returns {Promise} oldPlaylist.toJSONExpanded + */ + async getOldJsonExpanded(include) { + this.playlistMediaItems = await this.getPlaylistMediaItems({ + include: [ + { + model: sequelize.models.book, + include: sequelize.models.libraryItem + }, + { + model: sequelize.models.podcastEpisode, + include: { + model: sequelize.models.podcast, + include: sequelize.models.libraryItem + } + } + ], + order: [['order', 'ASC']] + }) || [] + + const oldPlaylist = sequelize.models.playlist.getOldPlaylist(this) + const libraryItemIds = oldPlaylist.items.map(i => i.libraryItemId) + + let libraryItems = await sequelize.models.libraryItem.getAllOldLibraryItems({ + id: libraryItemIds + }) + + const playlistExpanded = oldCollection.toJSONExpanded(libraryItems) + + if (include?.includes('rssfeed')) { + const feeds = await this.getFeeds() + if (feeds?.length) { + playlistExpanded.rssFeed = sequelize.models.feed.getOldFeed(feeds[0]) + } + } + + return playlistExpanded + } + static createFromOld(oldPlaylist) { const playlist = this.getFromOld(oldPlaylist) return this.create(playlist)