UNPKG

drive-watch

Version:

Watch for drive mount/eject events in OS X

135 lines (107 loc) 3.79 kB
// -------------------- // drive-watch module // -------------------- // modules var fs = require('fs-extra-promise'), _ = require('lodash'); // exports // create drivesPath var platform = process.platform; var drivesPath = (function() { if (platform == 'darwin') return '/Volumes'; if (platform == 'linux') return '/media/' + process.env.USER; throw new Error("Platform '" + platform + "' not supported"); })(); var DriveWatch = module.exports = function(eventHandler, options) { if (eventHandler && typeof eventHandler == 'object') { options = eventHandler; eventHandler = options.handler; } else { if (!options) options = {}; if (!eventHandler) eventHandler = options.handler; } delete options.handler; if (options.scanInterval === undefined) options.scanInterval = 10000; // 10 seconds this.options = options; this.eventHandler = eventHandler; return this; }; DriveWatch.prototype.start = function() { var self = this; // start watching var reading, newEvents; this.watcher = fs.watch(drivesPath, function(event, name) { // jshint ignore:line if (reading) { newEvents = true; return; } var foundIndex = self.drives.indexOf(name); if (foundIndex != -1) { // drive ejected self.drives.splice(foundIndex, 1); if (self.eventHandler) self.eventHandler('eject', name); return; } // drive mounted self.drives.push(name); if (self.eventHandler) self.eventHandler('mount', name); }); // get drives currently connected return getDrives(); // get drives initially connected function getDrives() { return getDrivesNow().then(function(drives) { // if new drive events during scan, redo scan if (newEvents) return getDrives(); recordDrives(drives); if (self.options.scanInterval) self.scanTimer = setTimeout(updateDrives, self.options.scanInterval); // return drives array, cloned so not altered by future events return self.drives.slice(0); }); } // periodic scan for drives mounted/ejected function updateDrives() { delete self.scanTimer; var oldDrives = self.drives; return getDrivesNow().then(function(drives) { // if new drive events during scan, redo scan if (newEvents) return updateDrives(); recordDrives(drives); if (self.eventHandler) { // find drives ejected _.difference(oldDrives, drives).forEach(function(name) { self.eventHandler('eject', name); }); // find drives mounted _.difference(drives, oldDrives).forEach(function(name) { self.eventHandler('mount', name); }); } // schedule to run again self.scanTimer = setTimeout(updateDrives, self.options.scanInterval); }); } // scan for connected drives function getDrivesNow() { reading = true; newEvents = false; return fs.readdirAsync(drivesPath) .then(function(files) { var drives = files.filter(function(name) { return name != '.DS_Store'; }); return drives; }); } // save drives array to this.drives function recordDrives(drives) { self.drives = drives; reading = false; } }; DriveWatch.prototype.stop = function() { if (this.watcher) this.watcher.close(); delete this.watcher; if (this.scanTimer) clearTimeout(this.scanTimer); delete this.scanTimer; };