mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-03 19:07:00 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			111 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const Path = require('path')
 | 
						|
const EventEmitter = require('events')
 | 
						|
const Watcher = require('watcher')
 | 
						|
const Logger = require('./Logger')
 | 
						|
 | 
						|
class FolderWatcher extends EventEmitter {
 | 
						|
  constructor(audiobookPath) {
 | 
						|
    super()
 | 
						|
    this.AudiobookPath = audiobookPath
 | 
						|
    this.folderMap = {}
 | 
						|
    this.watcher = null
 | 
						|
 | 
						|
    this.pendingFiles = []
 | 
						|
    this.pendingDelay = 4000
 | 
						|
    this.pendingTimeout = null
 | 
						|
  }
 | 
						|
 | 
						|
  initWatcher() {
 | 
						|
    try {
 | 
						|
      Logger.info('[FolderWatcher] Initializing..')
 | 
						|
      this.watcher = new Watcher(this.AudiobookPath, {
 | 
						|
        ignored: /(^|[\/\\])\../, // ignore dotfiles
 | 
						|
        renameDetection: true,
 | 
						|
        renameTimeout: 2000,
 | 
						|
        recursive: true,
 | 
						|
        ignoreInitial: true,
 | 
						|
        persistent: true
 | 
						|
      })
 | 
						|
      this.watcher
 | 
						|
        .on('add', (path) => {
 | 
						|
          this.onNewFile(path)
 | 
						|
        }).on('change', (path) => {
 | 
						|
          // This is triggered from metadata changes, not what we want
 | 
						|
          // this.onFileUpdated(path)
 | 
						|
        }).on('unlink', path => {
 | 
						|
          this.onFileRemoved(path)
 | 
						|
        }).on('rename', (path, pathNext) => {
 | 
						|
          this.onRename(path, pathNext)
 | 
						|
        }).on('error', (error) => {
 | 
						|
          Logger.error(`[FolderWatcher] ${error}`)
 | 
						|
        }).on('ready', () => {
 | 
						|
          Logger.info('[FolderWatcher] Ready')
 | 
						|
        })
 | 
						|
    } catch (error) {
 | 
						|
      Logger.error('Chokidar watcher failed', error)
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  close() {
 | 
						|
    return this.watcher.close()
 | 
						|
  }
 | 
						|
 | 
						|
  // After [pendingBatchDelay] seconds emit batch
 | 
						|
  async onNewFile(path) {
 | 
						|
    if (this.pendingFiles.includes(path)) return
 | 
						|
 | 
						|
    Logger.debug('FolderWatcher: New File', path)
 | 
						|
 | 
						|
    var dir = Path.dirname(path)
 | 
						|
    if (dir === this.AudiobookPath) {
 | 
						|
      Logger.debug('New File added to root dir, ignoring it')
 | 
						|
      return
 | 
						|
    }
 | 
						|
 | 
						|
    this.pendingFiles.push(path)
 | 
						|
    clearTimeout(this.pendingTimeout)
 | 
						|
    this.pendingTimeout = setTimeout(() => {
 | 
						|
      this.emit('files', this.pendingFiles.map(f => f))
 | 
						|
      this.pendingFiles = []
 | 
						|
    }, this.pendingDelay)
 | 
						|
  }
 | 
						|
 | 
						|
  onFileRemoved(path) {
 | 
						|
    Logger.debug('[FolderWatcher] File Removed', path)
 | 
						|
 | 
						|
    var dir = Path.dirname(path)
 | 
						|
    if (dir === this.AudiobookPath) {
 | 
						|
      Logger.debug('New File added to root dir, ignoring it')
 | 
						|
      return
 | 
						|
    }
 | 
						|
 | 
						|
    this.pendingFiles.push(path)
 | 
						|
    clearTimeout(this.pendingTimeout)
 | 
						|
    this.pendingTimeout = setTimeout(() => {
 | 
						|
      this.emit('files', this.pendingFiles.map(f => f))
 | 
						|
      this.pendingFiles = []
 | 
						|
    }, this.pendingDelay)
 | 
						|
  }
 | 
						|
 | 
						|
  onFileUpdated(path) {
 | 
						|
    Logger.debug('[FolderWatcher] Updated File', path)
 | 
						|
  }
 | 
						|
 | 
						|
  onRename(pathFrom, pathTo) {
 | 
						|
    Logger.debug(`[FolderWatcher] Rename ${pathFrom} => ${pathTo}`)
 | 
						|
 | 
						|
    var dir = Path.dirname(pathTo)
 | 
						|
    if (dir === this.AudiobookPath) {
 | 
						|
      Logger.debug('New File added to root dir, ignoring it')
 | 
						|
      return
 | 
						|
    }
 | 
						|
 | 
						|
    this.pendingFiles.push(pathTo)
 | 
						|
    clearTimeout(this.pendingTimeout)
 | 
						|
    this.pendingTimeout = setTimeout(() => {
 | 
						|
      this.emit('files', this.pendingFiles.map(f => f))
 | 
						|
      this.pendingFiles = []
 | 
						|
    }, this.pendingDelay)
 | 
						|
  }
 | 
						|
}
 | 
						|
module.exports = FolderWatcher |