1
0
mirror of https://github.com/advplyr/audiobookshelf.git synced 2025-04-02 01:16:54 +02:00

Update numIssues on filter data, fix watcher scanning in new items

This commit is contained in:
advplyr 2023-08-20 13:16:53 -05:00
parent 4f94deefa0
commit 21343ffbd1
4 changed files with 74 additions and 8 deletions

View File

@ -69,6 +69,10 @@ class Database {
return this.models.mediaProgress return this.models.mediaProgress
} }
/**
* Check if db file exists
* @returns {boolean}
*/
async checkHasDb() { async checkHasDb() {
if (!await fs.pathExists(this.dbPath)) { if (!await fs.pathExists(this.dbPath)) {
Logger.info(`[Database] absdatabase.sqlite not found at ${this.dbPath}`) Logger.info(`[Database] absdatabase.sqlite not found at ${this.dbPath}`)
@ -77,6 +81,10 @@ class Database {
return true 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) { async init(force = false) {
this.dbPath = Path.join(global.ConfigPath, 'absdatabase.sqlite') this.dbPath = Path.join(global.ConfigPath, 'absdatabase.sqlite')
@ -93,6 +101,10 @@ class Database {
await this.loadData() await this.loadData()
} }
/**
* Connect to db
* @returns {boolean}
*/
async connect() { async connect() {
Logger.info(`[Database] Initializing db at "${this.dbPath}"`) Logger.info(`[Database] Initializing db at "${this.dbPath}"`)
this.sequelize = new Sequelize({ this.sequelize = new Sequelize({
@ -115,12 +127,18 @@ class Database {
} }
} }
/**
* Disconnect from db
*/
async disconnect() { async disconnect() {
Logger.info(`[Database] Disconnecting sqlite db`) Logger.info(`[Database] Disconnecting sqlite db`)
await this.sequelize.close() await this.sequelize.close()
this.sequelize = null this.sequelize = null
} }
/**
* Reconnect to db and init
*/
async reconnect() { async reconnect() {
Logger.info(`[Database] Reconnecting sqlite db`) Logger.info(`[Database] Reconnecting sqlite db`)
await this.init() await this.init()
@ -576,6 +594,28 @@ class Database {
} }
return this.libraryFilterData[libraryId].series.some(se => se.id === seriesId) 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() module.exports = new Database()

View File

@ -191,6 +191,8 @@ class LibraryController {
return user.checkCanAccessLibrary && user.checkCanAccessLibrary(library.id) return user.checkCanAccessLibrary && user.checkCanAccessLibrary(library.id)
} }
SocketAuthority.emitter('library_updated', library.toJSON(), userFilter) SocketAuthority.emitter('library_updated', library.toJSON(), userFilter)
await Database.resetLibraryIssuesFilterData(library.id)
} }
return res.json(library.toJSON()) return res.json(library.toJSON())
} }
@ -249,6 +251,12 @@ class LibraryController {
await Database.models.library.resetDisplayOrder() await Database.models.library.resetDisplayOrder()
SocketAuthority.emitter('library_removed', libraryJson) SocketAuthority.emitter('library_removed', libraryJson)
// Remove library filter data
if (Database.libraryFilterData[library.id]) {
delete Database.libraryFilterData[library.id]
}
return res.json(libraryJson) return res.json(libraryJson)
} }
@ -480,6 +488,7 @@ class LibraryController {
async removeLibraryItemsWithIssues(req, res) { async removeLibraryItemsWithIssues(req, res) {
const libraryItemsWithIssues = await Database.models.libraryItem.findAll({ const libraryItemsWithIssues = await Database.models.libraryItem.findAll({
where: { where: {
libraryId: req.library.id,
[Sequelize.Op.or]: [ [Sequelize.Op.or]: [
{ {
isMissing: true isMissing: true
@ -519,6 +528,11 @@ class LibraryController {
await this.handleDeleteLibraryItem(libraryItem.mediaType, libraryItem.id, mediaItemIds) 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) res.sendStatus(200)
} }
@ -963,6 +977,7 @@ class LibraryController {
} }
res.sendStatus(200) res.sendStatus(200)
await this.scanner.scan(req.library, options) await this.scanner.scan(req.library, options)
await Database.resetLibraryIssuesFilterData(req.library.id)
Logger.info('[LibraryController] Scan complete') Logger.info('[LibraryController] Scan complete')
} }
@ -1039,9 +1054,9 @@ class LibraryController {
/** /**
* Middleware that is not using libraryItems from memory * Middleware that is not using libraryItems from memory
* @param {*} req * @param {import('express').Request} req
* @param {*} res * @param {import('express').Response} res
* @param {*} next * @param {import('express').NextFunction} next
*/ */
async middlewareNew(req, res, next) { async middlewareNew(req, res, next) {
if (!req.user.checkCanAccessLibrary(req.params.id)) { if (!req.user.checkCanAccessLibrary(req.params.id)) {

View File

@ -78,6 +78,7 @@ class LibraryItemController {
Logger.error(`[LibraryItemController] Failed to delete library item from file system at "${libraryItemPath}"`, error) Logger.error(`[LibraryItemController] Failed to delete library item from file system at "${libraryItemPath}"`, error)
}) })
} }
await Database.resetLibraryIssuesFilterData(req.libraryItem.libraryId)
res.sendStatus(200) res.sendStatus(200)
} }
@ -332,6 +333,8 @@ class LibraryItemController {
}) })
} }
} }
await Database.resetLibraryIssuesFilterData(req.libraryItem.libraryId)
res.sendStatus(200) res.sendStatus(200)
} }
@ -456,9 +459,11 @@ class LibraryItemController {
await this.scanner.scanLibraryItemByRequest(libraryItem) 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) { async scan(req, res) {
if (!req.user.isAdminOrUp) { if (!req.user.isAdminOrUp) {
Logger.error(`[LibraryItemController] Non-admin user attempted to scan library item`, req.user) 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) const result = await this.scanner.scanLibraryItemByRequest(req.libraryItem)
await Database.resetLibraryIssuesFilterData(req.libraryItem.libraryId)
res.json({ res.json({
result: Object.keys(ScanResult).find(key => ScanResult[key] == result) result: Object.keys(ScanResult).find(key => ScanResult[key] == result)
}) })

View File

@ -564,22 +564,27 @@ class Scanner {
const library = await Database.models.library.getOldById(libraryId) const library = await Database.models.library.getOldById(libraryId)
if (!library) { if (!library) {
Logger.error(`[Scanner] Library not found in files changed ${libraryId}`) Logger.error(`[Scanner] Library not found in files changed ${libraryId}`)
continue; continue
} }
const folder = library.getFolderById(folderId) const folder = library.getFolderById(folderId)
if (!folder) { if (!folder) {
Logger.error(`[Scanner] Folder is not in library in files changed "${folderId}", Library "${library.name}"`) 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 relFilePaths = folderGroups[folderId].fileUpdates.map(fileUpdate => fileUpdate.relPath)
const fileUpdateGroup = groupFilesIntoLibraryItemPaths(library.mediaType, relFilePaths, false) const fileUpdateGroup = groupFilesIntoLibraryItemPaths(library.mediaType, relFilePaths, false)
if (!Object.keys(fileUpdateGroup).length) { if (!Object.keys(fileUpdateGroup).length) {
Logger.info(`[Scanner] No important changes to scan for in folder "${folderId}"`) Logger.info(`[Scanner] No important changes to scan for in folder "${folderId}"`)
continue; continue
} }
const folderScanResults = await this.scanFolderUpdates(library, folder, fileUpdateGroup) const folderScanResults = await this.scanFolderUpdates(library, folder, fileUpdateGroup)
Logger.debug(`[Scanner] Folder scan results`, folderScanResults) 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 this.scanningFilesChanged = false
@ -700,7 +705,7 @@ class Scanner {
attributes: ['id', 'path'], attributes: ['id', 'path'],
where: { where: {
path: { path: {
[Sequelize.Op.startsWith]: fullPath [Sequelize.Op.startsWith]: fullPath + '/'
} }
} }
}) })