From 21343ffbd1bd78dda02396dc5be96c978b28b344 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 20 Aug 2023 13:16:53 -0500 Subject: [PATCH] Update numIssues on filter data, fix watcher scanning in new items --- server/Database.js | 40 +++++++++++++++++++++ server/controllers/LibraryController.js | 21 +++++++++-- server/controllers/LibraryItemController.js | 8 ++++- server/scanner/Scanner.js | 13 ++++--- 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/server/Database.js b/server/Database.js index 1d9bbaa3..7bdff528 100644 --- a/server/Database.js +++ b/server/Database.js @@ -69,6 +69,10 @@ class Database { return this.models.mediaProgress } + /** + * Check if db file exists + * @returns {boolean} + */ async checkHasDb() { if (!await fs.pathExists(this.dbPath)) { Logger.info(`[Database] absdatabase.sqlite not found at ${this.dbPath}`) @@ -77,6 +81,10 @@ class Database { return true } + /** + * Connect to db, build models and run migrations + * @param {boolean} [force=false] Used for testing, drops & re-creates all tables + */ async init(force = false) { this.dbPath = Path.join(global.ConfigPath, 'absdatabase.sqlite') @@ -93,6 +101,10 @@ class Database { await this.loadData() } + /** + * Connect to db + * @returns {boolean} + */ async connect() { Logger.info(`[Database] Initializing db at "${this.dbPath}"`) this.sequelize = new Sequelize({ @@ -115,12 +127,18 @@ class Database { } } + /** + * Disconnect from db + */ async disconnect() { Logger.info(`[Database] Disconnecting sqlite db`) await this.sequelize.close() this.sequelize = null } + /** + * Reconnect to db and init + */ async reconnect() { Logger.info(`[Database] Reconnecting sqlite db`) await this.init() @@ -576,6 +594,28 @@ class Database { } return this.libraryFilterData[libraryId].series.some(se => se.id === seriesId) } + + /** + * Reset numIssues for library + * @param {string} libraryId + */ + async resetLibraryIssuesFilterData(libraryId) { + if (!this.libraryFilterData[libraryId]) return // Do nothing if filter data is not set + + this.libraryFilterData[libraryId].numIssues = await this.libraryItemModel.count({ + where: { + libraryId, + [Sequelize.Op.or]: [ + { + isMissing: true + }, + { + isInvalid: true + } + ] + } + }) + } } module.exports = new Database() \ No newline at end of file diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js index f49f5539..df2afe9d 100644 --- a/server/controllers/LibraryController.js +++ b/server/controllers/LibraryController.js @@ -191,6 +191,8 @@ class LibraryController { return user.checkCanAccessLibrary && user.checkCanAccessLibrary(library.id) } SocketAuthority.emitter('library_updated', library.toJSON(), userFilter) + + await Database.resetLibraryIssuesFilterData(library.id) } return res.json(library.toJSON()) } @@ -249,6 +251,12 @@ class LibraryController { await Database.models.library.resetDisplayOrder() SocketAuthority.emitter('library_removed', libraryJson) + + // Remove library filter data + if (Database.libraryFilterData[library.id]) { + delete Database.libraryFilterData[library.id] + } + return res.json(libraryJson) } @@ -480,6 +488,7 @@ class LibraryController { async removeLibraryItemsWithIssues(req, res) { const libraryItemsWithIssues = await Database.models.libraryItem.findAll({ where: { + libraryId: req.library.id, [Sequelize.Op.or]: [ { isMissing: true @@ -519,6 +528,11 @@ class LibraryController { await this.handleDeleteLibraryItem(libraryItem.mediaType, libraryItem.id, mediaItemIds) } + // Set numIssues to 0 for library filter data + if (Database.libraryFilterData[req.library.id]) { + Database.libraryFilterData[req.library.id].numIssues = 0 + } + res.sendStatus(200) } @@ -963,6 +977,7 @@ class LibraryController { } res.sendStatus(200) await this.scanner.scan(req.library, options) + await Database.resetLibraryIssuesFilterData(req.library.id) Logger.info('[LibraryController] Scan complete') } @@ -1039,9 +1054,9 @@ class LibraryController { /** * Middleware that is not using libraryItems from memory - * @param {*} req - * @param {*} res - * @param {*} next + * @param {import('express').Request} req + * @param {import('express').Response} res + * @param {import('express').NextFunction} next */ async middlewareNew(req, res, next) { if (!req.user.checkCanAccessLibrary(req.params.id)) { diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js index d5fa20bc..64a5fd08 100644 --- a/server/controllers/LibraryItemController.js +++ b/server/controllers/LibraryItemController.js @@ -78,6 +78,7 @@ class LibraryItemController { Logger.error(`[LibraryItemController] Failed to delete library item from file system at "${libraryItemPath}"`, error) }) } + await Database.resetLibraryIssuesFilterData(req.libraryItem.libraryId) res.sendStatus(200) } @@ -332,6 +333,8 @@ class LibraryItemController { }) } } + + await Database.resetLibraryIssuesFilterData(req.libraryItem.libraryId) res.sendStatus(200) } @@ -456,9 +459,11 @@ class LibraryItemController { await this.scanner.scanLibraryItemByRequest(libraryItem) } } + + await Database.resetLibraryIssuesFilterData(req.libraryItem.libraryId) } - // POST: api/items/:id/scan (admin) + // POST: api/items/:id/scan async scan(req, res) { if (!req.user.isAdminOrUp) { Logger.error(`[LibraryItemController] Non-admin user attempted to scan library item`, req.user) @@ -471,6 +476,7 @@ class LibraryItemController { } const result = await this.scanner.scanLibraryItemByRequest(req.libraryItem) + await Database.resetLibraryIssuesFilterData(req.libraryItem.libraryId) res.json({ result: Object.keys(ScanResult).find(key => ScanResult[key] == result) }) diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js index 559cbcbd..c9059741 100644 --- a/server/scanner/Scanner.js +++ b/server/scanner/Scanner.js @@ -564,22 +564,27 @@ class Scanner { const library = await Database.models.library.getOldById(libraryId) if (!library) { Logger.error(`[Scanner] Library not found in files changed ${libraryId}`) - continue; + continue } const folder = library.getFolderById(folderId) if (!folder) { Logger.error(`[Scanner] Folder is not in library in files changed "${folderId}", Library "${library.name}"`) - continue; + continue } const relFilePaths = folderGroups[folderId].fileUpdates.map(fileUpdate => fileUpdate.relPath) const fileUpdateGroup = groupFilesIntoLibraryItemPaths(library.mediaType, relFilePaths, false) if (!Object.keys(fileUpdateGroup).length) { Logger.info(`[Scanner] No important changes to scan for in folder "${folderId}"`) - continue; + continue } const folderScanResults = await this.scanFolderUpdates(library, folder, fileUpdateGroup) Logger.debug(`[Scanner] Folder scan results`, folderScanResults) + + // If something was updated then reset numIssues filter data for library + if (Object.values(folderScanResults).some(scanResult => scanResult !== ScanResult.NOTHING && scanResult !== ScanResult.UPTODATE)) { + await Database.resetLibraryIssuesFilterData(libraryId) + } } this.scanningFilesChanged = false @@ -700,7 +705,7 @@ class Scanner { attributes: ['id', 'path'], where: { path: { - [Sequelize.Op.startsWith]: fullPath + [Sequelize.Op.startsWith]: fullPath + '/' } } })