2021-09-07 03:14:04 +02:00
|
|
|
const Path = require('path')
|
|
|
|
const EventEmitter = require('events')
|
|
|
|
const Watcher = require('watcher')
|
|
|
|
const Logger = require('./Logger')
|
2021-08-18 00:01:11 +02:00
|
|
|
|
|
|
|
class FolderWatcher extends EventEmitter {
|
|
|
|
constructor(audiobookPath) {
|
|
|
|
super()
|
|
|
|
this.AudiobookPath = audiobookPath
|
|
|
|
this.folderMap = {}
|
|
|
|
this.watcher = null
|
2021-09-07 03:14:04 +02:00
|
|
|
|
2021-09-11 02:55:02 +02:00
|
|
|
this.pendingFiles = []
|
|
|
|
this.pendingDelay = 4000
|
|
|
|
this.pendingTimeout = null
|
2021-08-18 00:01:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
initWatcher() {
|
|
|
|
try {
|
2021-08-26 00:36:54 +02:00
|
|
|
Logger.info('[FolderWatcher] Initializing..')
|
|
|
|
this.watcher = new Watcher(this.AudiobookPath, {
|
2021-08-18 00:01:11 +02:00
|
|
|
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
2021-08-26 00:36:54 +02:00
|
|
|
renameDetection: true,
|
|
|
|
renameTimeout: 2000,
|
|
|
|
recursive: true,
|
|
|
|
ignoreInitial: true,
|
|
|
|
persistent: true
|
2021-08-18 00:01:11 +02:00
|
|
|
})
|
|
|
|
this.watcher
|
|
|
|
.on('add', (path) => {
|
|
|
|
this.onNewFile(path)
|
|
|
|
}).on('change', (path) => {
|
2021-09-05 01:02:42 +02:00
|
|
|
// This is triggered from metadata changes, not what we want
|
|
|
|
// this.onFileUpdated(path)
|
2021-08-18 00:01:11 +02:00
|
|
|
}).on('unlink', path => {
|
|
|
|
this.onFileRemoved(path)
|
2021-08-26 00:36:54 +02:00
|
|
|
}).on('rename', (path, pathNext) => {
|
|
|
|
this.onRename(path, pathNext)
|
2021-08-18 00:01:11 +02:00
|
|
|
}).on('error', (error) => {
|
2021-08-26 00:36:54 +02:00
|
|
|
Logger.error(`[FolderWatcher] ${error}`)
|
2021-08-18 00:01:11 +02:00
|
|
|
}).on('ready', () => {
|
2021-08-26 00:36:54 +02:00
|
|
|
Logger.info('[FolderWatcher] Ready')
|
2021-08-18 00:01:11 +02:00
|
|
|
})
|
|
|
|
} catch (error) {
|
|
|
|
Logger.error('Chokidar watcher failed', error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close() {
|
|
|
|
return this.watcher.close()
|
|
|
|
}
|
|
|
|
|
2021-09-07 03:14:04 +02:00
|
|
|
// After [pendingBatchDelay] seconds emit batch
|
|
|
|
async onNewFile(path) {
|
2021-09-11 02:55:02 +02:00
|
|
|
if (this.pendingFiles.includes(path)) return
|
|
|
|
|
2021-08-24 14:15:56 +02:00
|
|
|
Logger.debug('FolderWatcher: New File', path)
|
2021-09-07 03:14:04 +02:00
|
|
|
|
|
|
|
var dir = Path.dirname(path)
|
2021-09-11 02:55:02 +02:00
|
|
|
if (dir === this.AudiobookPath) {
|
|
|
|
Logger.debug('New File added to root dir, ignoring it')
|
|
|
|
return
|
2021-09-07 03:14:04 +02:00
|
|
|
}
|
|
|
|
|
2021-09-11 02:55:02 +02:00
|
|
|
this.pendingFiles.push(path)
|
|
|
|
clearTimeout(this.pendingTimeout)
|
|
|
|
this.pendingTimeout = setTimeout(() => {
|
|
|
|
this.emit('files', this.pendingFiles.map(f => f))
|
|
|
|
this.pendingFiles = []
|
|
|
|
}, this.pendingDelay)
|
2021-08-18 00:01:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
onFileRemoved(path) {
|
2021-08-26 00:36:54 +02:00
|
|
|
Logger.debug('[FolderWatcher] File Removed', path)
|
2021-09-07 03:14:04 +02:00
|
|
|
|
|
|
|
var dir = Path.dirname(path)
|
2021-09-11 02:55:02 +02:00
|
|
|
if (dir === this.AudiobookPath) {
|
|
|
|
Logger.debug('New File added to root dir, ignoring it')
|
|
|
|
return
|
2021-09-07 03:14:04 +02:00
|
|
|
}
|
|
|
|
|
2021-09-11 02:55:02 +02:00
|
|
|
this.pendingFiles.push(path)
|
|
|
|
clearTimeout(this.pendingTimeout)
|
|
|
|
this.pendingTimeout = setTimeout(() => {
|
|
|
|
this.emit('files', this.pendingFiles.map(f => f))
|
|
|
|
this.pendingFiles = []
|
|
|
|
}, this.pendingDelay)
|
2021-08-18 00:01:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
onFileUpdated(path) {
|
2021-08-26 00:36:54 +02:00
|
|
|
Logger.debug('[FolderWatcher] Updated File', path)
|
2021-08-18 00:01:11 +02:00
|
|
|
}
|
2021-08-26 00:36:54 +02:00
|
|
|
|
|
|
|
onRename(pathFrom, pathTo) {
|
|
|
|
Logger.debug(`[FolderWatcher] Rename ${pathFrom} => ${pathTo}`)
|
2021-09-07 03:14:04 +02:00
|
|
|
|
|
|
|
var dir = Path.dirname(pathTo)
|
2021-09-11 02:55:02 +02:00
|
|
|
if (dir === this.AudiobookPath) {
|
|
|
|
Logger.debug('New File added to root dir, ignoring it')
|
|
|
|
return
|
2021-09-07 03:14:04 +02:00
|
|
|
}
|
|
|
|
|
2021-09-11 02:55:02 +02:00
|
|
|
this.pendingFiles.push(pathTo)
|
|
|
|
clearTimeout(this.pendingTimeout)
|
|
|
|
this.pendingTimeout = setTimeout(() => {
|
|
|
|
this.emit('files', this.pendingFiles.map(f => f))
|
|
|
|
this.pendingFiles = []
|
|
|
|
}, this.pendingDelay)
|
2021-08-26 00:36:54 +02:00
|
|
|
}
|
2021-08-18 00:01:11 +02:00
|
|
|
}
|
|
|
|
module.exports = FolderWatcher
|