diff --git a/server/SocketAuthority.js b/server/SocketAuthority.js index 19c686d9..050e7e2f 100644 --- a/server/SocketAuthority.js +++ b/server/SocketAuthority.js @@ -84,6 +84,42 @@ class SocketAuthority { } } + /** + * Emits event with library item to all clients that can access the library item + * Note: Emits toOldJSONExpanded() + * + * @param {string} evt + * @param {import('./models/LibraryItem')} libraryItem + */ + libraryItemEmitter(evt, libraryItem) { + for (const socketId in this.clients) { + if (this.clients[socketId].user?.checkCanAccessLibraryItem(libraryItem)) { + this.clients[socketId].socket.emit(evt, libraryItem.toOldJSONExpanded()) + } + } + } + + /** + * Emits event with library items to all clients that can access the library items + * Note: Emits toOldJSONExpanded() + * + * @param {string} evt + * @param {import('./models/LibraryItem')[]} libraryItems + */ + libraryItemsEmitter(evt, libraryItems) { + for (const socketId in this.clients) { + if (this.clients[socketId].user) { + const libraryItemsAccessibleToUser = libraryItems.filter((li) => this.clients[socketId].user.checkCanAccessLibraryItem(li)) + if (libraryItemsAccessibleToUser.length) { + this.clients[socketId].socket.emit( + evt, + libraryItemsAccessibleToUser.map((li) => li.toOldJSONExpanded()) + ) + } + } + } + } + /** * Closes the Socket.IO server and disconnect all clients * diff --git a/server/controllers/AuthorController.js b/server/controllers/AuthorController.js index 47150883..50eeda31 100644 --- a/server/controllers/AuthorController.js +++ b/server/controllers/AuthorController.js @@ -152,10 +152,7 @@ class AuthorController { for (const libraryItem of libraryItems) { await libraryItem.saveMetadataFile() } - SocketAuthority.emitter( - 'items_updated', - libraryItems.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_updated', libraryItems) } // Remove old author @@ -210,10 +207,7 @@ class AuthorController { } if (libraryItems.length) { - SocketAuthority.emitter( - 'items_updated', - libraryItems.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_updated', libraryItems) } } else { numBooksForAuthor = await Database.bookAuthorModel.getCountForAuthor(req.author.id) diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js index f9aeba3f..e63441f0 100644 --- a/server/controllers/LibraryController.js +++ b/server/controllers/LibraryController.js @@ -1188,10 +1188,7 @@ class LibraryController { } if (itemsUpdated.length) { - SocketAuthority.emitter( - 'items_updated', - itemsUpdated.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_updated', itemsUpdated) } res.json({ @@ -1232,10 +1229,7 @@ class LibraryController { } if (itemsUpdated.length) { - SocketAuthority.emitter( - 'items_updated', - itemsUpdated.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_updated', itemsUpdated) } res.json({ diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js index 2e696ff0..768a23dc 100644 --- a/server/controllers/LibraryItemController.js +++ b/server/controllers/LibraryItemController.js @@ -253,7 +253,7 @@ class LibraryItemController { } Logger.debug(`[LibraryItemController] Updated library item media ${req.libraryItem.media.title}`) - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) } res.json({ updated: hasUpdates, @@ -300,7 +300,7 @@ class LibraryItemController { req.libraryItem.changed('updatedAt', true) await req.libraryItem.save() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) res.json({ success: true, cover: result.cover @@ -332,7 +332,7 @@ class LibraryItemController { req.libraryItem.changed('updatedAt', true) await req.libraryItem.save() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) } res.json({ success: true, @@ -358,7 +358,7 @@ class LibraryItemController { await CacheManager.purgeCoverCache(req.libraryItem.id) - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) } res.sendStatus(200) @@ -485,7 +485,7 @@ class LibraryItemController { req.libraryItem.media.changed('audioFiles', true) await req.libraryItem.media.save() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) res.json(req.libraryItem.toOldJSON()) } @@ -663,7 +663,7 @@ class LibraryItemController { await libraryItem.saveMetadataFile() Logger.debug(`[LibraryItemController] Updated library item media "${libraryItem.media.title}"`) - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) itemsUpdated++ } } @@ -894,7 +894,7 @@ class LibraryItemController { await req.libraryItem.saveMetadataFile() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) } res.json({ @@ -1005,7 +1005,7 @@ class LibraryItemController { await req.libraryItem.save() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) res.sendStatus(200) } @@ -1153,7 +1153,7 @@ class LibraryItemController { await req.libraryItem.save() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) res.sendStatus(200) } diff --git a/server/controllers/MiscController.js b/server/controllers/MiscController.js index 48eca3f8..0e9f0377 100644 --- a/server/controllers/MiscController.js +++ b/server/controllers/MiscController.js @@ -343,7 +343,7 @@ class MiscController { }) await libraryItem.saveMetadataFile() - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) numItemsUpdated++ } } @@ -386,7 +386,7 @@ class MiscController { }) await libraryItem.saveMetadataFile() - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) numItemsUpdated++ } @@ -481,7 +481,7 @@ class MiscController { }) await libraryItem.saveMetadataFile() - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) numItemsUpdated++ } } @@ -524,7 +524,7 @@ class MiscController { }) await libraryItem.saveMetadataFile() - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) numItemsUpdated++ } diff --git a/server/controllers/PodcastController.js b/server/controllers/PodcastController.js index c66b4088..6395e05b 100644 --- a/server/controllers/PodcastController.js +++ b/server/controllers/PodcastController.js @@ -161,7 +161,7 @@ class PodcastController { } } - SocketAuthority.emitter('item_added', newLibraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_added', newLibraryItem) res.json(newLibraryItem.toOldJSONExpanded()) @@ -379,7 +379,7 @@ class PodcastController { const overrideDetails = req.query.override === '1' const episodesUpdated = await Scanner.quickMatchPodcastEpisodes(req.libraryItem, { overrideDetails }) if (episodesUpdated) { - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) } res.json({ @@ -418,7 +418,7 @@ class PodcastController { Logger.info(`[PodcastController] Updated episode "${episode.title}" keys`, episode.changed()) await episode.save() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) } else { Logger.info(`[PodcastController] No changes to episode "${episode.title}"`) } @@ -504,7 +504,7 @@ class PodcastController { req.libraryItem.media.numEpisodes = req.libraryItem.media.podcastEpisodes.length await req.libraryItem.media.save() - SocketAuthority.emitter('item_updated', req.libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', req.libraryItem) res.json(req.libraryItem.toOldJSON()) } diff --git a/server/managers/PodcastManager.js b/server/managers/PodcastManager.js index 9c621ea1..052ba8b3 100644 --- a/server/managers/PodcastManager.js +++ b/server/managers/PodcastManager.js @@ -254,7 +254,7 @@ class PodcastManager { await libraryItem.media.save() } - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) const podcastEpisodeExpanded = podcastEpisode.toOldJSONExpanded(libraryItem.id) podcastEpisodeExpanded.libraryItem = libraryItem.toOldJSONExpanded() SocketAuthority.emitter('episode_added', podcastEpisodeExpanded) @@ -367,7 +367,7 @@ class PodcastManager { libraryItem.changed('updatedAt', true) await libraryItem.save() - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) return libraryItem.media.autoDownloadEpisodes } @@ -425,7 +425,7 @@ class PodcastManager { libraryItem.changed('updatedAt', true) await libraryItem.save() - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) return newEpisodes || [] } @@ -712,7 +712,7 @@ class PodcastManager { } } - SocketAuthority.emitter('item_added', newLibraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_added', newLibraryItem) // Turn on podcast auto download cron if not already on if (newLibraryItem.media.autoDownloadEpisodes) { diff --git a/server/scanner/LibraryItemScanner.js b/server/scanner/LibraryItemScanner.js index bd99060c..133a1e30 100644 --- a/server/scanner/LibraryItemScanner.js +++ b/server/scanner/LibraryItemScanner.js @@ -64,7 +64,7 @@ class LibraryItemScanner { const { libraryItem: expandedLibraryItem, wasUpdated } = await this.rescanLibraryItemMedia(libraryItem, libraryItemScanData, library.settings, scanLogger) if (libraryItemDataUpdated || wasUpdated) { - SocketAuthority.emitter('item_updated', expandedLibraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', expandedLibraryItem) await this.checkAuthorsAndSeriesRemovedFromBooks(library.id, scanLogger) diff --git a/server/scanner/LibraryScanner.js b/server/scanner/LibraryScanner.js index 1e92efde..4d0285dd 100644 --- a/server/scanner/LibraryScanner.js +++ b/server/scanner/LibraryScanner.js @@ -223,11 +223,7 @@ class LibraryScanner { // Emit item updates in chunks of 10 to client if (libraryItemsUpdated.length === 10) { - // TODO: Should only emit to clients where library item is accessible - SocketAuthority.emitter( - 'items_updated', - libraryItemsUpdated.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_updated', libraryItemsUpdated) libraryItemsUpdated = [] } @@ -235,11 +231,7 @@ class LibraryScanner { } // Emit item updates to client if (libraryItemsUpdated.length) { - // TODO: Should only emit to clients where library item is accessible - SocketAuthority.emitter( - 'items_updated', - libraryItemsUpdated.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_updated', libraryItemsUpdated) } // Authors and series that were removed from books should be removed if they are now empty @@ -277,11 +269,7 @@ class LibraryScanner { // Emit new items in chunks of 10 to client if (newLibraryItems.length === 10) { - // TODO: Should only emit to clients where library item is accessible - SocketAuthority.emitter( - 'items_added', - newLibraryItems.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_added', newLibraryItems) newLibraryItems = [] } @@ -289,11 +277,7 @@ class LibraryScanner { } // Emit new items to client if (newLibraryItems.length) { - // TODO: Should only emit to clients where library item is accessible - SocketAuthority.emitter( - 'items_added', - newLibraryItems.map((li) => li.toOldJSONExpanded()) - ) + SocketAuthority.libraryItemsEmitter('items_added', newLibraryItems) } } @@ -609,7 +593,7 @@ class LibraryScanner { Logger.info(`[LibraryScanner] Scanning file update group and library item was deleted "${existingLibraryItem.media.title}" - marking as missing`) existingLibraryItem.isMissing = true await existingLibraryItem.save() - SocketAuthority.emitter('item_updated', existingLibraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', existingLibraryItem) itemGroupingResults[itemDir] = ScanResult.REMOVED continue @@ -643,7 +627,7 @@ class LibraryScanner { const isSingleMediaItem = isSingleMediaFile(fileUpdateGroup, itemDir) const newLibraryItem = await LibraryItemScanner.scanPotentialNewLibraryItem(fullPath, library, folder, isSingleMediaItem) if (newLibraryItem) { - SocketAuthority.emitter('item_added', newLibraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_added', newLibraryItem) } itemGroupingResults[itemDir] = newLibraryItem ? ScanResult.ADDED : ScanResult.NOTHING } diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js index c5c62532..1e2751ed 100644 --- a/server/scanner/Scanner.js +++ b/server/scanner/Scanner.js @@ -126,7 +126,7 @@ class Scanner { await libraryItem.saveMetadataFile() - SocketAuthority.emitter('item_updated', libraryItem.toOldJSONExpanded()) + SocketAuthority.libraryItemEmitter('item_updated', libraryItem) } return {