audiobookshelf/server/scanner/LibraryScan.js

150 lines
3.9 KiB
JavaScript
Raw Normal View History

const Path = require('path')
2023-07-05 01:14:44 +02:00
const uuidv4 = require("uuid").v4
2022-07-06 02:53:01 +02:00
const fs = require('../libs/fsExtra')
2022-07-07 02:18:27 +02:00
const date = require('../libs/dateAndTime')
const Logger = require('../Logger')
const Library = require('../objects/Library')
const { LogLevel } = require('../utils/constants')
const { secondsToTimestamp, elapsedPretty } = require('../utils/index')
class LibraryScan {
constructor() {
this.id = null
2022-02-16 01:33:33 +01:00
this.type = null
/** @type {import('../objects/Library')} */
this.library = null
this.verbose = false
this.startedAt = null
this.finishedAt = null
this.elapsed = null
this.error = null
this.resultsMissing = 0
this.resultsAdded = 0
this.resultsUpdated = 0
2023-09-03 00:49:28 +02:00
/** @type {string[]} */
this.authorsRemovedFromBooks = []
/** @type {string[]} */
this.seriesRemovedFromBooks = []
this.logs = []
}
get libraryId() { return this.library.id }
get libraryName() { return this.library.name }
get libraryMediaType() { return this.library.mediaType }
get folders() { return this.library.folders }
get timestamp() {
return (new Date()).toISOString()
}
get resultStats() {
return `${this.resultsAdded} Added | ${this.resultsUpdated} Updated | ${this.resultsMissing} Missing`
}
get elapsedTimestamp() {
return secondsToTimestamp(this.elapsed / 1000)
}
get getScanEmitData() {
return {
id: this.libraryId,
2022-02-16 01:33:33 +01:00
type: this.type,
name: this.libraryName,
error: this.error,
results: {
added: this.resultsAdded,
updated: this.resultsUpdated,
missing: this.resultsMissing
}
}
}
get totalResults() {
return this.resultsAdded + this.resultsUpdated + this.resultsMissing
}
get logFilename() {
return date.format(new Date(), 'YYYY-MM-DD') + '_' + this.id + '.txt'
}
get scanResultsString() {
if (this.error) return this.error
const strs = []
if (this.resultsAdded) strs.push(`${this.resultsAdded} added`)
if (this.resultsUpdated) strs.push(`${this.resultsUpdated} updated`)
if (this.resultsMissing) strs.push(`${this.resultsMissing} missing`)
if (!strs.length) return `Everything was up to date (${elapsedPretty(this.elapsed / 1000)})`
return strs.join(', ') + ` (${elapsedPretty(this.elapsed / 1000)})`
}
toJSON() {
return {
id: this.id,
2022-02-16 01:33:33 +01:00
type: this.type,
library: this.library.toJSON(),
startedAt: this.startedAt,
finishedAt: this.finishedAt,
elapsed: this.elapsed,
error: this.error,
resultsAdded: this.resultsAdded,
resultsUpdated: this.resultsUpdated,
resultsMissing: this.resultsMissing
}
}
setData(library, type = 'scan') {
2023-07-05 01:14:44 +02:00
this.id = uuidv4()
2022-02-16 01:33:33 +01:00
this.type = type
this.library = new Library(library.toJSON()) // clone library
this.startedAt = Date.now()
}
/**
*
* @param {string} error
*/
setComplete(error = null) {
this.finishedAt = Date.now()
this.elapsed = this.finishedAt - this.startedAt
this.error = error
}
getLogLevelString(level) {
for (const key in LogLevel) {
if (LogLevel[key] === level) {
return key
}
}
return 'UNKNOWN'
}
addLog(level, ...args) {
const logObj = {
timestamp: this.timestamp,
message: args.join(' '),
levelName: this.getLogLevelString(level),
level
}
if (this.verbose) {
Logger.debug(`[LibraryScan] "${this.libraryName}":`, ...args)
}
this.logs.push(logObj)
}
async saveLog() {
await Logger.logManager.ensureScanLogDir()
2022-12-18 21:26:15 +01:00
const logDir = Path.join(global.MetadataPath, 'logs', 'scans')
const outputPath = Path.join(logDir, this.logFilename)
const logLines = [JSON.stringify(this.toJSON())]
this.logs.forEach(l => {
logLines.push(JSON.stringify(l))
})
await fs.writeFile(outputPath, logLines.join('\n') + '\n')
Logger.info(`[LibraryScan] Scan log saved "${outputPath}"`)
}
}
module.exports = LibraryScan