mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Update controllers to use toOldJSON functions
This commit is contained in:
		
							parent
							
								
									7fae25a726
								
							
						
					
					
						commit
						6d52f88a96
					
				| @ -665,7 +665,7 @@ class Database { | ||||
|   /** | ||||
|    * Clean invalid records in database | ||||
|    * Series should have atleast one Book | ||||
|    * Book and Podcast must have an associated LibraryItem | ||||
|    * Book and Podcast must have an associated LibraryItem (and vice versa) | ||||
|    * Remove playback sessions that are 3 seconds or less | ||||
|    */ | ||||
|   async cleanDatabase() { | ||||
| @ -695,6 +695,28 @@ class Database { | ||||
|       await book.destroy() | ||||
|     } | ||||
| 
 | ||||
|     // Remove invalid LibraryItem records
 | ||||
|     const libraryItemsWithNoMedia = await this.libraryItemModel.findAll({ | ||||
|       include: [ | ||||
|         { | ||||
|           model: this.bookModel, | ||||
|           attributes: ['id'] | ||||
|         }, | ||||
|         { | ||||
|           model: this.podcastModel, | ||||
|           attributes: ['id'] | ||||
|         } | ||||
|       ], | ||||
|       where: { | ||||
|         '$book.id$': null, | ||||
|         '$podcast.id$': null | ||||
|       } | ||||
|     }) | ||||
|     for (const libraryItem of libraryItemsWithNoMedia) { | ||||
|       Logger.warn(`Found libraryItem "${libraryItem.id}" with no media - removing it`) | ||||
|       await libraryItem.destroy() | ||||
|     } | ||||
| 
 | ||||
|     const playlistMediaItemsWithNoMediaItem = await this.playlistMediaItemModel.findAll({ | ||||
|       include: [ | ||||
|         { | ||||
|  | ||||
| @ -125,7 +125,7 @@ class AuthorController { | ||||
|       const bookAuthorsToCreate = [] | ||||
|       const allItemsWithAuthor = await Database.authorModel.getAllLibraryItemsForAuthor(req.author.id) | ||||
| 
 | ||||
|       const oldLibraryItems = [] | ||||
|       const libraryItems = [] | ||||
|       allItemsWithAuthor.forEach((libraryItem) => { | ||||
|         // Replace old author with merging author for each book
 | ||||
|         libraryItem.media.authors = libraryItem.media.authors.filter((au) => au.id !== req.author.id) | ||||
| @ -134,23 +134,22 @@ class AuthorController { | ||||
|           name: existingAuthor.name | ||||
|         }) | ||||
| 
 | ||||
|         const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|         oldLibraryItems.push(oldLibraryItem) | ||||
|         libraryItems.push(libraryItem) | ||||
| 
 | ||||
|         bookAuthorsToCreate.push({ | ||||
|           bookId: libraryItem.media.id, | ||||
|           authorId: existingAuthor.id | ||||
|         }) | ||||
|       }) | ||||
|       if (oldLibraryItems.length) { | ||||
|       if (libraryItems.length) { | ||||
|         await Database.removeBulkBookAuthors(req.author.id) // Remove all old BookAuthor
 | ||||
|         await Database.createBulkBookAuthors(bookAuthorsToCreate) // Create all new BookAuthor
 | ||||
|         for (const libraryItem of allItemsWithAuthor) { | ||||
|         for (const libraryItem of libraryItems) { | ||||
|           await libraryItem.saveMetadataFile() | ||||
|         } | ||||
|         SocketAuthority.emitter( | ||||
|           'items_updated', | ||||
|           oldLibraryItems.map((li) => li.toJSONExpanded()) | ||||
|           libraryItems.map((li) => li.toOldJSONExpanded()) | ||||
|         ) | ||||
|       } | ||||
| 
 | ||||
| @ -190,7 +189,7 @@ class AuthorController { | ||||
|         const allItemsWithAuthor = await Database.authorModel.getAllLibraryItemsForAuthor(req.author.id) | ||||
| 
 | ||||
|         numBooksForAuthor = allItemsWithAuthor.length | ||||
|         const oldLibraryItems = [] | ||||
|         const libraryItems = [] | ||||
|         // Update author name on all books
 | ||||
|         for (const libraryItem of allItemsWithAuthor) { | ||||
|           libraryItem.media.authors = libraryItem.media.authors.map((au) => { | ||||
| @ -199,16 +198,16 @@ class AuthorController { | ||||
|             } | ||||
|             return au | ||||
|           }) | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|           oldLibraryItems.push(oldLibraryItem) | ||||
| 
 | ||||
|           libraryItems.push(libraryItem) | ||||
| 
 | ||||
|           await libraryItem.saveMetadataFile() | ||||
|         } | ||||
| 
 | ||||
|         if (oldLibraryItems.length) { | ||||
|         if (libraryItems.length) { | ||||
|           SocketAuthority.emitter( | ||||
|             'items_updated', | ||||
|             oldLibraryItems.map((li) => li.toJSONExpanded()) | ||||
|             libraryItems.map((li) => li.toOldJSONExpanded()) | ||||
|           ) | ||||
|         } | ||||
|       } else { | ||||
|  | ||||
| @ -221,7 +221,9 @@ class CollectionController { | ||||
|    * @param {Response} res | ||||
|    */ | ||||
|   async addBook(req, res) { | ||||
|     const libraryItem = await Database.libraryItemModel.getOldById(req.body.id) | ||||
|     const libraryItem = await Database.libraryItemModel.findByPk(req.body.id, { | ||||
|       attributes: ['libraryId', 'mediaId'] | ||||
|     }) | ||||
|     if (!libraryItem) { | ||||
|       return res.status(404).send('Book not found') | ||||
|     } | ||||
| @ -231,14 +233,14 @@ class CollectionController { | ||||
| 
 | ||||
|     // Check if book is already in collection
 | ||||
|     const collectionBooks = await req.collection.getCollectionBooks() | ||||
|     if (collectionBooks.some((cb) => cb.bookId === libraryItem.media.id)) { | ||||
|     if (collectionBooks.some((cb) => cb.bookId === libraryItem.mediaId)) { | ||||
|       return res.status(400).send('Book already in collection') | ||||
|     } | ||||
| 
 | ||||
|     // Create collectionBook record
 | ||||
|     await Database.collectionBookModel.create({ | ||||
|       collectionId: req.collection.id, | ||||
|       bookId: libraryItem.media.id, | ||||
|       bookId: libraryItem.mediaId, | ||||
|       order: collectionBooks.length + 1 | ||||
|     }) | ||||
|     const jsonExpanded = await req.collection.getOldJsonExpanded() | ||||
| @ -255,7 +257,9 @@ class CollectionController { | ||||
|    * @param {Response} res | ||||
|    */ | ||||
|   async removeBook(req, res) { | ||||
|     const libraryItem = await Database.libraryItemModel.getOldById(req.params.bookId) | ||||
|     const libraryItem = await Database.libraryItemModel.findByPk(req.params.bookId, { | ||||
|       attributes: ['mediaId'] | ||||
|     }) | ||||
|     if (!libraryItem) { | ||||
|       return res.sendStatus(404) | ||||
|     } | ||||
| @ -266,7 +270,7 @@ class CollectionController { | ||||
|     }) | ||||
| 
 | ||||
|     let jsonExpanded = null | ||||
|     const collectionBookToRemove = collectionBooks.find((cb) => cb.bookId === libraryItem.media.id) | ||||
|     const collectionBookToRemove = collectionBooks.find((cb) => cb.bookId === libraryItem.mediaId) | ||||
|     if (collectionBookToRemove) { | ||||
|       // Remove collection book record
 | ||||
|       await collectionBookToRemove.destroy() | ||||
| @ -274,7 +278,7 @@ class CollectionController { | ||||
|       // Update order on collection books
 | ||||
|       let order = 1 | ||||
|       for (const collectionBook of collectionBooks) { | ||||
|         if (collectionBook.bookId === libraryItem.media.id) continue | ||||
|         if (collectionBook.bookId === libraryItem.mediaId) continue | ||||
|         if (collectionBook.order !== order) { | ||||
|           await collectionBook.update({ | ||||
|             order | ||||
|  | ||||
| @ -1145,14 +1145,14 @@ class LibraryController { | ||||
|       await libraryItem.media.update({ | ||||
|         narrators: libraryItem.media.narrators | ||||
|       }) | ||||
|       const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|       itemsUpdated.push(oldLibraryItem) | ||||
| 
 | ||||
|       itemsUpdated.push(libraryItem) | ||||
|     } | ||||
| 
 | ||||
|     if (itemsUpdated.length) { | ||||
|       SocketAuthority.emitter( | ||||
|         'items_updated', | ||||
|         itemsUpdated.map((li) => li.toJSONExpanded()) | ||||
|         itemsUpdated.map((li) => li.toOldJSONExpanded()) | ||||
|       ) | ||||
|     } | ||||
| 
 | ||||
| @ -1189,14 +1189,14 @@ class LibraryController { | ||||
|       await libraryItem.media.update({ | ||||
|         narrators: libraryItem.media.narrators | ||||
|       }) | ||||
|       const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|       itemsUpdated.push(oldLibraryItem) | ||||
| 
 | ||||
|       itemsUpdated.push(libraryItem) | ||||
|     } | ||||
| 
 | ||||
|     if (itemsUpdated.length) { | ||||
|       SocketAuthority.emitter( | ||||
|         'items_updated', | ||||
|         itemsUpdated.map((li) => li.toJSONExpanded()) | ||||
|         itemsUpdated.map((li) => li.toOldJSONExpanded()) | ||||
|       ) | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -551,11 +551,11 @@ class LibraryItemController { | ||||
|     const hardDelete = req.query.hard == 1 // Delete files from filesystem
 | ||||
| 
 | ||||
|     const { libraryItemIds } = req.body | ||||
|     if (!libraryItemIds?.length) { | ||||
|     if (!libraryItemIds?.length || !Array.isArray(libraryItemIds)) { | ||||
|       return res.status(400).send('Invalid request body') | ||||
|     } | ||||
| 
 | ||||
|     const itemsToDelete = await Database.libraryItemModel.getAllOldLibraryItems({ | ||||
|     const itemsToDelete = await Database.libraryItemModel.findAllExpandedWhere({ | ||||
|       id: libraryItemIds | ||||
|     }) | ||||
| 
 | ||||
| @ -566,19 +566,19 @@ class LibraryItemController { | ||||
|     const libraryId = itemsToDelete[0].libraryId | ||||
|     for (const libraryItem of itemsToDelete) { | ||||
|       const libraryItemPath = libraryItem.path | ||||
|       Logger.info(`[LibraryItemController] (${hardDelete ? 'Hard' : 'Soft'}) deleting Library Item "${libraryItem.media.metadata.title}" with id "${libraryItem.id}"`) | ||||
|       Logger.info(`[LibraryItemController] (${hardDelete ? 'Hard' : 'Soft'}) deleting Library Item "${libraryItem.media.title}" with id "${libraryItem.id}"`) | ||||
|       const mediaItemIds = [] | ||||
|       const seriesIds = [] | ||||
|       const authorIds = [] | ||||
|       if (libraryItem.isPodcast) { | ||||
|         mediaItemIds.push(...libraryItem.media.episodes.map((ep) => ep.id)) | ||||
|         mediaItemIds.push(...libraryItem.media.podcastEpisodes.map((ep) => ep.id)) | ||||
|       } else { | ||||
|         mediaItemIds.push(libraryItem.media.id) | ||||
|         if (libraryItem.media.metadata.series?.length) { | ||||
|           seriesIds.push(...libraryItem.media.metadata.series.map((se) => se.id)) | ||||
|         if (libraryItem.media.series?.length) { | ||||
|           seriesIds.push(...libraryItem.media.series.map((se) => se.id)) | ||||
|         } | ||||
|         if (libraryItem.media.metadata.authors?.length) { | ||||
|           authorIds.push(...libraryItem.media.metadata.authors.map((au) => au.id)) | ||||
|         if (libraryItem.media.authors?.length) { | ||||
|           authorIds.push(...libraryItem.media.authors.map((au) => au.id)) | ||||
|         } | ||||
|       } | ||||
|       await this.handleDeleteLibraryItem(libraryItem.id, mediaItemIds) | ||||
| @ -623,7 +623,7 @@ class LibraryItemController { | ||||
|     } | ||||
| 
 | ||||
|     // Get all library items to update
 | ||||
|     const libraryItems = await Database.libraryItemModel.getAllOldLibraryItems({ | ||||
|     const libraryItems = await Database.libraryItemModel.findAllExpandedWhere({ | ||||
|       id: libraryItemIds | ||||
|     }) | ||||
|     if (updatePayloads.length !== libraryItems.length) { | ||||
| @ -645,21 +645,23 @@ class LibraryItemController { | ||||
|       if (libraryItem.isBook) { | ||||
|         if (Array.isArray(mediaPayload.metadata?.series)) { | ||||
|           const seriesIdsInUpdate = mediaPayload.metadata.series.map((se) => se.id) | ||||
|           const seriesRemoved = libraryItem.media.metadata.series.filter((se) => !seriesIdsInUpdate.includes(se.id)) | ||||
|           const seriesRemoved = libraryItem.media.series.filter((se) => !seriesIdsInUpdate.includes(se.id)) | ||||
|           seriesIdsRemoved.push(...seriesRemoved.map((se) => se.id)) | ||||
|         } | ||||
|         if (Array.isArray(mediaPayload.metadata?.authors)) { | ||||
|           const authorIdsInUpdate = mediaPayload.metadata.authors.map((au) => au.id) | ||||
|           const authorsRemoved = libraryItem.media.metadata.authors.filter((au) => !authorIdsInUpdate.includes(au.id)) | ||||
|           const authorsRemoved = libraryItem.media.authors.filter((au) => !authorIdsInUpdate.includes(au.id)) | ||||
|           authorIdsRemoved.push(...authorsRemoved.map((au) => au.id)) | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       if (libraryItem.media.update(mediaPayload)) { | ||||
|         Logger.debug(`[LibraryItemController] Updated library item media ${libraryItem.media.metadata.title}`) | ||||
|       const hasUpdates = await libraryItem.media.updateFromRequest(mediaPayload) | ||||
|       if (hasUpdates) { | ||||
|         libraryItem.changed('updatedAt', true) | ||||
|         await libraryItem.save() | ||||
| 
 | ||||
|         await Database.updateLibraryItem(libraryItem) | ||||
|         SocketAuthority.emitter('item_updated', libraryItem.toJSONExpanded()) | ||||
|         Logger.debug(`[LibraryItemController] Updated library item media "${libraryItem.media.title}"`) | ||||
|         SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) | ||||
|         itemsUpdated++ | ||||
|       } | ||||
|     } | ||||
| @ -688,11 +690,11 @@ class LibraryItemController { | ||||
|     if (!libraryItemIds.length) { | ||||
|       return res.status(403).send('Invalid payload') | ||||
|     } | ||||
|     const libraryItems = await Database.libraryItemModel.getAllOldLibraryItems({ | ||||
|     const libraryItems = await Database.libraryItemModel.findAllExpandedWhere({ | ||||
|       id: libraryItemIds | ||||
|     }) | ||||
|     res.json({ | ||||
|       libraryItems: libraryItems.map((li) => li.toJSONExpanded()) | ||||
|       libraryItems: libraryItems.map((li) => li.toOldJSONExpanded()) | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
| @ -715,7 +717,7 @@ class LibraryItemController { | ||||
|       return res.sendStatus(400) | ||||
|     } | ||||
| 
 | ||||
|     const libraryItems = await Database.libraryItemModel.getAllOldLibraryItems({ | ||||
|     const libraryItems = await Database.libraryItemModel.findAllExpandedWhere({ | ||||
|       id: req.body.libraryItemIds | ||||
|     }) | ||||
|     if (!libraryItems?.length) { | ||||
| @ -737,7 +739,8 @@ class LibraryItemController { | ||||
|     } | ||||
| 
 | ||||
|     for (const libraryItem of libraryItems) { | ||||
|       const matchResult = await Scanner.quickMatchLibraryItem(this, libraryItem, options) | ||||
|       const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|       const matchResult = await Scanner.quickMatchLibraryItem(this, oldLibraryItem, options) | ||||
|       if (matchResult.updated) { | ||||
|         itemsUpdated++ | ||||
|       } else if (matchResult.warning) { | ||||
|  | ||||
| @ -66,7 +66,7 @@ class MeController { | ||||
|     const libraryItem = await Database.libraryItemModel.findByPk(req.params.libraryItemId) | ||||
|     const episode = await Database.podcastEpisodeModel.findByPk(req.params.episodeId) | ||||
| 
 | ||||
|     if (!libraryItem || (libraryItem.mediaType === 'podcast' && !episode)) { | ||||
|     if (!libraryItem || (libraryItem.isPodcast && !episode)) { | ||||
|       Logger.error(`[MeController] Media item not found for library item id "${req.params.libraryItemId}"`) | ||||
|       return res.sendStatus(404) | ||||
|     } | ||||
| @ -296,7 +296,7 @@ class MeController { | ||||
|     const mediaProgressesInProgress = req.user.mediaProgresses.filter((mp) => !mp.isFinished && (mp.currentTime > 0 || mp.ebookProgress > 0)) | ||||
| 
 | ||||
|     const libraryItemsIds = [...new Set(mediaProgressesInProgress.map((mp) => mp.extraData?.libraryItemId).filter((id) => id))] | ||||
|     const libraryItems = await Database.libraryItemModel.getAllOldLibraryItems({ id: libraryItemsIds }) | ||||
|     const libraryItems = await Database.libraryItemModel.findAllExpandedWhere({ id: libraryItemsIds }) | ||||
| 
 | ||||
|     let itemsInProgress = [] | ||||
| 
 | ||||
| @ -304,19 +304,19 @@ class MeController { | ||||
|       const oldMediaProgress = mediaProgress.getOldMediaProgress() | ||||
|       const libraryItem = libraryItems.find((li) => li.id === oldMediaProgress.libraryItemId) | ||||
|       if (libraryItem) { | ||||
|         if (oldMediaProgress.episodeId && libraryItem.mediaType === 'podcast') { | ||||
|           const episode = libraryItem.media.episodes.find((ep) => ep.id === oldMediaProgress.episodeId) | ||||
|         if (oldMediaProgress.episodeId && libraryItem.isPodcast) { | ||||
|           const episode = libraryItem.media.podcastEpisodes.find((ep) => ep.id === oldMediaProgress.episodeId) | ||||
|           if (episode) { | ||||
|             const libraryItemWithEpisode = { | ||||
|               ...libraryItem.toJSONMinified(), | ||||
|               recentEpisode: episode.toJSON(), | ||||
|               ...libraryItem.toOldJSONMinified(), | ||||
|               recentEpisode: episode.toOldJSON(libraryItem.id), | ||||
|               progressLastUpdate: oldMediaProgress.lastUpdate | ||||
|             } | ||||
|             itemsInProgress.push(libraryItemWithEpisode) | ||||
|           } | ||||
|         } else if (!oldMediaProgress.episodeId) { | ||||
|           itemsInProgress.push({ | ||||
|             ...libraryItem.toJSONMinified(), | ||||
|             ...libraryItem.toOldJSONMinified(), | ||||
|             progressLastUpdate: oldMediaProgress.lastUpdate | ||||
|           }) | ||||
|         } | ||||
|  | ||||
| @ -342,8 +342,8 @@ class MiscController { | ||||
|           tags: libraryItem.media.tags | ||||
|         }) | ||||
|         await libraryItem.saveMetadataFile() | ||||
|         const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|         SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded()) | ||||
| 
 | ||||
|         SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) | ||||
|         numItemsUpdated++ | ||||
|       } | ||||
|     } | ||||
| @ -385,8 +385,8 @@ class MiscController { | ||||
|         tags: libraryItem.media.tags | ||||
|       }) | ||||
|       await libraryItem.saveMetadataFile() | ||||
|       const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|       SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded()) | ||||
| 
 | ||||
|       SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) | ||||
|       numItemsUpdated++ | ||||
|     } | ||||
| 
 | ||||
| @ -480,8 +480,8 @@ class MiscController { | ||||
|           genres: libraryItem.media.genres | ||||
|         }) | ||||
|         await libraryItem.saveMetadataFile() | ||||
|         const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|         SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded()) | ||||
| 
 | ||||
|         SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) | ||||
|         numItemsUpdated++ | ||||
|       } | ||||
|     } | ||||
| @ -523,8 +523,8 @@ class MiscController { | ||||
|         genres: libraryItem.media.genres | ||||
|       }) | ||||
|       await libraryItem.saveMetadataFile() | ||||
|       const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|       SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded()) | ||||
| 
 | ||||
|       SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) | ||||
|       numItemsUpdated++ | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -276,7 +276,7 @@ class PlaylistController { | ||||
|       return res.status(400).send('Request body has no libraryItemId') | ||||
|     } | ||||
| 
 | ||||
|     const libraryItem = await Database.libraryItemModel.getOldById(itemToAdd.libraryItemId) | ||||
|     const libraryItem = await Database.libraryItemModel.getExpandedById(itemToAdd.libraryItemId) | ||||
|     if (!libraryItem) { | ||||
|       return res.status(400).send('Library item not found') | ||||
|     } | ||||
| @ -286,7 +286,7 @@ class PlaylistController { | ||||
|     if ((itemToAdd.episodeId && !libraryItem.isPodcast) || (libraryItem.isPodcast && !itemToAdd.episodeId)) { | ||||
|       return res.status(400).send('Invalid item to add for this library type') | ||||
|     } | ||||
|     if (itemToAdd.episodeId && !libraryItem.media.checkHasEpisode(itemToAdd.episodeId)) { | ||||
|     if (itemToAdd.episodeId && !libraryItem.media.podcastEpisodes.some((pe) => pe.id === itemToAdd.episodeId)) { | ||||
|       return res.status(400).send('Episode not found in library item') | ||||
|     } | ||||
| 
 | ||||
| @ -308,17 +308,17 @@ class PlaylistController { | ||||
| 
 | ||||
|     // Add the new item to to the old json expanded to prevent having to fully reload the playlist media items
 | ||||
|     if (itemToAdd.episodeId) { | ||||
|       const episode = libraryItem.media.episodes.find((ep) => ep.id === itemToAdd.episodeId) | ||||
|       const episode = libraryItem.media.podcastEpisodes.find((ep) => ep.id === itemToAdd.episodeId) | ||||
|       jsonExpanded.items.push({ | ||||
|         episodeId: itemToAdd.episodeId, | ||||
|         episode: episode.toJSONExpanded(), | ||||
|         episode: episode.toOldJSONExpanded(libraryItem.id), | ||||
|         libraryItemId: libraryItem.id, | ||||
|         libraryItem: libraryItem.toJSONMinified() | ||||
|         libraryItem: libraryItem.toOldJSONMinified() | ||||
|       }) | ||||
|     } else { | ||||
|       jsonExpanded.items.push({ | ||||
|         libraryItemId: libraryItem.id, | ||||
|         libraryItem: libraryItem.toJSONExpanded() | ||||
|         libraryItem: libraryItem.toOldJSONExpanded() | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
| @ -388,8 +388,8 @@ class PlaylistController { | ||||
|     // Find all library items
 | ||||
|     const libraryItemIds = new Set(req.body.items.map((i) => i.libraryItemId).filter((i) => i)) | ||||
| 
 | ||||
|     const oldLibraryItems = await Database.libraryItemModel.getAllOldLibraryItems({ id: Array.from(libraryItemIds) }) | ||||
|     if (oldLibraryItems.length !== libraryItemIds.size) { | ||||
|     const libraryItems = await Database.libraryItemModel.findAllExpandedWhere({ id: Array.from(libraryItemIds) }) | ||||
|     if (libraryItems.length !== libraryItemIds.size) { | ||||
|       return res.status(400).send('Invalid request body items') | ||||
|     } | ||||
| 
 | ||||
| @ -401,7 +401,7 @@ class PlaylistController { | ||||
|     // Setup array of playlistMediaItem records to add
 | ||||
|     let order = req.playlist.playlistMediaItems.length + 1 | ||||
|     for (const item of req.body.items) { | ||||
|       const libraryItem = oldLibraryItems.find((li) => li.id === item.libraryItemId) | ||||
|       const libraryItem = libraryItems.find((li) => li.id === item.libraryItemId) | ||||
| 
 | ||||
|       const mediaItemId = item.episodeId || libraryItem.media.id | ||||
|       if (req.playlist.playlistMediaItems.some((pmi) => pmi.mediaItemId === mediaItemId)) { | ||||
| @ -417,17 +417,17 @@ class PlaylistController { | ||||
| 
 | ||||
|         // Add the new item to to the old json expanded to prevent having to fully reload the playlist media items
 | ||||
|         if (item.episodeId) { | ||||
|           const episode = libraryItem.media.episodes.find((ep) => ep.id === item.episodeId) | ||||
|           const episode = libraryItem.media.podcastEpisodes.find((ep) => ep.id === item.episodeId) | ||||
|           jsonExpanded.items.push({ | ||||
|             episodeId: item.episodeId, | ||||
|             episode: episode.toJSONExpanded(), | ||||
|             episode: episode.toOldJSONExpanded(libraryItem.id), | ||||
|             libraryItemId: libraryItem.id, | ||||
|             libraryItem: libraryItem.toJSONMinified() | ||||
|             libraryItem: libraryItem.toOldJSONMinified() | ||||
|           }) | ||||
|         } else { | ||||
|           jsonExpanded.items.push({ | ||||
|             libraryItemId: libraryItem.id, | ||||
|             libraryItem: libraryItem.toJSONExpanded() | ||||
|             libraryItem: libraryItem.toOldJSONExpanded() | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|  | ||||
| @ -296,9 +296,9 @@ class PodcastManager { | ||||
| 
 | ||||
|     Logger.info(`[PodcastManager] runEpisodeCheck: "${libraryItem.media.title}" | Last check: ${new Date(lastEpisodeCheck)} | ${latestEpisodePublishedAt ? `Latest episode pubDate: ${new Date(latestEpisodePublishedAt)}` : 'No latest episode'}`) | ||||
| 
 | ||||
|     // Use latest episode pubDate if exists OR fallback to using lastEpisodeCheckDate
 | ||||
|     //    lastEpisodeCheckDate will be the current time when adding a new podcast
 | ||||
|     const dateToCheckForEpisodesAfter = latestEpisodePublishedAt || lastEpisodeCheckDate | ||||
|     // Use latest episode pubDate if exists OR fallback to using lastEpisodeCheck
 | ||||
|     //    lastEpisodeCheck will be the current time when adding a new podcast
 | ||||
|     const dateToCheckForEpisodesAfter = latestEpisodePublishedAt || lastEpisodeCheck | ||||
|     Logger.debug(`[PodcastManager] runEpisodeCheck: "${libraryItem.media.title}" checking for episodes after ${new Date(dateToCheckForEpisodesAfter)}`) | ||||
| 
 | ||||
|     const newEpisodes = await this.checkPodcastForNewEpisodes(libraryItem, dateToCheckForEpisodesAfter, libraryItem.media.maxNewEpisodesToDownload) | ||||
|  | ||||
| @ -282,7 +282,7 @@ class Collection extends Model { | ||||
|       const libraryItem = book.libraryItem | ||||
|       delete book.libraryItem | ||||
|       libraryItem.media = book | ||||
|       return this.sequelize.models.libraryItem.getOldLibraryItem(libraryItem).toJSONExpanded() | ||||
|       return libraryItem.toOldJSONExpanded() | ||||
|     }) | ||||
| 
 | ||||
|     return json | ||||
|  | ||||
| @ -122,45 +122,6 @@ class LibraryItem extends Model { | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * | ||||
|    * @param {import('sequelize').WhereOptions} [where] | ||||
|    * @returns {Array<objects.LibraryItem>} old library items | ||||
|    */ | ||||
|   static async getAllOldLibraryItems(where = null) { | ||||
|     let libraryItems = await this.findAll({ | ||||
|       where, | ||||
|       include: [ | ||||
|         { | ||||
|           model: this.sequelize.models.book, | ||||
|           include: [ | ||||
|             { | ||||
|               model: this.sequelize.models.author, | ||||
|               through: { | ||||
|                 attributes: [] | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               model: this.sequelize.models.series, | ||||
|               through: { | ||||
|                 attributes: ['sequence'] | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         { | ||||
|           model: this.sequelize.models.podcast, | ||||
|           include: [ | ||||
|             { | ||||
|               model: this.sequelize.models.podcastEpisode | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|       ] | ||||
|     }) | ||||
|     return libraryItems.map((ti) => this.getOldLibraryItem(ti)) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Convert an expanded LibraryItem into an old library item | ||||
|    * | ||||
| @ -448,6 +409,47 @@ class LibraryItem extends Model { | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * | ||||
|    * @param {import('sequelize').WhereOptions} where | ||||
|    * @returns {Promise<LibraryItemExpanded[]>} | ||||
|    */ | ||||
|   static async findAllExpandedWhere(where = null) { | ||||
|     return this.findAll({ | ||||
|       where, | ||||
|       include: [ | ||||
|         { | ||||
|           model: this.sequelize.models.book, | ||||
|           include: [ | ||||
|             { | ||||
|               model: this.sequelize.models.author, | ||||
|               through: { | ||||
|                 attributes: [] | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               model: this.sequelize.models.series, | ||||
|               through: { | ||||
|                 attributes: ['sequence'] | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         { | ||||
|           model: this.sequelize.models.podcast, | ||||
|           include: { | ||||
|             model: this.sequelize.models.podcastEpisode | ||||
|           } | ||||
|         } | ||||
|       ], | ||||
|       order: [ | ||||
|         // Ensure author & series stay in the same order
 | ||||
|         [this.sequelize.models.book, this.sequelize.models.author, this.sequelize.models.bookAuthor, 'createdAt', 'ASC'], | ||||
|         [this.sequelize.models.book, this.sequelize.models.series, 'bookSeries', 'createdAt', 'ASC'] | ||||
|       ] | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * | ||||
|    * @param {string} libraryItemId | ||||
| @ -611,7 +613,7 @@ class LibraryItem extends Model { | ||||
| 
 | ||||
|     return { | ||||
|       libraryItems: libraryItems.map((li) => { | ||||
|         const oldLibraryItem = this.getOldLibraryItem(li).toJSONMinified() | ||||
|         const oldLibraryItem = li.toOldJSONMinified() | ||||
|         if (li.collapsedSeries) { | ||||
|           oldLibraryItem.collapsedSeries = li.collapsedSeries | ||||
|         } | ||||
|  | ||||
| @ -357,7 +357,7 @@ class Playlist extends Model { | ||||
|         libraryItem.media = pmi.mediaItem | ||||
|         return { | ||||
|           libraryItemId: libraryItem.id, | ||||
|           libraryItem: this.sequelize.models.libraryItem.getOldLibraryItem(libraryItem).toJSONExpanded() | ||||
|           libraryItem: libraryItem.toOldJSONExpanded() | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
| @ -368,7 +368,7 @@ class Playlist extends Model { | ||||
|         episodeId: pmi.mediaItemId, | ||||
|         episode: pmi.mediaItem.toOldJSONExpanded(libraryItem.id), | ||||
|         libraryItemId: libraryItem.id, | ||||
|         libraryItem: this.sequelize.models.libraryItem.getOldLibraryItem(libraryItem).toJSONMinified() | ||||
|         libraryItem: libraryItem.toOldJSONMinified() | ||||
|       } | ||||
|     }) | ||||
| 
 | ||||
|  | ||||
| @ -166,10 +166,6 @@ class Podcast { | ||||
|     return true | ||||
|   } | ||||
| 
 | ||||
|   checkHasEpisode(episodeId) { | ||||
|     return this.episodes.some((ep) => ep.id === episodeId) | ||||
|   } | ||||
| 
 | ||||
|   getEpisode(episodeId) { | ||||
|     if (!episodeId) return null | ||||
| 
 | ||||
|  | ||||
| @ -64,8 +64,7 @@ class LibraryItemScanner { | ||||
| 
 | ||||
|     const { libraryItem: expandedLibraryItem, wasUpdated } = await this.rescanLibraryItemMedia(libraryItem, libraryItemScanData, library.settings, scanLogger) | ||||
|     if (libraryItemDataUpdated || wasUpdated) { | ||||
|       const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(expandedLibraryItem) | ||||
|       SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded()) | ||||
|       SocketAuthority.emitter('item_updated', expandedLibraryItem.toOldJSONExpanded()) | ||||
| 
 | ||||
|       await this.checkAuthorsAndSeriesRemovedFromBooks(library.id, scanLogger) | ||||
| 
 | ||||
|  | ||||
| @ -167,7 +167,7 @@ class LibraryScanner { | ||||
|     if (this.shouldCancelScan(libraryScan)) return true | ||||
| 
 | ||||
|     const libraryItemIdsMissing = [] | ||||
|     let oldLibraryItemsUpdated = [] | ||||
|     let libraryItemsUpdated = [] | ||||
|     for (const existingLibraryItem of existingLibraryItems) { | ||||
|       // First try to find matching library item with exact file path
 | ||||
|       let libraryItemData = libraryItemDataFound.find((lid) => lid.path === existingLibraryItem.path) | ||||
| @ -190,11 +190,11 @@ class LibraryScanner { | ||||
|             libraryItemIdsMissing.push(existingLibraryItem.id) | ||||
| 
 | ||||
|             // TODO: Temporary while using old model to socket emit
 | ||||
|             const oldLibraryItem = await Database.libraryItemModel.getOldById(existingLibraryItem.id) | ||||
|             if (oldLibraryItem) { | ||||
|               oldLibraryItem.isMissing = true | ||||
|               oldLibraryItem.updatedAt = Date.now() | ||||
|               oldLibraryItemsUpdated.push(oldLibraryItem) | ||||
|             const libraryItem = await Database.libraryItemModel.getExpandedById(existingLibraryItem.id) | ||||
|             if (libraryItem) { | ||||
|               libraryItem.isMissing = true | ||||
|               await libraryItem.save() | ||||
|               libraryItemsUpdated.push(libraryItem) | ||||
|             } | ||||
|           } | ||||
|         } | ||||
| @ -206,16 +206,15 @@ class LibraryScanner { | ||||
|             const { libraryItem, wasUpdated } = await LibraryItemScanner.rescanLibraryItemMedia(existingLibraryItem, libraryItemData, libraryScan.library.settings, libraryScan) | ||||
|             if (!forceRescan || wasUpdated) { | ||||
|               libraryScan.resultsUpdated++ | ||||
|               const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem) | ||||
|               oldLibraryItemsUpdated.push(oldLibraryItem) | ||||
|               libraryItemsUpdated.push(libraryItem) | ||||
|             } else { | ||||
|               libraryScan.addLog(LogLevel.DEBUG, `Library item "${existingLibraryItem.relPath}" is up-to-date`) | ||||
|             } | ||||
|           } else { | ||||
|             libraryScan.resultsUpdated++ | ||||
|             // TODO: Temporary while using old model to socket emit
 | ||||
|             const oldLibraryItem = await Database.libraryItemModel.getOldById(existingLibraryItem.id) | ||||
|             oldLibraryItemsUpdated.push(oldLibraryItem) | ||||
|             const libraryItem = await Database.libraryItemModel.getExpandedById(existingLibraryItem.id) | ||||
|             libraryItemsUpdated.push(libraryItem) | ||||
|           } | ||||
|         } else { | ||||
|           libraryScan.addLog(LogLevel.DEBUG, `Library item "${existingLibraryItem.relPath}" is up-to-date`) | ||||
| @ -223,23 +222,23 @@ class LibraryScanner { | ||||
|       } | ||||
| 
 | ||||
|       // Emit item updates in chunks of 10 to client
 | ||||
|       if (oldLibraryItemsUpdated.length === 10) { | ||||
|       if (libraryItemsUpdated.length === 10) { | ||||
|         // TODO: Should only emit to clients where library item is accessible
 | ||||
|         SocketAuthority.emitter( | ||||
|           'items_updated', | ||||
|           oldLibraryItemsUpdated.map((li) => li.toJSONExpanded()) | ||||
|           libraryItemsUpdated.map((li) => li.toOldJSONExpanded()) | ||||
|         ) | ||||
|         oldLibraryItemsUpdated = [] | ||||
|         libraryItemsUpdated = [] | ||||
|       } | ||||
| 
 | ||||
|       if (this.shouldCancelScan(libraryScan)) return true | ||||
|     } | ||||
|     // Emit item updates to client
 | ||||
|     if (oldLibraryItemsUpdated.length) { | ||||
|     if (libraryItemsUpdated.length) { | ||||
|       // TODO: Should only emit to clients where library item is accessible
 | ||||
|       SocketAuthority.emitter( | ||||
|         'items_updated', | ||||
|         oldLibraryItemsUpdated.map((li) => li.toJSONExpanded()) | ||||
|         libraryItemsUpdated.map((li) => li.toOldJSONExpanded()) | ||||
|       ) | ||||
|     } | ||||
| 
 | ||||
| @ -267,34 +266,33 @@ class LibraryScanner { | ||||
| 
 | ||||
|     // Add new library items
 | ||||
|     if (libraryItemDataFound.length) { | ||||
|       let newOldLibraryItems = [] | ||||
|       let newLibraryItems = [] | ||||
|       for (const libraryItemData of libraryItemDataFound) { | ||||
|         const newLibraryItem = await LibraryItemScanner.scanNewLibraryItem(libraryItemData, libraryScan.library.settings, libraryScan) | ||||
|         if (newLibraryItem) { | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(newLibraryItem) | ||||
|           newOldLibraryItems.push(oldLibraryItem) | ||||
|           newLibraryItems.push(newLibraryItem) | ||||
| 
 | ||||
|           libraryScan.resultsAdded++ | ||||
|         } | ||||
| 
 | ||||
|         // Emit new items in chunks of 10 to client
 | ||||
|         if (newOldLibraryItems.length === 10) { | ||||
|         if (newLibraryItems.length === 10) { | ||||
|           // TODO: Should only emit to clients where library item is accessible
 | ||||
|           SocketAuthority.emitter( | ||||
|             'items_added', | ||||
|             newOldLibraryItems.map((li) => li.toJSONExpanded()) | ||||
|             newLibraryItems.map((li) => li.toOldJSONExpanded()) | ||||
|           ) | ||||
|           newOldLibraryItems = [] | ||||
|           newLibraryItems = [] | ||||
|         } | ||||
| 
 | ||||
|         if (this.shouldCancelScan(libraryScan)) return true | ||||
|       } | ||||
|       // Emit new items to client
 | ||||
|       if (newOldLibraryItems.length) { | ||||
|       if (newLibraryItems.length) { | ||||
|         // TODO: Should only emit to clients where library item is accessible
 | ||||
|         SocketAuthority.emitter( | ||||
|           'items_added', | ||||
|           newOldLibraryItems.map((li) => li.toJSONExpanded()) | ||||
|           newLibraryItems.map((li) => li.toOldJSONExpanded()) | ||||
|         ) | ||||
|       } | ||||
|     } | ||||
| @ -645,8 +643,7 @@ class LibraryScanner { | ||||
|       const isSingleMediaItem = isSingleMediaFile(fileUpdateGroup, itemDir) | ||||
|       const newLibraryItem = await LibraryItemScanner.scanPotentialNewLibraryItem(fullPath, library, folder, isSingleMediaItem) | ||||
|       if (newLibraryItem) { | ||||
|         const oldNewLibraryItem = Database.libraryItemModel.getOldLibraryItem(newLibraryItem) | ||||
|         SocketAuthority.emitter('item_added', oldNewLibraryItem.toJSONExpanded()) | ||||
|         SocketAuthority.emitter('item_added', newLibraryItem.toOldJSONExpanded()) | ||||
|       } | ||||
|       itemGroupingResults[itemDir] = newLibraryItem ? ScanResult.ADDED : ScanResult.NOTHING | ||||
|     } | ||||
|  | ||||
| @ -1200,7 +1200,7 @@ async function migrationPatchNewColumns(queryInterface) { | ||||
|  */ | ||||
| async function handleOldLibraryItems(ctx) { | ||||
|   const oldLibraryItems = await oldDbFiles.loadOldData('libraryItems') | ||||
|   const libraryItems = await ctx.models.libraryItem.getAllOldLibraryItems() | ||||
|   const libraryItems = (await ctx.models.libraryItem.findAllExpandedWhere()).map((li) => ctx.models.libraryItem.getOldLibraryItem(li)) | ||||
| 
 | ||||
|   const bulkUpdateItems = [] | ||||
|   const bulkUpdateEpisodes = [] | ||||
|  | ||||
| @ -18,7 +18,7 @@ module.exports = { | ||||
|    * @param {string} libraryId | ||||
|    * @param {import('../../models/User')} user | ||||
|    * @param {object} options | ||||
|    * @returns {object} { libraryItems:LibraryItem[], count:number } | ||||
|    * @returns {Promise<{ libraryItems:import('../../models/LibraryItem')[], count:number }>} | ||||
|    */ | ||||
|   async getFilteredLibraryItems(libraryId, user, options) { | ||||
|     const { filterBy, sortBy, sortDesc, limit, offset, collapseseries, include, mediaType } = options | ||||
| @ -52,7 +52,7 @@ module.exports = { | ||||
|       const { libraryItems, count } = await libraryItemsBookFilters.getFilteredLibraryItems(library.id, user, 'progress', 'in-progress', 'progress', true, false, include, limit, 0, true) | ||||
|       return { | ||||
|         items: libraryItems.map((li) => { | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|           const oldLibraryItem = li.toOldJSONMinified() | ||||
|           if (li.rssFeed) { | ||||
|             oldLibraryItem.rssFeed = li.rssFeed.toOldJSONMinified() | ||||
|           } | ||||
| @ -68,7 +68,7 @@ module.exports = { | ||||
|       return { | ||||
|         count, | ||||
|         items: libraryItems.map((li) => { | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|           const oldLibraryItem = li.toOldJSONMinified() | ||||
|           oldLibraryItem.recentEpisode = li.recentEpisode | ||||
|           return oldLibraryItem | ||||
|         }) | ||||
| @ -89,7 +89,7 @@ module.exports = { | ||||
|       const { libraryItems, count } = await libraryItemsBookFilters.getFilteredLibraryItems(library.id, user, 'recent', null, 'addedAt', true, false, include, limit, 0) | ||||
|       return { | ||||
|         libraryItems: libraryItems.map((li) => { | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|           const oldLibraryItem = li.toOldJSONMinified() | ||||
|           if (li.rssFeed) { | ||||
|             oldLibraryItem.rssFeed = li.rssFeed.toOldJSONMinified() | ||||
|           } | ||||
| @ -107,7 +107,7 @@ module.exports = { | ||||
|       const { libraryItems, count } = await libraryItemsPodcastFilters.getFilteredLibraryItems(library.id, user, 'recent', null, 'addedAt', true, include, limit, 0) | ||||
|       return { | ||||
|         libraryItems: libraryItems.map((li) => { | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|           const oldLibraryItem = li.toOldJSONMinified() | ||||
|           if (li.rssFeed) { | ||||
|             oldLibraryItem.rssFeed = li.rssFeed.toOldJSONMinified() | ||||
|           } | ||||
| @ -136,7 +136,7 @@ module.exports = { | ||||
|     const { libraryItems, count } = await libraryItemsBookFilters.getContinueSeriesLibraryItems(library, user, include, limit, 0) | ||||
|     return { | ||||
|       libraryItems: libraryItems.map((li) => { | ||||
|         const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|         const oldLibraryItem = li.toOldJSONMinified() | ||||
|         if (li.rssFeed) { | ||||
|           oldLibraryItem.rssFeed = li.rssFeed.toOldJSONMinified() | ||||
|         } | ||||
| @ -166,7 +166,7 @@ module.exports = { | ||||
|       const { libraryItems, count } = await libraryItemsBookFilters.getFilteredLibraryItems(library.id, user, 'progress', 'finished', 'progress', true, false, include, limit, 0) | ||||
|       return { | ||||
|         items: libraryItems.map((li) => { | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|           const oldLibraryItem = li.toOldJSONMinified() | ||||
|           if (li.rssFeed) { | ||||
|             oldLibraryItem.rssFeed = li.rssFeed.toOldJSONMinified() | ||||
|           } | ||||
| @ -182,7 +182,7 @@ module.exports = { | ||||
|       return { | ||||
|         count, | ||||
|         items: libraryItems.map((li) => { | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|           const oldLibraryItem = li.toOldJSONMinified() | ||||
|           oldLibraryItem.recentEpisode = li.recentEpisode | ||||
|           return oldLibraryItem | ||||
|         }) | ||||
| @ -293,15 +293,17 @@ module.exports = { | ||||
|       }) | ||||
|       oldSeries.books = s.bookSeries | ||||
|         .map((bs) => { | ||||
|           const libraryItem = bs.book.libraryItem?.toJSON() | ||||
|           const libraryItem = bs.book.libraryItem | ||||
|           if (!libraryItem) { | ||||
|             Logger.warn(`Book series book has no libraryItem`, bs, bs.book, 'series=', series) | ||||
|             return null | ||||
|           } | ||||
| 
 | ||||
|           delete bs.book.libraryItem | ||||
|           bs.book.authors = [] // Not needed
 | ||||
|           bs.book.series = [] // Not needed
 | ||||
|           libraryItem.media = bs.book | ||||
|           const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem).toJSONMinified() | ||||
|           const oldLibraryItem = libraryItem.toOldJSONMinified() | ||||
|           return oldLibraryItem | ||||
|         }) | ||||
|         .filter((b) => b) | ||||
| @ -373,7 +375,7 @@ module.exports = { | ||||
|     const { libraryItems, count } = await libraryItemsBookFilters.getDiscoverLibraryItems(library.id, user, include, limit) | ||||
|     return { | ||||
|       libraryItems: libraryItems.map((li) => { | ||||
|         const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|         const oldLibraryItem = li.toOldJSONMinified() | ||||
|         if (li.rssFeed) { | ||||
|           oldLibraryItem.rssFeed = li.rssFeed.toOldJSONMinified() | ||||
|         } | ||||
| @ -400,7 +402,7 @@ module.exports = { | ||||
|     return { | ||||
|       count, | ||||
|       libraryItems: libraryItems.map((li) => { | ||||
|         const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(li).toJSONMinified() | ||||
|         const oldLibraryItem = li.toOldJSONMinified() | ||||
|         oldLibraryItem.recentEpisode = li.recentEpisode | ||||
|         return oldLibraryItem | ||||
|       }) | ||||
|  | ||||
| @ -349,7 +349,7 @@ module.exports = { | ||||
|    * @param {number} limit | ||||
|    * @param {number} offset | ||||
|    * @param {boolean} isHomePage for home page shelves | ||||
|    * @returns {object} { libraryItems:LibraryItem[], count:number } | ||||
|    * @returns {{ libraryItems: import('../../models/LibraryItem')[], count: number }} | ||||
|    */ | ||||
|   async getFilteredLibraryItems(libraryId, user, filterGroup, filterValue, sortBy, sortDesc, collapseseries, include, limit, offset, isHomePage = false) { | ||||
|     // TODO: Handle collapse sub-series
 | ||||
| @ -583,8 +583,8 @@ module.exports = { | ||||
|     }) | ||||
| 
 | ||||
|     const libraryItems = books.map((bookExpanded) => { | ||||
|       const libraryItem = bookExpanded.libraryItem.toJSON() | ||||
|       const book = bookExpanded.toJSON() | ||||
|       const libraryItem = bookExpanded.libraryItem | ||||
|       const book = bookExpanded | ||||
| 
 | ||||
|       if (filterGroup === 'series' && book.series?.length) { | ||||
|         // For showing sequence on book cover when filtering for series
 | ||||
| @ -596,27 +596,37 @@ module.exports = { | ||||
|       } | ||||
| 
 | ||||
|       delete book.libraryItem | ||||
|       delete book.authors | ||||
|       delete book.series | ||||
| 
 | ||||
|       book.series = | ||||
|         book.bookSeries?.map((bs) => { | ||||
|           const series = bs.series | ||||
|           delete bs.series | ||||
|           series.bookSeries = bs | ||||
|           return series | ||||
|         }) || [] | ||||
|       delete book.bookSeries | ||||
| 
 | ||||
|       book.authors = book.bookAuthors?.map((ba) => ba.author) || [] | ||||
|       delete book.bookAuthors | ||||
| 
 | ||||
|       // For showing details of collapsed series
 | ||||
|       if (collapseseries && book.bookSeries?.length) { | ||||
|         const collapsedSeries = book.bookSeries.find((bs) => collapseSeriesBookSeries.some((cbs) => cbs.id === bs.id)) | ||||
|       if (collapseseries && book.series?.length) { | ||||
|         const collapsedSeries = book.series.find((bs) => collapseSeriesBookSeries.some((cbs) => cbs.id === bs.bookSeries.id)) | ||||
|         if (collapsedSeries) { | ||||
|           const collapseSeriesObj = collapseSeriesBookSeries.find((csbs) => csbs.id === collapsedSeries.id) | ||||
|           const collapseSeriesObj = collapseSeriesBookSeries.find((csbs) => csbs.id === collapsedSeries.bookSeries.id) | ||||
|           libraryItem.collapsedSeries = { | ||||
|             id: collapsedSeries.series.id, | ||||
|             name: collapsedSeries.series.name, | ||||
|             nameIgnorePrefix: collapsedSeries.series.nameIgnorePrefix, | ||||
|             sequence: collapsedSeries.sequence, | ||||
|             id: collapsedSeries.id, | ||||
|             name: collapsedSeries.name, | ||||
|             nameIgnorePrefix: collapsedSeries.nameIgnorePrefix, | ||||
|             sequence: collapsedSeries.bookSeries.sequence, | ||||
|             numBooks: collapseSeriesObj?.numBooks || 0, | ||||
|             libraryItemIds: collapseSeriesObj?.libraryItemIds || [] | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       if (bookExpanded.libraryItem.feeds?.length) { | ||||
|         libraryItem.rssFeed = bookExpanded.libraryItem.feeds[0] | ||||
|       if (libraryItem.feeds?.length) { | ||||
|         libraryItem.rssFeed = libraryItem.feeds[0] | ||||
|       } | ||||
| 
 | ||||
|       if (includeMediaItemShare) { | ||||
| @ -646,7 +656,7 @@ module.exports = { | ||||
|    * @param {string[]} include | ||||
|    * @param {number} limit | ||||
|    * @param {number} offset | ||||
|    * @returns {{ libraryItems:import('../../models/LibraryItem')[], count:number }} | ||||
|    * @returns {Promise<{ libraryItems:import('../../models/LibraryItem')[], count:number }>} | ||||
|    */ | ||||
|   async getContinueSeriesLibraryItems(library, user, include, limit, offset) { | ||||
|     const libraryId = library.id | ||||
| @ -758,16 +768,19 @@ module.exports = { | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         const libraryItem = s.bookSeries[bookIndex].book.libraryItem.toJSON() | ||||
|         const book = s.bookSeries[bookIndex].book.toJSON() | ||||
|         const libraryItem = s.bookSeries[bookIndex].book.libraryItem | ||||
|         const book = s.bookSeries[bookIndex].book | ||||
|         delete book.libraryItem | ||||
| 
 | ||||
|         book.series = [] | ||||
| 
 | ||||
|         libraryItem.series = { | ||||
|           id: s.id, | ||||
|           name: s.name, | ||||
|           sequence: s.bookSeries[bookIndex].sequence | ||||
|         } | ||||
|         if (s.bookSeries[bookIndex].book.libraryItem.feeds?.length) { | ||||
|           libraryItem.rssFeed = s.bookSeries[bookIndex].book.libraryItem.feeds[0] | ||||
|         if (libraryItem.feeds?.length) { | ||||
|           libraryItem.rssFeed = libraryItem.feeds[0] | ||||
|         } | ||||
|         libraryItem.media = book | ||||
|         return libraryItem | ||||
| @ -788,7 +801,7 @@ module.exports = { | ||||
|    * @param {import('../../models/User')} user | ||||
|    * @param {string[]} include | ||||
|    * @param {number} limit | ||||
|    * @returns {object} {libraryItems:LibraryItem, count:number} | ||||
|    * @returns {Promise<{ libraryItems: import('../../models/LibraryItem')[], count: number }>} | ||||
|    */ | ||||
|   async getDiscoverLibraryItems(libraryId, user, include, limit) { | ||||
|     const userPermissionBookWhere = this.getUserPermissionBookWhereQuery(user) | ||||
| @ -895,13 +908,26 @@ module.exports = { | ||||
| 
 | ||||
|     // Step 3: Map books to library items
 | ||||
|     const libraryItems = books.map((bookExpanded) => { | ||||
|       const libraryItem = bookExpanded.libraryItem.toJSON() | ||||
|       const book = bookExpanded.toJSON() | ||||
|       const libraryItem = bookExpanded.libraryItem | ||||
|       const book = bookExpanded | ||||
|       delete book.libraryItem | ||||
| 
 | ||||
|       book.series = | ||||
|         book.bookSeries?.map((bs) => { | ||||
|           const series = bs.series | ||||
|           delete bs.series | ||||
|           series.bookSeries = bs | ||||
|           return series | ||||
|         }) || [] | ||||
|       delete book.bookSeries | ||||
| 
 | ||||
|       book.authors = book.bookAuthors?.map((ba) => ba.author) || [] | ||||
|       delete book.bookAuthors | ||||
| 
 | ||||
|       libraryItem.media = book | ||||
| 
 | ||||
|       if (bookExpanded.libraryItem.feeds?.length) { | ||||
|         libraryItem.rssFeed = bookExpanded.libraryItem.feeds[0] | ||||
|       if (libraryItem.feeds?.length) { | ||||
|         libraryItem.rssFeed = libraryItem.feeds[0] | ||||
|       } | ||||
| 
 | ||||
|       return libraryItem | ||||
| @ -961,11 +987,11 @@ module.exports = { | ||||
|    * Get library items for series | ||||
|    * @param {import('../../models/Series')} series | ||||
|    * @param {import('../../models/User')} [user] | ||||
|    * @returns {Promise<import('../../objects/LibraryItem')[]>} | ||||
|    * @returns {Promise<import('../../models/LibraryItem')[]>} | ||||
|    */ | ||||
|   async getLibraryItemsForSeries(series, user) { | ||||
|     const { libraryItems } = await this.getFilteredLibraryItems(series.libraryId, user, 'series', series.id, null, null, false, [], null, null) | ||||
|     return libraryItems.map((li) => Database.libraryItemModel.getOldLibraryItem(li)) | ||||
|     return libraryItems | ||||
|   }, | ||||
| 
 | ||||
|   /** | ||||
| @ -1040,9 +1066,21 @@ module.exports = { | ||||
|     for (const book of books) { | ||||
|       const libraryItem = book.libraryItem | ||||
|       delete book.libraryItem | ||||
| 
 | ||||
|       book.series = book.bookSeries.map((bs) => { | ||||
|         const series = bs.series | ||||
|         delete bs.series | ||||
|         series.bookSeries = bs | ||||
|         return series | ||||
|       }) | ||||
|       delete book.bookSeries | ||||
| 
 | ||||
|       book.authors = book.bookAuthors.map((ba) => ba.author) | ||||
|       delete book.bookAuthors | ||||
| 
 | ||||
|       libraryItem.media = book | ||||
|       itemMatches.push({ | ||||
|         libraryItem: Database.libraryItemModel.getOldLibraryItem(libraryItem).toJSONExpanded() | ||||
|         libraryItem: libraryItem.toOldJSONExpanded() | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
| @ -1132,7 +1170,9 @@ module.exports = { | ||||
|       const books = series.bookSeries.map((bs) => { | ||||
|         const libraryItem = bs.book.libraryItem | ||||
|         libraryItem.media = bs.book | ||||
|         return Database.libraryItemModel.getOldLibraryItem(libraryItem).toJSON() | ||||
|         libraryItem.media.authors = [] | ||||
|         libraryItem.media.series = [] | ||||
|         return libraryItem.toOldJSON() | ||||
|       }) | ||||
|       seriesMatches.push({ | ||||
|         series: series.toOldJSON(), | ||||
|  | ||||
| @ -107,7 +107,7 @@ module.exports = { | ||||
|    * @param {string[]} include | ||||
|    * @param {number} limit | ||||
|    * @param {number} offset | ||||
|    * @returns {object} { libraryItems:LibraryItem[], count:number } | ||||
|    * @returns {Promise<{ libraryItems: import('../../models/LibraryItem')[], count: number }>} | ||||
|    */ | ||||
|   async getFilteredLibraryItems(libraryId, user, filterGroup, filterValue, sortBy, sortDesc, include, limit, offset) { | ||||
|     const includeRSSFeed = include.includes('rssfeed') | ||||
| @ -175,16 +175,19 @@ module.exports = { | ||||
|     }) | ||||
| 
 | ||||
|     const libraryItems = podcasts.map((podcastExpanded) => { | ||||
|       const libraryItem = podcastExpanded.libraryItem.toJSON() | ||||
|       const podcast = podcastExpanded.toJSON() | ||||
|       const libraryItem = podcastExpanded.libraryItem | ||||
|       const podcast = podcastExpanded | ||||
| 
 | ||||
|       delete podcast.libraryItem | ||||
| 
 | ||||
|       if (podcastExpanded.libraryItem.feeds?.length) { | ||||
|         libraryItem.rssFeed = podcastExpanded.libraryItem.feeds[0] | ||||
|       if (libraryItem.feeds?.length) { | ||||
|         libraryItem.rssFeed = libraryItem.feeds[0] | ||||
|       } | ||||
|       if (podcast.numEpisodesIncomplete) { | ||||
|         libraryItem.numEpisodesIncomplete = podcast.numEpisodesIncomplete | ||||
|       if (podcast.dataValues.numEpisodesIncomplete) { | ||||
|         libraryItem.numEpisodesIncomplete = podcast.dataValues.numEpisodesIncomplete | ||||
|       } | ||||
|       if (podcast.dataValues.numEpisodes) { | ||||
|         podcast.numEpisodes = podcast.dataValues.numEpisodes | ||||
|       } | ||||
| 
 | ||||
|       libraryItem.media = podcast | ||||
| @ -209,7 +212,7 @@ module.exports = { | ||||
|    * @param {number} limit | ||||
|    * @param {number} offset | ||||
|    * @param {boolean} isHomePage for home page shelves | ||||
|    * @returns {object} {libraryItems:LibraryItem[], count:number} | ||||
|    * @returns {Promise<{ libraryItems: import('../../models/LibraryItem')[], count: number }>} | ||||
|    */ | ||||
|   async getFilteredPodcastEpisodes(libraryId, user, filterGroup, filterValue, sortBy, sortDesc, limit, offset, isHomePage = false) { | ||||
|     if (sortBy === 'progress' && filterGroup !== 'progress') { | ||||
| @ -289,10 +292,11 @@ module.exports = { | ||||
|     }) | ||||
| 
 | ||||
|     const libraryItems = podcastEpisodes.map((ep) => { | ||||
|       const libraryItem = ep.podcast.libraryItem.toJSON() | ||||
|       const podcast = ep.podcast.toJSON() | ||||
|       const libraryItem = ep.podcast.libraryItem | ||||
|       const podcast = ep.podcast | ||||
|       delete podcast.libraryItem | ||||
|       libraryItem.media = podcast | ||||
| 
 | ||||
|       libraryItem.recentEpisode = ep.getOldPodcastEpisode(libraryItem.id).toJSON() | ||||
|       return libraryItem | ||||
|     }) | ||||
| @ -362,8 +366,9 @@ module.exports = { | ||||
|       const libraryItem = podcast.libraryItem | ||||
|       delete podcast.libraryItem | ||||
|       libraryItem.media = podcast | ||||
|       libraryItem.media.podcastEpisodes = [] | ||||
|       itemMatches.push({ | ||||
|         libraryItem: Database.libraryItemModel.getOldLibraryItem(libraryItem).toJSONExpanded() | ||||
|         libraryItem: libraryItem.toOldJSONExpanded() | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -162,6 +162,12 @@ module.exports = { | ||||
|             include: [ | ||||
|               { | ||||
|                 model: Database.libraryItemModel | ||||
|               }, | ||||
|               { | ||||
|                 model: Database.authorModel | ||||
|               }, | ||||
|               { | ||||
|                 model: Database.seriesModel | ||||
|               } | ||||
|             ] | ||||
|           }, | ||||
| @ -195,10 +201,10 @@ module.exports = { | ||||
|         }) | ||||
|       }) | ||||
|       oldSeries.books = s.bookSeries.map((bs) => { | ||||
|         const libraryItem = bs.book.libraryItem.toJSON() | ||||
|         const libraryItem = bs.book.libraryItem | ||||
|         delete bs.book.libraryItem | ||||
|         libraryItem.media = bs.book | ||||
|         const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem).toJSONMinified() | ||||
|         const oldLibraryItem = libraryItem.toOldJSONMinified() | ||||
|         return oldLibraryItem | ||||
|       }) | ||||
|       allOldSeries.push(oldSeries) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user