UNPKG

wranglebot

Version:

open source media asset management

212 lines (188 loc) 5.37 kB
import { finder } from "../system/index.js"; import { SearchLite } from "searchlite"; import ReturnObject from "../utility/SendBack.js"; import { Volume } from "./Volume.js"; import LogBot from "logbotjs"; import EventEmitter from "events"; import { FSWatcher } from "fs"; class DriveBot extends EventEmitter { /** * @wbType {Volume[]} */ drives: any = []; verbose; watchers = []; private watcher: FSWatcher | null = null; constructor() { super(); } /** * Starts listening to changes to mounted volumes * * @example * driveBot.watch(["mylib1, mylib2"]); * * @fires DriveBot#removed * @fires DriveBot#added * */ watch() { this.watcher = finder.watch(finder.pathToVolumes, (eventType, volumeName) => { if (eventType === "rename") { this.getDrive(volumeName).then((drive) => { if (drive) { const oldDrive = drive; this.drives.splice(this.drives.indexOf(drive), 1); LogBot.log(200, "Volume removed: " + volumeName); this.emit("removed", oldDrive); } else { this.scan() .then((allDrives) => { const search = SearchLite.find(allDrives, "label", volumeName); if (search.wasSuccess()) { this.drives.push(search.result); LogBot.log(200, "Volume added: " + volumeName); this.emit("added", search.result); } }) .catch((e) => { console.error(e); }); } }); } }); } hasWatcher() { return this.watcher !== null; } stopWatching() { if (this.watcher) { this.watcher.close(); this.watcher = null; } } /** * scans all mounted drives and returns an Array of Drives * @return {Promise<Volume[]>} */ async scan() { return new Promise((resolve) => { let newDrives: any = []; finder.getDisks().then(async (drives) => { for (let drive of drives) { const newDrive = new Volume(drive); newDrives.push(newDrive); } resolve(newDrives); }); }); } async updateDrives() { if (this.drives.length === 0) this.drives = await this.scan(); } async getDriveById(id) { await this.updateDrives(); return this.drives.find((drive) => drive.volumeId === id); } async eject(id) { return new Promise((resolve) => { this.getDriveById(id).then((vol) => { if (vol) { finder.eject(vol.mountpoint, (error) => { if (!error) { LogBot.log(200, "Ejected " + vol.label); resolve(true); } else { LogBot.log(500, "Error ejecting drive: " + error); resolve(false); } }); } }); }); } async ejectDevice(deviceName) { return new Promise((resolve) => { let search = SearchLite.find(this.drives, "label", deviceName); if (search.wasSuccess()) { if (search.result.status === "offline") { this.drives.splice(search.count, 1); resolve( new ReturnObject({ status: 200, message: deviceName + " was offline, so I removed it.", }) ); } else { finder.eject(search.result.mountpoint, (error) => { if (!error) { this.drives.splice(search.count, 1); resolve( new ReturnObject({ status: 200, message: "I have successfully ejected the drive " + deviceName, }) ); } else { resolve( new ReturnObject({ status: 500, message: "I was unable to eject the drive " + deviceName, }) ); } }); } } }); } async getDrive(driveName) { await this.updateDrives(); let search = SearchLite.find(this.drives, "label", driveName); if (search.wasSuccess()) { return search.result; } return false; } getDriveByMountpoint(mountpoint) { if (this.drives.length === 0) throw new Error("No drives found"); let search = SearchLite.find(this.drives, "mountpoint", mountpoint); if (search.wasSuccess()) { return search.result; } return false; } async getDriveBySerial(serialNumber) { await this.updateDrives(); let search = SearchLite.find(this.drives, "serialNumber", serialNumber); if (search.wasSuccess()) { return search.result; } return false; } async getDrives() { await this.updateDrives(); return this.drives; } async getMountPoint(mountpoint) { await this.updateDrives(); let search = SearchLite.find(this.drives, "mountpoint", mountpoint); if (search.wasSuccess()) { return search.result.mountpoint; } return ""; } async getCurrentVolumeName(serialNumber) { const driveToCheck = await this.getDriveBySerial(serialNumber); if (driveToCheck) { return driveToCheck.label; } return ""; } log(message, type) { LogBot.log(`DriveBot:${type}`, message, this.verbose); } } const driveBot = new DriveBot(); export { driveBot, DriveBot };