const { app, BrowserWindow, ipcMain, shell, systemPreferences } = require('electron'); const axios = require('axios'); const fs = require('fs'); //const http = require('http'); const os = require('os'); const path = require('path'); const process = require('process'); //const request = require('request'); //const url = require('url'); // const usb = require('usb') // Compiled with an old version of Node.js console.log(os.type()); console.log(process.getSystemVersion()); if (os.type == 'Darwin') { if (systemPreferences.getMediaAccessStatus('microphone') != 'granted') { systemPreferences.askForMediaAccess('microphone'); } else { console.log(systemPreferences.getMediaAccessStatus('microphone')); } if (systemPreferences.getMediaAccessStatus('camera') != 'granted') { systemPreferences.askForMediaAccess('camera'); } else { console.log(systemPreferences.getMediaAccessStatus('camera')); } } function createWindow () { // Create the browser window. win = new BrowserWindow({ width: 1500, // 1500 1280 height: 1024, // 1024 backgroundColor: '#fff', icon: './app/img/favicon.ico', webPreferences: { contextIsolation: false, nodeIntegration: true, nodeIntegrationInWorker: true } }) win.setMinimumSize(1024, 768); //win.setFullScreenable(false) win.FullScreenable = false; // and load the index.html of the app. win.loadFile('app/index.html'); // Open the DevTools. win.webContents.openDevTools(); // Emitted when the window is closed. win.on('closed', () => { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. win = null; }) win.on('minimize', () => { //win.restore(); }) } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', createWindow); // Quit when all windows are closed. app.on('window-all-closed', () => { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { app.quit(); } }) app.on('activate', () => { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open.location_files if (win === null) { createWindow(); } }) // ipcMain.on('download_file', (event, api_base_url, api_endpoint, api_temporary_token, save_path) => { ipcMain.on('download_file', async (event, api_base_url, api_endpoint, save_path) => { console.log('*** call IPC download_file() ***'); // console.log('ipcMain on download_file: api_base_url='+api_base_url+' | api_temporary_token='+api_temporary_token); console.log('ipcMain on download_file: api_base_url='+api_base_url); // console.log(api_temporary_token); console.log('ipcMain download and save file: HTTP '+api_endpoint+' -> FILE '+save_path); let result = await download_file(api_base_url, api_endpoint, save_path); event.sender.send('download_file_reply', result); // axios.defaults.baseURL = api_base_url; // axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*'; // app_config.access_control_allow_origin; // axios.defaults.headers.common['content-type'] = 'application/json'; // axios.defaults.headers.common['x-aether-api-key'] = 'dFP6J9DVj9hUgIMn-fNIqg'; // api_secret_key; // axios.defaults.headers.common['x-account-id'] = '_XY7DXtc9MY'; // account_id; // const url = api_endpoint; // const writer = fs.createWriteStream(save_path); // await axios({ // method: 'get', // url: url, // responseType: 'stream' /* responseType must be stream */ // }).then(function (response) { // console.log('Downloading...?'); // // response.data.pipe(fs.createWriteStream(save_path)); // // return true; // return new Promise((resolve, reject) => { // response.data.pipe(writer); // let error = null; // writer.on('error', err => { // console.log('Writer error!'); // error = err; // writer.close(); // reject(err); // }); // writer.on('close', () => { // console.log('Writer close!'); // if (!error) { // resolve(true); // } // //no need to call the reject here, as it will have been called in the // //'error' stream; // }); // }); // }) // .catch(function (error) { // if (error.response && error.response.status === 404) { // return null; // Returning null since there were no results // } // console.log(`Response Status: ${error.response.status}; Status Text: ${error.response.statusText}`); // // console.log(error); // return false; // Returning false since something may have gone wrong. Also more in line with what the API returns. // }); // event.sender.send('asynchronous-reply', true); }); async function download_file(api_base_url, api_endpoint, save_path) { return new Promise((resolve, reject) => { axios.defaults.baseURL = api_base_url; axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*'; // app_config.access_control_allow_origin; axios.defaults.headers.common['content-type'] = 'application/json'; axios.defaults.headers.common['x-aether-api-key'] = 'dFP6J9DVj9hUgIMn-fNIqg'; // api_secret_key; axios.defaults.headers.common['x-account-id'] = '_XY7DXtc9MY'; // account_id; const url = api_endpoint; const writer = fs.createWriteStream(save_path); let result = axios({ method: 'get', url: url, responseType: 'stream' /* responseType must be stream */ }).then(function (response) { console.log('Downloading...?'); // response.data.pipe(fs.createWriteStream(save_path)); // return true; return new Promise((resolve, reject) => { response.data.pipe(writer); let error = null; writer.on('error', err => { console.log('Writer error!'); error = err; writer.close(); reject(err); }); writer.on('close', () => { console.log('Writer close!'); if (!error) { resolve(true); } //no need to call the reject here, as it will have been called in the //'error' stream; }); }); }) .catch(function (error) { if (error.response && error.response.status === 404) { return null; // Returning null since there were no results } console.log(`Response Status: ${error.response.status}; Status Text: ${error.response.statusText}`); // console.log(error); return false; // Returning false since something may have gone wrong. Also more in line with what the API returns. }); resolve(result) }) } // ipcMain.on('open_local_file', (event, file_path, filename) => { // ipcMain.on('open_local_file', ({host_file_cache_path, hash, filename}) => { ipcMain.on('open_local_file', (event, host_file_cache_path, hash, host_file_temp_path, filename) => { console.log('ipcMain open local file: '+host_file_cache_path+' -> '+filename); let cache_file_path = path.join(process.cwd(), host_file_cache_path); console.log(cache_file_path); let hash_filename = hash+'.file'; let full_cache_file_path = path.join(cache_file_path, hash_filename); console.log(full_cache_file_path); open_temp_file_path = path.join(process.cwd(), host_file_temp_path, filename); // 'temp/' console.log(open_temp_file_path); if (fs.existsSync(open_temp_file_path)) { console.log('A file with the same name already exists in the local temp directory: '+open_temp_file_path); // NOTE: Should the file be checked to see if it has changed from the hashed cache version??? // NOTE: What if they made changes to the file locally in temp? The changed file would be used since a new copy is not being made. // NOTE: It might make sense for this to be a configurable option depending on the group. Some do not allow changes. This helps enforce that. } if (fs.existsSync(full_cache_file_path)) { console.log('Hashed file cache exists: '+full_cache_file_path); console.log('Copying file to temp: '+open_temp_file_path); try { fs.copyFileSync(full_cache_file_path, open_temp_file_path); } catch (error) { console.error(error); return false; } // console.log('Creating file link: '+open_temp_file_path); // fs.linkSync(full_cache_file_path, open_temp_file_path); } else { return false; } shell.openPath(open_temp_file_path); //fs.open(open_temp_file_path); // return true; event.sender.send('asynchronous-reply', true); });