Add:Schedule periodic library scans #655

This commit is contained in:
advplyr 2022-08-17 18:44:21 -05:00
parent 0c20988e18
commit 2304f37cbe
10 changed files with 112 additions and 20 deletions

View file

@ -32,6 +32,7 @@ const PlaybackSessionManager = require('./managers/PlaybackSessionManager')
const PodcastManager = require('./managers/PodcastManager')
const AudioMetadataMangaer = require('./managers/AudioMetadataManager')
const RssFeedManager = require('./managers/RssFeedManager')
const CronManager = require('./managers/CronManager')
class Server {
constructor(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH) {
@ -74,9 +75,10 @@ class Server {
this.rssFeedManager = new RssFeedManager(this.db, this.emitter.bind(this))
this.scanner = new Scanner(this.db, this.coverManager, this.emitter.bind(this))
this.cronManager = new CronManager(this.db, this.scanner)
// Routers
this.apiRouter = new ApiRouter(this.db, this.auth, this.scanner, this.playbackSessionManager, this.abMergeManager, this.coverManager, this.backupManager, this.watcher, this.cacheManager, this.podcastManager, this.audioMetadataManager, this.rssFeedManager, this.emitter.bind(this), this.clientEmitter.bind(this))
this.apiRouter = new ApiRouter(this.db, this.auth, this.scanner, this.playbackSessionManager, this.abMergeManager, this.coverManager, this.backupManager, this.watcher, this.cacheManager, this.podcastManager, this.audioMetadataManager, this.rssFeedManager, this.cronManager, this.emitter.bind(this), this.clientEmitter.bind(this))
this.hlsRouter = new HlsRouter(this.db, this.auth, this.playbackSessionManager, this.emitter.bind(this))
this.staticRouter = new StaticRouter(this.db)
@ -151,6 +153,7 @@ class Server {
await this.logManager.init()
await this.rssFeedManager.init()
this.podcastManager.init()
this.cronManager.init()
if (this.db.serverSettings.scannerDisableWatcher) {
Logger.info(`[Server] Watcher is disabled`)

View file

@ -108,6 +108,9 @@ class LibraryController {
// Update watcher
this.watcher.updateLibrary(library)
// Update auto scan cron
this.cronManager.updateLibraryScanCron(library)
// Remove libraryItems no longer in library
var itemsToRemove = this.db.libraryItems.filter(li => li.libraryId === library.id && !library.checkFullPathInLibrary(li.path))
if (itemsToRemove.length) {

View file

@ -3,14 +3,14 @@
const EventEmitter = require('events');
const TimeMatcher = require('./time-matcher');
class Scheduler extends EventEmitter{
constructor(pattern, timezone, autorecover){
class Scheduler extends EventEmitter {
constructor(pattern, timezone, autorecover) {
super();
this.timeMatcher = new TimeMatcher(pattern, timezone);
this.autorecover = autorecover;
}
start(){
start() {
// clear timeout if exists
this.stop();
@ -22,11 +22,11 @@ class Scheduler extends EventEmitter{
const elapsedTime = process.hrtime(lastCheck);
const elapsedMs = (elapsedTime[0] * 1e9 + elapsedTime[1]) / 1e6;
const missedExecutions = Math.floor(elapsedMs / 1000);
for(let i = missedExecutions; i >= 0; i--){
for (let i = missedExecutions; i >= 0; i--) {
const date = new Date(new Date().getTime() - i * 1000);
let date_tmp = this.timeMatcher.apply(date);
if(lastExecution.getTime() < date_tmp.getTime() && (i === 0 || this.autorecover) && this.timeMatcher.match(date)){
if (lastExecution.getTime() < date_tmp.getTime() && (i === 0 || this.autorecover) && this.timeMatcher.match(date)) {
this.emit('scheduled-time-matched', date_tmp);
date_tmp.setMilliseconds(0);
lastExecution = date_tmp;
@ -38,8 +38,8 @@ class Scheduler extends EventEmitter{
matchTime();
}
stop(){
if(this.timeout){
stop() {
if (this.timeout) {
clearTimeout(this.timeout);
}
this.timeout = null;

View file

@ -56,14 +56,14 @@ class BackupManager {
updateCronSchedule() {
if (this.scheduleTask && !this.serverSettings.backupSchedule) {
Logger.info(`[BackupManager] Disabling backup schedule`)
if (this.scheduleTask.destroy) this.scheduleTask.destroy()
if (this.scheduleTask.stop) this.scheduleTask.stop()
this.scheduleTask = null
} else if (!this.scheduleTask && this.serverSettings.backupSchedule) {
Logger.info(`[BackupManager] Starting backup schedule ${this.serverSettings.backupSchedule}`)
this.scheduleCron()
} else if (this.serverSettings.backupSchedule) {
Logger.info(`[BackupManager] Restarting backup schedule ${this.serverSettings.backupSchedule}`)
if (this.scheduleTask.destroy) this.scheduleTask.destroy()
if (this.scheduleTask.stop) this.scheduleTask.stop()
this.scheduleCron()
}
}

View file

@ -0,0 +1,61 @@
const cron = require('../libs/nodeCron')
const Logger = require('../Logger')
class CronManager {
constructor(db, scanner) {
this.db = db
this.scanner = scanner
this.libraryScanCrons = []
}
init() {
this.initLibraryScanCrons()
}
initLibraryScanCrons() {
for (const library of this.db.libraries) {
if (library.settings.autoScanCronExpression) {
this.startCronForLibrary(library)
}
}
}
startCronForLibrary(library) {
Logger.debug(`[CronManager] Init library scan cron for ${library.name} on schedule ${library.settings.autoScanCronExpression}`)
const libScanCron = cron.schedule(library.settings.autoScanCronExpression, () => {
Logger.debug(`[CronManager] Library scan cron executing for ${library.name}`)
this.scanner.scan(library)
})
this.libraryScanCrons.push({
libraryId: library.id,
expression: library.settings.autoScanCronExpression,
task: libScanCron
})
}
removeCronForLibrary(library) {
Logger.debug(`[CronManager] Removing library scan cron for ${library.name}`)
this.libraryScanCrons = this.libraryScanCrons.filter(lsc => lsc.libraryId !== library.id)
}
updateLibraryScanCron(library) {
const expression = library.settings.autoScanCronExpression
const existingCron = this.libraryScanCrons.find(lsc => lsc.libraryId === library.id)
if (!expression && existingCron) {
if (existingCron.task.stop) existingCron.task.stop()
this.removeCronForLibrary(library)
} else if (!existingCron && expression) {
this.startCronForLibrary(library)
} else if (existingCron && existingCron.expression !== expression) {
if (existingCron.task.stop) existingCron.task.stop()
this.removeCronForLibrary(library)
this.startCronForLibrary(library)
}
}
}
module.exports = CronManager

View file

@ -25,7 +25,7 @@ const Series = require('../objects/entities/Series')
const FileSystemController = require('../controllers/FileSystemController')
class ApiRouter {
constructor(db, auth, scanner, playbackSessionManager, abMergeManager, coverManager, backupManager, watcher, cacheManager, podcastManager, audioMetadataManager, rssFeedManager, emitter, clientEmitter) {
constructor(db, auth, scanner, playbackSessionManager, abMergeManager, coverManager, backupManager, watcher, cacheManager, podcastManager, audioMetadataManager, rssFeedManager, cronManager, emitter, clientEmitter) {
this.db = db
this.auth = auth
this.scanner = scanner
@ -38,6 +38,7 @@ class ApiRouter {
this.podcastManager = podcastManager
this.audioMetadataManager = audioMetadataManager
this.rssFeedManager = rssFeedManager
this.cronManager = cronManager
this.emitter = emitter
this.clientEmitter = clientEmitter