const Constants = require('../../constants'); const fs = require('fs'); const helpers = require('../../helpers'); const os = require('os'); const path = require('path'); let expectedUnmount = {}; let firstMountCheck = true; let manualMountDetection = {}; let mountedData = {}; let mountedLocations = []; const clearManualMountDetection = provider => { if (manualMountDetection[provider]) { clearInterval(manualMountDetection[provider]); delete manualMountDetection[provider]; } }; const monitorMount = (sender, provider, providerList, version, pid, location) => { manualMountDetection[provider] = setInterval(() => { helpers .detectRepertoryMounts(version, providerList) .then(result => { if (result[provider].PID !== pid) { if (result[provider].PID === -1) { clearManualMountDetection(provider); sender.send(Constants.IPC_Unmount_Drive_Reply, { data: { Expected: expectedUnmount[provider], Location: location, Provider: provider, Error: Error(provider + ' Unmounted').toString(), Success: false, } }); } else { pid = result[provider].PID; } } }) .catch(e => { console.log(e); }); },6000); }; const unmountAllDrives = () => { // Reset mount states for (const provider of Object.keys(manualMountDetection)) { clearManualMountDetection(provider); expectedUnmount[provider] = true; } // Unmount all items for (const i in mountedLocations) { const data = mountedData[mountedLocations[i]]; helpers.stopMountProcessSync(data.Version, data.Provider, data.Remote); } mountedLocations = []; mountedData = {}; }; const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { ipcMain.on(Constants.IPC_Check_Mount_Location + '_sync', (event, data) => { let response = { Success: true, Error: '' }; try { if (fs.existsSync(data.Location) && fs.statSync(data.Location).isDirectory()) { if (fs.readdirSync(data.Location).length !== 0) { response.Success = false; response.Error = 'Directory not empty: ' + data.Location; } } else { response.Success = false; response.Error = 'Directory not found: ' + data.Location; } } catch (e) { response.Success = false; response.Error = e.toString(); } event.returnValue = response; }); ipcMain.on(Constants.IPC_Detect_Mount, (event, data) => { const provider = data.Provider; let driveLetters = {}; const providerList = [ ...Constants.PROVIDER_LIST, ...data.RemoteMounts, ]; for (const provider of providerList) { driveLetters[provider] = []; } const grabDriveLetters = (locations) => { for (let i = 'c'.charCodeAt(0); i <= 'z'.charCodeAt(0); i++) { const drive = (String.fromCharCode(i) + ':').toUpperCase(); let driveInUse; if (Object.keys(locations).length > 0) { for (const provider of providerList) { driveInUse = locations[provider].startsWith(drive); if (driveInUse) break; } } if (!driveInUse) { try { if (!fs.existsSync(drive)) { for (const provider of providerList) { driveLetters[provider].push(drive); } } } catch (e) { } } } if (Object.keys(locations).length > 0) { for (const provider of providerList) { if (locations[provider].length > 0) { if (!driveLetters[provider].find((driveLetter) => { return driveLetter === locations[provider]; })) { driveLetters[provider].push(locations[provider]); } } } } }; const setImage = (locations) => { let driveInUse; if (Object.keys(locations).length > 0) { for (const provider of providerList) { driveInUse = locations[provider].length > 0; if (driveInUse) break; } } setTrayImage(driveInUse) }; helpers .detectRepertoryMounts(data.Version, providerList) .then((results) => { let storageData = {}; let locations = {}; for (const provider of providerList) { storageData[provider] = results[provider] ? results[provider] : { Active: false, Location: '', PID: -1, }; locations[provider] = storageData[provider].Location; if (storageData[provider].PID !== -1) { expectedUnmount[provider] = false; if (firstMountCheck) { monitorMount(event.sender, provider, providerList, data.Version, storageData[provider].PID, storageData[provider].Location); } } } if (os.platform() === 'win32') { grabDriveLetters(locations); } setImage(locations); if (firstMountCheck) { firstMountCheck = false; } standardIPCReply(event, Constants.IPC_Detect_Mount_Reply, { Active: storageData[provider].Active, DriveLetters: driveLetters[provider], Location: locations[provider], PID: storageData[provider].PID, Provider: provider, }); }) .catch(error => { if (os.platform() === 'win32') { grabDriveLetters({}); } setImage({}); standardIPCReply(event, Constants.IPC_Detect_Mount_Reply, { DriveLetters: driveLetters[provider], Provider: provider, }, error); }); }); ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { expectedUnmount[data.Provider] = false; if (mountedLocations.indexOf(data.Location) !== -1) { console.log(data.Provider + ' already mounted: ' + data.Location); } else { mountedLocations.push(data.Location); mountedData[data.Location] = { Provider: data.Provider, Remote: data.Remote, Version: data.Version, }; const errorHandler = (pid, error) => { if (mountedLocations.indexOf(data.Location) !== -1) { mountedLocations.splice(mountedLocations.indexOf(data.Location), 1); delete mountedData[data.Location]; } standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, { Expected: expectedUnmount[data.Provider], Location: data.Location, Provider: data.Provider, Remote: data.Remote, }, error || Error(data.Provider + ' Unmounted')); }; helpers .executeMount(data.Version, data.Provider, data.Remote, data.Location, (error, pid) => { errorHandler(pid, error); }) .then(() => { standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, { Provider: data.Provider, Remote: data.Remote, }); }) .catch(error => { errorHandler(-1, error); }); } }); ipcMain.on(Constants.IPC_Remove_Remote_Mount, (event, data) => { data = data.replace(':', '_'); const dataDirectory = path.resolve(path.join(helpers.getDataDirectory(), '..', 'remote', data)); try { helpers.removeDirectoryRecursively(dataDirectory); standardIPCReply(event, Constants.IPC_Remove_Remote_Mount_Reply, {DataDirectory: dataDirectory}); } catch (e) { standardIPCReply(event, Constants.IPC_Remove_Remote_Mount_Reply, {DataDirectory: dataDirectory}, e); } }); ipcMain.on(Constants.IPC_Unmount_All_Drives, (event, data) => { unmountAllDrives(); standardIPCReply(event, Constants.IPC_Unmount_All_Drives_Reply); }); ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { clearManualMountDetection(data.Provider); expectedUnmount[data.Provider] = true; helpers .stopMountProcess(data.Version, data.Provider, data.Remote) .then(result => { console.log(result); }) .catch(e => { console.log(e); }); }); }; module.exports = { addListeners, unmountAllDrives };