1192 lines
45 KiB
JavaScript
1192 lines
45 KiB
JavaScript
'use strict';
|
|
/* This should only contain functions that can not be pulled easily into Svelte */
|
|
/*
|
|
Exported functions in use:
|
|
* load_config()
|
|
* check_hash_file_cache()
|
|
* download_hash_file_to_cache()
|
|
* open_hash_file_to_temp()
|
|
* open_local_file()
|
|
* kill_processes()
|
|
* run_osascript()
|
|
* run_cmd()
|
|
* get_device_info
|
|
|
|
Local functions in use:
|
|
* open_local_file()
|
|
*/
|
|
|
|
const child_process = require('child_process');
|
|
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const fs_promises = require('node:fs/promises');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
const { ipcRenderer } = require('electron');
|
|
|
|
// import psList from 'ps-list';
|
|
// const ps_list = require('ps-list');
|
|
|
|
let home_directory = require('os').homedir();
|
|
console.log('Home: '+home_directory);
|
|
|
|
let tmp_directory = require('os').tmpdir();
|
|
console.log('Temporary: '+tmp_directory);
|
|
|
|
let config = null;
|
|
|
|
exports.load_init_config = function () {
|
|
console.log('*** Aether App Native export: load_init_config() ***');
|
|
|
|
let cwd = process.cwd();
|
|
console.log(`CWD: ${cwd}`);
|
|
|
|
try {
|
|
if (cwd == '/') {
|
|
cwd = home_directory;
|
|
}
|
|
let directory_list = fs.readdirSync(cwd)
|
|
console.log('CWD Contents:', directory_list);
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
// let home_directory = require('os').homedir();
|
|
// console.log('Home: '+home_directory);
|
|
|
|
// let tmp_directory = require('os').tmpdir();
|
|
// console.log('Temporary: '+tmp_directory);
|
|
|
|
// let config = null;
|
|
let config_directory = null;
|
|
// let default_config_path = path.join(process.cwd(),'ae_native_app_config.current.json');
|
|
let default_config_path = 'ae_native_app_config.current.json';
|
|
console.log(`Default Config File (path): ${default_config_path}`);
|
|
let config_path = null;
|
|
|
|
// Set the config path for macOS or Linux
|
|
if (os.platform == 'darwin') {
|
|
// config_directory = path.join(home_directory, 'Library/Application Support/OSIT');
|
|
config_directory = path.join(home_directory, 'OSIT/native_app');
|
|
console.log('macOS config directory: '+config_directory);
|
|
} else if (os.platform == 'linux') {
|
|
config_directory = path.join(home_directory, '.config/OSIT');
|
|
console.log('Linux config directory: '+config_directory);
|
|
}
|
|
|
|
// Look for the config file and copy the default if not found.
|
|
if (fs.existsSync(config_directory)) {
|
|
console.log('Config directory found: '+config_directory);
|
|
} else {
|
|
fs.mkdirSync(config_directory);
|
|
console.log('Config directory created: '+config_directory);
|
|
|
|
//default_config_path = path.join(process.cwd(),'ae_native_app_config.current.json');
|
|
// config_path = path.join(config_directory, 'ae_native_app_config.json');
|
|
// fs.copyFileSync(default_config_path, config_path);
|
|
// console.log('Default config file copied: '+config_directory);
|
|
}
|
|
|
|
config_path = path.join(config_directory, 'ae_native_app_config.json');
|
|
|
|
// Attempt to open the config file. The preferred location is based on the OS's config directory.
|
|
if (fs.existsSync(config_path)) {
|
|
console.log(`Config file (ae_native_app_config.json) found under ${config_directory}`);
|
|
} else if (!fs.existsSync(config_path) && fs.existsSync(default_config_path)) {
|
|
fs.copyFileSync(default_config_path, config_path);
|
|
console.log('Default config file copied: '+config_directory);
|
|
|
|
// config = JSON.parse(fs.readFileSync(config_path));
|
|
// console.log('Config file read.');
|
|
} else if (fs.existsSync(path.join(cwd, 'ae_native_app_config.json'))) {
|
|
//fs.copyFileSync(default_config_path, config_path);
|
|
//console.log('Default config file copied: '+config_directory);
|
|
|
|
console.log(`Config file (config.json) not found under ${config_directory}. Using config in CWD. ${cwd}`);
|
|
config_path = path.join(cwd, 'ae_native_app_config.json');
|
|
|
|
console.log(`Config file (config.json) not found under ${config_directory}. Using config in CWD. ${cwd}`);
|
|
let found_config_path = path.join(cwd, 'ae_native_app_config.json');
|
|
|
|
fs.copyFileSync(found_config_path, config_path);
|
|
console.log(`Found config file copied: ${config_directory}`);
|
|
} else if (fs.existsSync(path.join(cwd, 'ae_native_app_config.current.json'))) {
|
|
console.log(`Config file (config.json) not found under ${config_directory} or CWD. Using default config in CWD. ${cwd}`);
|
|
default_config_path = path.join(cwd, 'ae_native_app_config.current.json');
|
|
|
|
fs.copyFileSync(default_config_path, config_path);
|
|
console.log(`Default config file copied: ${config_directory}`);
|
|
} else {
|
|
console.log('Can not find a config file.');
|
|
|
|
return false;
|
|
}
|
|
|
|
let local_config = JSON.parse(fs.readFileSync(config_path));
|
|
console.log('Config file read.', local_config);
|
|
config = local_config;
|
|
|
|
// Do some quick clean up.
|
|
|
|
config.home_directory = home_directory; // From the OS platform
|
|
config.tmp_directory = tmp_directory; // From the OS platform
|
|
|
|
config.app_root_path = config.app_root_path.replace('[home]', home_directory);
|
|
config.app_root_path = config.app_root_path.replace('[tmp]', tmp_directory);
|
|
console.log(`App Root Path: ${config.app_root_path}`);
|
|
|
|
config.local_file_cache_path = config.local_file_cache_path.replace('[home]', home_directory);
|
|
config.local_file_cache_path = config.local_file_cache_path.replace('[tmp]', tmp_directory);
|
|
console.log(`Local File Cache Path: ${config.local_file_cache_path}`);
|
|
if (fs.existsSync(config.local_file_cache_path)) {
|
|
} else {
|
|
fs.mkdirSync(config.local_file_cache_path);
|
|
console.log(`Host file cache directory created: ${config.local_file_cache_path}`);
|
|
}
|
|
|
|
config.host_file_temp_path = config.host_file_temp_path.replace('[home]', home_directory);
|
|
config.host_file_temp_path = config.host_file_temp_path.replace('[tmp]', tmp_directory);
|
|
console.log(`Host file temp path: ${config.host_file_temp_path}`);
|
|
if (fs.existsSync(config.host_file_temp_path)) {
|
|
} else {
|
|
fs.mkdirSync(config.host_file_temp_path);
|
|
console.log(`Host file temp directory created: ${config.host_file_temp_path}`);
|
|
}
|
|
|
|
if (!config.account_id) {
|
|
config.account_id = '_XY7DXtc9MY'; // Not ideal...?
|
|
}
|
|
|
|
let import_config_to_ipc_result = ipcRenderer.invoke('import_config', config).then((result) => {
|
|
console.log('IPC import config finished');
|
|
// console.log(result);
|
|
return result; // Result should be "true"
|
|
})
|
|
|
|
//console.log(config);
|
|
return config;
|
|
}
|
|
|
|
|
|
exports.load_full_config = function (init_config) {
|
|
console.log('*** Aether App Native export: load_config() ***');
|
|
|
|
console.log('Init config.', init_config);
|
|
// config = init_config;
|
|
|
|
config = get_url_cfg(init_config).then((cfg) => {
|
|
console.log('URL config file downloaded.', cfg);
|
|
|
|
let new_config = init_config;
|
|
|
|
// Update with remote device config settings from API.
|
|
new_config.account_id = cfg.account_id_random;
|
|
new_config.event_id = cfg.event_id_random;
|
|
new_config.event_device_id = cfg.event_device_id;
|
|
new_config.event_location_id = cfg.event_location_id;
|
|
new_config.event_session_id = cfg.event_session_id;
|
|
|
|
new_config.check_event_device_loop_period = cfg.check_event_device_loop_period;
|
|
new_config.check_event_location_loop_period = cfg.check_event_location_loop_period;
|
|
new_config.check_event_loop_period = cfg.check_event_loop_period;
|
|
new_config.check_event_session_loop_period = cfg.check_event_session_loop_period;
|
|
|
|
new_config.record_audio = cfg.record_audio;
|
|
new_config.record_video = cfg.record_video;
|
|
new_config.recording_path = cfg.recording_path;
|
|
new_config.recording_path = new_config.recording_path.replace('[home]', home_directory);
|
|
new_config.recording_path = new_config.recording_path.replace('[tmp]', home_directory);
|
|
|
|
new_config.home_directory = home_directory; // From the OS platform
|
|
new_config.tmp_directory = tmp_directory; // From the OS platform
|
|
|
|
new_config.app_root_path = new_config.app_root_path.replace('[home]', home_directory);
|
|
new_config.app_root_path = new_config.app_root_path.replace('[tmp]', tmp_directory);
|
|
console.log(`App Root Path: ${new_config.app_root_path}`);
|
|
|
|
new_config.local_file_cache_path = new_config.local_file_cache_path.replace('[home]', home_directory);
|
|
new_config.local_file_cache_path = new_config.local_file_cache_path.replace('[tmp]', tmp_directory);
|
|
console.log(`Local File Cache Path: ${new_config.local_file_cache_path}`);
|
|
if (fs.existsSync(new_config.local_file_cache_path)) {
|
|
} else {
|
|
fs.mkdirSync(new_config.local_file_cache_path);
|
|
console.log(`Host file cache directory created: ${new_config.local_file_cache_path}`);
|
|
}
|
|
|
|
new_config.host_file_temp_path = new_config.host_file_temp_path.replace('[home]', home_directory);
|
|
new_config.host_file_temp_path = new_config.host_file_temp_path.replace('[tmp]', tmp_directory);
|
|
console.log(`Host file temp path: ${new_config.host_file_temp_path}`);
|
|
if (fs.existsSync(new_config.host_file_temp_path)) {
|
|
} else {
|
|
fs.mkdirSync(new_config.host_file_temp_path);
|
|
console.log(`Host file temp directory created: ${new_config.host_file_temp_path}`);
|
|
}
|
|
|
|
let import_config_to_ipc_result = ipcRenderer.invoke('import_config', new_config).then((result) => {
|
|
console.log('IPC import config finished');
|
|
// console.log(result);
|
|
return result; // Result should be "true"
|
|
})
|
|
|
|
return new_config
|
|
})
|
|
|
|
//console.log(config);
|
|
return config;
|
|
}
|
|
|
|
|
|
async function get_url_cfg(cfg) {
|
|
let base_url = `${cfg.api_protocol}://${cfg.api_server}:${cfg.api_port}/${cfg.api_path}`;
|
|
|
|
let axios_api = axios.create({
|
|
baseURL: base_url,
|
|
timeout: 60000, // in milliseconds; 60000 = 60 seconds
|
|
/* other custom settings */
|
|
});
|
|
// axios_api.defaults.headers = cfg['headers'];
|
|
|
|
// axios.defaults.baseURL = `${cfg.api_protocol}://${cfg.api_server}:${cfg.api_port}/${cfg.api_path}`;
|
|
axios_api.defaults.headers.common['Access-Control-Allow-Origin'] = cfg.access_control_allow_origin; // '*'; // app_cfg.access_control_allow_origin;
|
|
axios_api.defaults.headers.common['content-type'] = 'application/json';
|
|
axios_api.defaults.headers.common['x-aether-api-key'] = cfg.api_secret_key;
|
|
// axios_api.defaults.headers.common['x-account-id'] = cfg.account_id;
|
|
|
|
let event_device_id = 'dbgMWS3KEHE';
|
|
let endpoint = `/event/device/${event_device_id}`;
|
|
|
|
let params = {'event_device_code': 'asdf'};
|
|
|
|
let response_data_promise = await axios_api.get(
|
|
endpoint,
|
|
{
|
|
params: params,
|
|
onDownloadProgress: (progressEvent) => {
|
|
let percent_completed = Math.round(
|
|
(progressEvent.loaded * 100) / progressEvent.total
|
|
);
|
|
console.log('GET Data Timestamp:', progressEvent.timeStamp, 'Total:', progressEvent.total, 'Loaded:', progressEvent.loaded, 'Percent Completed', percent_completed);
|
|
|
|
// temp_get_object_percent_completed = percent_completed;
|
|
}
|
|
}
|
|
)
|
|
.then(function (response) {
|
|
console.log(`Response: ${response}`);
|
|
|
|
let return_data = response.data['data'];
|
|
if (Array.isArray(return_data)) {
|
|
console.log(`Data result is an array/list. Array length: ${return_data.length}`);
|
|
} else {
|
|
console.log(`Data result is a dictionary/object, not an array/list.`);
|
|
}
|
|
return return_data;
|
|
})
|
|
.catch(function (error) {
|
|
console.log(`Base URL: ${base_url} | Endpoint: ${endpoint}`);
|
|
|
|
console.log('Error Message:', error.message); // Is this needed here or below in the in the else portion???
|
|
if (error.response) {
|
|
console.log(`Response Status: ${error.response.status}; Status Text: ${error.response.statusText}`);
|
|
} else {
|
|
console.log('Error:', error);
|
|
}
|
|
|
|
if (error.response && error.response.status === 404) {
|
|
return null; // Returning null since there were no results
|
|
}
|
|
return false; // Returning false since something may have gone wrong. Also more in line with what the API returns.
|
|
});
|
|
|
|
return response_data_promise;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check for local file
|
|
// Updated 2022-05-06
|
|
exports.check_local_file = async function ({local_file_path, filename}) {
|
|
console.log('*** Electron framework export: check_local_file() ***');
|
|
// console.log('Check for local file');
|
|
console.log(`Local File Path: ${local_file_path}; Filename: ${filename}`);
|
|
|
|
let full_local_file_path = path.join(local_file_path, filename);
|
|
console.log(full_local_file_path);
|
|
|
|
if (fs.existsSync(full_local_file_path)) {
|
|
console.log(`Local file exists: ${full_local_file_path}`);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// Check local hash file cache
|
|
// Used by Svelte Event Launcher
|
|
// NOTE: Trying to replace this with something directly in the Svelte app part. 2022-10-11
|
|
// Updated 2022-05-06
|
|
exports.check_hash_file_cache = async function ({local_file_cache_path, hash}) {
|
|
// console.log('*** Electron framework export: check_hash_file_cache() ***');
|
|
// console.log('Check local hash file cache');
|
|
console.log(`*** Electron framework export: check_hash_file_cache() *** Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}`);
|
|
|
|
let hash_filename = `${hash}.file`;
|
|
|
|
let subdirectory = hash_filename.substring(0,2);
|
|
let subdirectory_path = path.join(local_file_cache_path, subdirectory);
|
|
if (fs.existsSync(subdirectory_path)) {
|
|
} else {
|
|
console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
|
|
return false;
|
|
}
|
|
|
|
let hash_file_cache_path = path.join(subdirectory_path, hash_filename);
|
|
// console.log(hash_file_cache_path);
|
|
|
|
if (fs.existsSync(hash_file_cache_path)) {
|
|
// console.log(`Hashed file exists in cache: ${hash_file_cache_path}`);
|
|
return true;
|
|
} else {
|
|
console.log(`Hashed file not found in cache: ${hash_file_cache_path}`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// Check local hash file cache
|
|
// Used by Svelte Event Launcher
|
|
// Updated 2022-10-12
|
|
exports.check_hash_file_cache_v2 = async function ({local_file_cache_path, hash, verify_hash=false}) {
|
|
console.log('*** Aether App Native export: check_hash_file_cache_v2() ***');
|
|
console.log(`Local File Cache Path: ${local_file_cache_path}; Hash: ${hash}`);
|
|
|
|
if (fs.existsSync(local_file_cache_path)) {
|
|
} else {
|
|
// This should not happen. The directory needs to be created.
|
|
console.log(`Cache directory for hashed files was not found: ${local_file_cache_path}`);
|
|
return false;
|
|
}
|
|
|
|
let hash_filename = `${hash}.file`;
|
|
|
|
let hash_subdirectory = hash_filename.substring(0,2);
|
|
let subdirectory_path = path.join(local_file_cache_path, hash_subdirectory);
|
|
|
|
if (fs.existsSync(subdirectory_path)) {
|
|
} else {
|
|
// This should not happen. The subdirectory needs to be created.
|
|
console.log(`Hashed file subdirectory not found in cache directory: ${subdirectory_path}`);
|
|
return false;
|
|
}
|
|
|
|
let full_cached_hash_path = path.join(subdirectory_path, hash_filename);
|
|
|
|
if (fs.existsSync(full_cached_hash_path)) {
|
|
// console.log(`Hashed file exists in cache: ${full_cached_hash_path}`);
|
|
|
|
if (verify_hash) {
|
|
const file_buffer = fs.readFileSync(full_cached_hash_path);
|
|
const file_hash_sha256 = crypto.createHash('sha256');
|
|
file_hash_sha256.update(file_buffer);
|
|
|
|
const file_hash_sha256_check = file_hash_sha256.digest('hex');
|
|
if (file_hash_sha256_check == hash) {
|
|
console.log('File hash match', file_hash_sha256_check);
|
|
} else {
|
|
// This should only happen if the file is actively being downloaded or it is corrupt.
|
|
console.log('File hash does not match', file_hash_sha256_check);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} else {
|
|
console.log(`Hashed file not found in cache: ${full_cached_hash_path}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
// Download hash file to cache
|
|
// Used by Svelte Event Launcher
|
|
// Updated 2022-05-06
|
|
exports.download_hash_file_to_cache = async function ({api_base_url, local_file_cache_path, event_file_id=null, hash=null}) {
|
|
// console.log('*** Electron framework export: download_hash_file_to_cache() ***');
|
|
// console.log('Download hash file to cache');
|
|
console.log(`*** Electron framework export: download_hash_file_to_cache() *** Base URL: ${api_base_url}; Host File Cache Path: ${local_file_cache_path}; Event File ID: ${event_file_id}; Hash: ${hash}`);
|
|
|
|
let endpoint = `/event/file/${event_file_id}/download`;
|
|
|
|
let hash_filename = `${hash}.file`;
|
|
|
|
let subdirectory = hash_filename.substring(0,2);
|
|
let subdirectory_path = path.join(local_file_cache_path, subdirectory);
|
|
if (fs.existsSync(subdirectory_path)) {
|
|
} else {
|
|
fs.mkdirSync(subdirectory_path);
|
|
console.log(`Subdirectory directory created: ${subdirectory_path}`);
|
|
}
|
|
|
|
let hash_file_cache_path = path.join(subdirectory_path, hash_filename);
|
|
if (fs.existsSync(hash_file_cache_path)) {
|
|
if (check_hash) {
|
|
const file_buffer = fs.readFileSync(hash_file_cache_path);
|
|
const file_hash_sha256 = crypto.createHash('sha256');
|
|
file_hash_sha256.update(file_buffer);
|
|
|
|
const file_hash_sha256_check = file_hash_sha256.digest('hex');S
|
|
if (file_hash_sha256_check == hash) {
|
|
console.log('File hash match', file_hash_sha256_check);
|
|
return true;
|
|
} else {
|
|
// This should only happen if the file is actively being downloaded or it is corrupt.
|
|
console.log('File hash does not match', file_hash_sha256_check);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
// console.log(`!!!ABOUT TO CALL DOWNLOAD FILE HANDLER!!! exports.download_hash_file_to_cache(); Base URL: ${api_base_url}`);
|
|
let download_file_result = await ipcRenderer.invoke('download_file', api_base_url, endpoint, hash_file_cache_path).then((result) => {
|
|
if (result) {
|
|
console.log('IPC download file process finished successfully');
|
|
return true;
|
|
} else if (result == null) {
|
|
console.log('IPC Download Result (file not found?):', result);
|
|
return null;
|
|
} else {
|
|
console.log('IPC Download Result (file being downloaded or something went wrong):', result);
|
|
return false;
|
|
}
|
|
});
|
|
// console.log(`!!!DONE WITH DOWNLOAD FILE HANDLER!!! exports.download_hash_file_to_cache(); Base URL: ${api_base_url}`);
|
|
|
|
return download_file_result;
|
|
}
|
|
|
|
|
|
// Download hash file to cache
|
|
// Used by Svelte Event Launcher
|
|
// Updated 2022-10-12
|
|
exports.download_hash_file_to_cache_v2 = async function ({api_base_url, local_file_cache_path, event_file_id=null, hash=null, verify_hash=true, overwrite_existing=false}) {
|
|
console.log('*** Aether App Native export: download_hash_file_to_cache_v2() ***');
|
|
console.log(`Base URL: ${api_base_url}; Host File Cache Path: ${local_file_cache_path}; Event File ID: ${event_file_id}; Hash: ${hash}`);
|
|
|
|
if (fs.existsSync(local_file_cache_path)) {
|
|
} else {
|
|
// This should not happen. The directory needs to be created.
|
|
console.log(`Cache directory for hashed files was not found: ${local_file_cache_path}`);
|
|
return false;
|
|
}
|
|
|
|
let endpoint = `/event/file/${event_file_id}/download`;
|
|
|
|
let hash_filename = `${hash}.file`;
|
|
|
|
let hash_subdirectory = hash_filename.substring(0,2);
|
|
let subdirectory_path = path.join(local_file_cache_path, hash_subdirectory);
|
|
|
|
if (fs.existsSync(subdirectory_path)) {
|
|
} else {
|
|
fs.mkdirSync(subdirectory_path);
|
|
console.log(`Hashed file subdirectory directory created in cache directory: ${subdirectory_path}`);
|
|
}
|
|
|
|
let full_cached_hash_path = path.join(subdirectory_path, hash_filename);
|
|
|
|
if (fs.existsSync(full_cached_hash_path)) {
|
|
console.log(`Hashed file exists in cache: ${full_cached_hash_path}`);
|
|
|
|
if (verify_hash) {
|
|
const file_buffer = fs.readFileSync(full_cached_hash_path);
|
|
const file_hash_sha256 = crypto.createHash('sha256');
|
|
file_hash_sha256.update(file_buffer);
|
|
|
|
const file_hash_sha256_check = file_hash_sha256.digest('hex');
|
|
if (file_hash_sha256_check == hash) {
|
|
// console.log('File hash match', file_hash_sha256_check);
|
|
if (overwrite_existing) {
|
|
console.log('Going to overwrite the existing file even though the hash matches.');
|
|
} else {
|
|
return true;
|
|
}
|
|
} else {
|
|
// This should only happen if the file is actively being copied or it is corrupt.
|
|
console.log('File hash does not match', file_hash_sha256_check);
|
|
if (overwrite_existing) {
|
|
console.log('Going to overwrite the existing file because the hash does not match.');
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let download_file_result = await ipcRenderer.invoke('download_file', api_base_url, endpoint, full_cached_hash_path, hash, verify_hash, overwrite_existing).then((result) => {
|
|
if (result) {
|
|
console.log('IPC download file process finished successfully');
|
|
return true;
|
|
} else if (result == null) {
|
|
console.log('IPC Download Result (file not found?):', result);
|
|
return null;
|
|
} else {
|
|
console.log('IPC Download Result (file being downloaded or something went wrong):', result);
|
|
return false;
|
|
}
|
|
});
|
|
|
|
return download_file_result;
|
|
}
|
|
|
|
|
|
|
|
// Open cached hash file after copying to temp directory
|
|
// Used by Svelte Event Launcher
|
|
// NOTE: Trying to replace this with something directly in the Svelte app part. 2022-10-11
|
|
// Updated 2022-05-06
|
|
exports.open_hash_file_to_temp = async function ({local_file_cache_path, hash, host_file_temp_path, filename}) {
|
|
console.log('*** Electron framework export: open_hash_file_to_temp() ***');
|
|
// console.log('Open cached hash file after copying to temp directory');
|
|
console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
|
|
|
|
let subdirectory = hash.substring(0,2);
|
|
let subdirectory_path = path.join(local_file_cache_path, subdirectory);
|
|
if (fs.existsSync(subdirectory_path)) {
|
|
} else {
|
|
console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
|
|
return false;
|
|
}
|
|
|
|
let open_hash_file_to_temp_result = await ipcRenderer.invoke('open_hash_file_to_temp', subdirectory_path, hash, host_file_temp_path, filename).then((result) => {
|
|
console.log('IPC open hash file to temp finished');
|
|
console.log(result);
|
|
return true;
|
|
})
|
|
|
|
// let result = await ipcRenderer.send('open_local_file', local_file_cache_path, hash, host_file_temp_path, filename);
|
|
// console.log(result);
|
|
|
|
console.log(open_hash_file_to_temp_result);
|
|
console.log('End: open_hash_file_to_temp()');
|
|
if (open_hash_file_to_temp_result) {
|
|
console.log('File opened successfully');
|
|
return true;
|
|
} else {
|
|
console.log('File was not opened successfully');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Open cached hash file after copying to temp directory
|
|
// Used by Svelte Event Launcher
|
|
// Updated 2022-10-12
|
|
exports.open_hash_file_to_temp_v2 = async function ({local_file_cache_path, hash, host_file_temp_path, filename, verify_hash=true}) {
|
|
console.log('*** Aether App Native export: open_hash_file_to_temp_v2() ***');
|
|
console.log(`Local File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Local File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
|
|
|
|
// console.log('Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory');
|
|
|
|
if (fs.existsSync(local_file_cache_path)) {
|
|
} else {
|
|
// This should not happen. The directory needs to be created.
|
|
console.log(`Cache directory for hashed files was not found: ${local_file_cache_path}`);
|
|
return false;
|
|
}
|
|
|
|
let hash_filename = `${hash}.file`;
|
|
|
|
let hash_subdirectory = hash_filename.substring(0,2);
|
|
let subdirectory_path = path.join(local_file_cache_path, hash_subdirectory);
|
|
|
|
if (fs.existsSync(subdirectory_path)) {
|
|
} else {
|
|
// This should not happen. The subdirectory needs to be created.
|
|
console.log(`Hashed file subdirectory not found in cache directory: ${subdirectory_path}`);
|
|
return false;
|
|
}
|
|
|
|
let full_cached_hash_path = path.join(subdirectory_path, hash_filename);
|
|
|
|
if (fs.existsSync(full_cached_hash_path)) {
|
|
console.log(`Hashed file exists in cache: ${full_cached_hash_path}`);
|
|
|
|
if (verify_hash) {
|
|
const file_buffer = fs.readFileSync(full_cached_hash_path);
|
|
const file_hash_sha256 = crypto.createHash('sha256');
|
|
file_hash_sha256.update(file_buffer);
|
|
|
|
const file_hash_sha256_check = file_hash_sha256.digest('hex');
|
|
if (file_hash_sha256_check == hash) {
|
|
// console.log('File hash match', file_hash_sha256_check);
|
|
} else {
|
|
// This should only happen if the file is actively being downloaded or it is corrupt.
|
|
console.log('File hash does not match', file_hash_sha256_check);
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
console.log(`Hashed file not found in cache: ${full_cached_hash_path}`);
|
|
return null;
|
|
}
|
|
|
|
let local_file_cache_path_w_sub = subdirectory_path; // I need to go back and clean up the variable names related file directory and file paths.
|
|
// NOTE: Setting check_hash to false since by default it was checked above.
|
|
let open_hash_file_to_temp_result = await ipcRenderer.invoke('open_hash_file_to_temp', local_file_cache_path_w_sub, hash, host_file_temp_path, filename, verify_hash=false).then((result) => {
|
|
console.log('IPC open hash file to temp finished');
|
|
if (result) {
|
|
console.log('Local hash file was opened from temp directory.');
|
|
return result;
|
|
} else {
|
|
console.log('Local hash file was not opened from the temp directory. Something went wrong.');
|
|
console.log(result);
|
|
return false;
|
|
}
|
|
})
|
|
|
|
// let result = await ipcRenderer.send('open_local_file', local_file_cache_path, hash, host_file_temp_path, filename);
|
|
// console.log(result);
|
|
|
|
// console.log(open_hash_file_to_temp_result);
|
|
// console.log('End: open_hash_file_to_temp()');
|
|
// if (open_hash_file_to_temp_result) {
|
|
// console.log('File opened successfully');
|
|
// return true;
|
|
// } else {
|
|
// console.log('File was not opened successfully');
|
|
// return false;
|
|
// }
|
|
|
|
// let open_hash_file_to_temp_result = await ipcRenderer.invoke('open_hash_file_to_temp', subdirectory_path, hash, host_file_temp_path, filename).then((result) => {
|
|
// console.log('IPC open hash file to temp finished');
|
|
// if (result) {
|
|
// console.log('Local hash file was opened from temp directory.');
|
|
// return result;
|
|
// } else {
|
|
// console.log('Local hash file was not opened from the temp directory. Something went wrong.');
|
|
// console.log(result);
|
|
// return false;
|
|
// }
|
|
// })
|
|
|
|
return open_hash_file_to_temp_result;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Open local file
|
|
// Used by Svelte Event Launcher
|
|
// NOTE: Trying to replace this with something directly in the Svelte app part. 2022-10-11
|
|
// Updated 2022-03-10
|
|
exports.open_local_file = async function ({local_file_path, filename}) {
|
|
console.log('*** Electron framework export: open_local_file() ***');
|
|
// console.log('Open local file');
|
|
console.log(`Local File Path: ${local_file_path}; Filename: ${filename}`);
|
|
|
|
// let full_local_file_path = path.join(local_file_path, filename);
|
|
// console.log(full_local_file_path);
|
|
|
|
// if (fs.existsSync(full_local_file_path)) {
|
|
// console.log(`Local file exists: ${full_local_file_path}`);
|
|
// // return true;
|
|
// } else {
|
|
// return false;
|
|
// }
|
|
|
|
let open_local_file_result = await ipcRenderer.invoke('open_local_file', local_file_path, filename).then((result) => {
|
|
console.log('IPC open local file finished');
|
|
console.log(result);
|
|
return true;
|
|
})
|
|
|
|
console.log(open_local_file_result);
|
|
console.log('End: open_local_file()');
|
|
if (open_local_file_result) {
|
|
console.log('File opened successfully');
|
|
return true;
|
|
} else {
|
|
console.log('File was not opened successfully');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// // Check local file cache and download from server if needed.
|
|
// // Updated 2022-03-09
|
|
// // exports.check_file_cache = async function ({local_file_cache_path, event_file_id, hash}) {
|
|
// exports.check_file_cache = async function ({api_base_url, local_file_cache_path, event_file_id, hash}) {
|
|
// console.log('*** Electron framework export: check_file_cache() ***');
|
|
// // console.log('Check local file cache and download from server if needed.');
|
|
// console.log(`Host File Cache Path: ${local_file_cache_path}; Event File ID: ${event_file_id}; Hash: ${hash}`);
|
|
|
|
// // NOTE: event_file_id is the event_file.id_random or event_file.event_file_id_random
|
|
// let hash_filename = hash+'.file';
|
|
|
|
// let save_path = path.join(local_file_cache_path, hash_filename);
|
|
// console.log(save_path);
|
|
|
|
// if (fs.existsSync(save_path)) {
|
|
// console.log('Hashed file cache already exists: '+save_path);
|
|
// return true;
|
|
// } else {
|
|
// console.log('Hashed file not found in local cache. Downloading file: '+save_path);
|
|
// let endpoint = `/event/file/${event_file_id}/download`;
|
|
// let result = await ipcRenderer.send('download_file', api_base_url, endpoint, save_path); // Must download file using main node.js thread.
|
|
// console.log(result);
|
|
|
|
// return new Promise((resolve, reject) => {
|
|
// ipcRenderer.once('download_file_reply', function(event, response){
|
|
// console.log(response);
|
|
// return response;
|
|
// })
|
|
// resolve(true);
|
|
// });
|
|
|
|
// // await ipcRenderer.once('download_file_reply', function(event, response){
|
|
// // console.log(response);
|
|
// // return response;
|
|
// // });
|
|
|
|
// // result.then(function (response) {
|
|
// // console.log('Downloaded!!!???');
|
|
// // return true;
|
|
// // }).catch(function (error) {
|
|
// // console.log(error);
|
|
// // return false;
|
|
// // });
|
|
|
|
// // return result;
|
|
|
|
// // console.log(result);
|
|
// // if (result) {
|
|
// // return true;
|
|
// // } else {
|
|
// // return false;
|
|
// // }
|
|
// }
|
|
// }
|
|
|
|
|
|
// Check local file cache and download from server if needed. Must use IPC to Main to download file. Set a Promise to wait for download_file_reply.
|
|
// Updated 2022-03-09
|
|
async function check_file_cache({api_base_url, local_file_cache_path, event_file_id, hash}) {
|
|
console.log('*** Electron framework: check_file_cache() ***');
|
|
// console.log('Check local file cache and download from server if needed.');
|
|
console.log(`Host File Cache Path: ${local_file_cache_path}; Event File ID: ${event_file_id}; Hash: ${hash}`);
|
|
|
|
// NOTE: event_file_id is the event_file.id_random or event_file.event_file_id_random
|
|
let hash_filename = hash+'.file';
|
|
|
|
let save_path = path.join(local_file_cache_path, hash_filename);
|
|
console.log(save_path);
|
|
|
|
if (fs.existsSync(save_path)) {
|
|
console.log('Hashed file cache already exists: '+save_path);
|
|
return true;
|
|
} else {
|
|
console.log('Hashed file not found in local cache. Downloading file: '+save_path);
|
|
let endpoint = `/event/file/${event_file_id}/download`;
|
|
let result = await ipcRenderer.send('download_file', api_base_url, endpoint, save_path); // Must download file using main node.js thread.
|
|
console.log(result);
|
|
|
|
return new Promise((resolve, reject) => {
|
|
ipcRenderer.once('download_file_reply', function(event, response){
|
|
console.log(response);
|
|
return response;
|
|
})
|
|
resolve(true);
|
|
});
|
|
|
|
// await ipcRenderer.once('download_file_reply', function(event, response){
|
|
// console.log(response);
|
|
// return response;
|
|
// });
|
|
|
|
// result.then(function (response) {
|
|
// console.log('Downloaded!!!???');
|
|
// return true;
|
|
// }).catch(function (error) {
|
|
// console.log(error);
|
|
// return false;
|
|
// });
|
|
|
|
// return result;
|
|
|
|
// console.log(result);
|
|
// if (result) {
|
|
// return true;
|
|
// } else {
|
|
// return false;
|
|
// }
|
|
}
|
|
}
|
|
|
|
|
|
// IPC to Main: Open local file cache if available. Copy to temp directory with given filename first.
|
|
// Updated 2022-03-09
|
|
async function open_local_file({local_file_cache_path, hash, host_file_temp_path, filename}) {
|
|
console.log('*** Electron framework: open_local_file() ***');
|
|
// console.log('Open local file cache if available. Copy to temp directory with given filename first.');
|
|
console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
|
|
|
|
console.log(local_file_cache_path);
|
|
console.log(hash);
|
|
console.log(filename);
|
|
|
|
let result = await ipcRenderer.send('open_local_file', local_file_cache_path, hash, host_file_temp_path, filename);
|
|
console.log(result);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// No longer needed? Not referenced as of 2022-10-11
|
|
exports.check_file_cache_and_open_local_file = async function ({local_file_cache_path, event_file_id, hash, host_file_temp_path, filename}) {
|
|
console.log('*** Electron framework: check_file_cache_and_open_local_file() ***');
|
|
console.log('Checking the local file cache against the remote server and then opening the local file.');
|
|
|
|
let check_file_cache_result = check_file_cache({local_file_cache_path: local_file_cache_path, event_file_id: event_file_id, hash: hash});
|
|
console.log(check_file_cache_result);
|
|
|
|
if (check_file_cache_result) {
|
|
let open_local_file_result = open_local_file({local_file_cache_path: local_file_cache_path, hash: hash, host_file_temp_path: host_file_temp_path, filename: filename});
|
|
console.log(open_local_file_result);
|
|
|
|
return open_local_file_result;
|
|
}
|
|
|
|
ipcRenderer.once('download_file_reply', function(event, response){
|
|
console.log(response);
|
|
|
|
let open_local_file_result = open_local_file({local_file_cache_path: local_file_cache_path, hash: hash, host_file_temp_path: host_file_temp_path, filename: filename});
|
|
console.log(open_local_file_result);
|
|
|
|
return open_local_file_result;
|
|
})
|
|
}
|
|
|
|
|
|
// Kill processes
|
|
// Signals: HUP (hang up), INT (interrupt), QUIT (quit), ABRT (abort), KILL (non-catchable, non-ignoraable kill), ALRMn (alarm clock), TERM (default; software termination signal)
|
|
// Updated 2022-05-07
|
|
exports.kill_processes = async function ({process_name = null, process_id = null, signal = null}) {
|
|
console.log('*** Electron framework export: kill_processes() ***');
|
|
console.log(process_name); // process_name or grep pattern
|
|
|
|
let cmd = '';
|
|
if (os.platform == 'darwin') {
|
|
if (signal == 'HUP') {
|
|
cmd = `killall -HUP '${process_name}'`;
|
|
} else if (signal == 'INT') {
|
|
cmd = `killall -INT '${process_name}'`;
|
|
} else if (signal == 'QUIT') {
|
|
cmd = `killall -QUIT '${process_name}'`;
|
|
} else if (signal == 'ABRT') {
|
|
cmd = `killall -ABRT '${process_name}'`;
|
|
} else if (signal == 'KILL') {
|
|
cmd = `killall -KILL '${process_name}'`;
|
|
} else if (signal == 'ALRM') {
|
|
cmd = `killall -ALRM '${process_name}'`;
|
|
} else if (signal == 'TERM') {
|
|
cmd = `killall -TERM '${process_name}'`;
|
|
} else if (process_id && signal == 'HUP') {
|
|
cmd = `killall -HUP ${process_id}`;
|
|
} else if (process_id && signal == 'INT') {
|
|
cmd = `killall -INT ${process_id}`;
|
|
} else if (process_id && signal == 'QUIT') {
|
|
cmd = `killall -QUIT ${process_id}`;
|
|
} else if (process_id && signal == 'ABRT') {
|
|
cmd = `killall -ABRT ${process_id}`;
|
|
} else if (process_id && signal == 'KILL') {
|
|
cmd = `killall -KILL ${process_id}`;
|
|
} else if (process_id && signal == 'ALRM') {
|
|
cmd = `killall -ALRM ${process_id}`;
|
|
} else if (process_id && signal == 'TERM') {
|
|
cmd = `killall -TERM ${process_id}`;
|
|
} else {
|
|
// cmd = `osascript -e 'quit app "${process_name}" saving no'`;
|
|
cmd = `osascript -e 'quit application "${process_name}" saving no'`;
|
|
}
|
|
|
|
} else {
|
|
cmd = `pkill ${process_name}`;
|
|
}
|
|
|
|
child_process.exec(cmd, (err, stdout, stdin) => {
|
|
// if (err) throw err;
|
|
if (err) console.log(err);
|
|
console.log(stdout);
|
|
});
|
|
console.log(`Killed processes matching ${process_name}`);
|
|
|
|
if (os.platform == 'darwin') {
|
|
if (process_name == 'Parallels:Acrobat Reader') {
|
|
// Regular expression: (Parallels).*(Acrobat Reader)
|
|
// This will find any process with Parallels and Acrobat Reader in the name
|
|
cmd = `pkill -i -f '(Parallels).*(Acrobat Reader)'`;
|
|
|
|
child_process.exec(cmd, (err, stdout, stdin) => {
|
|
if (err) throw err;
|
|
console.log(stdout);
|
|
});
|
|
console.log('Killed Parallels Acrobat Reader process');
|
|
}
|
|
|
|
if (process_name == 'Parallels:PowerPoint') {
|
|
// Regular expression: (Parallels).*(PowerPoint)
|
|
// This will find any process with Parallels and PowerPoint in the name
|
|
cmd = `pkill -i -f '(Parallels).*(PowerPoint)'`;
|
|
|
|
child_process.exec(cmd, (err, stdout, stdin) => {
|
|
if (err) throw err;
|
|
console.log(stdout);
|
|
});
|
|
console.log('Killed Parallels PowerPoint process');
|
|
}
|
|
}
|
|
|
|
// let signal = 'SIGTERM'; // 'SIGTERM', 'SIGINT', 'SIGHUP'
|
|
// process.kill(pid, signal);
|
|
// process.kill(pid, 0); // Special case test if process exists
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Run raw osascript
|
|
// Updated 2022-05-07
|
|
exports.run_osascript = async function ({cmd=null, interactive=false, language=null, flags='h', program_file=null}) {
|
|
console.log('*** Electron framework export: run_osascript() ***');
|
|
console.log(cmd);
|
|
|
|
if (os.platform == 'darwin') {
|
|
} else {
|
|
console.log('Not available for this platform. macOS (darwin) only.');
|
|
return false;
|
|
}
|
|
|
|
let osascript_str = '';
|
|
|
|
if (Array.isArray(cmd)) {
|
|
console.log('List of cmd strings');
|
|
let cmds_str = '';
|
|
for (let i = 0; i < cmd.length; i++) {
|
|
cmds_str += `-e '${cmd[i]}'`;
|
|
}
|
|
osascript_str = `osascript ${cmds_str}`
|
|
|
|
} else if (typeof cmd === 'string') {
|
|
console.log('Single cmd string');
|
|
osascript_str = `osascript -e '${cmd}'`;
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
if (language) {
|
|
console.log(`Language: ${language}`);
|
|
osascript_str = `${osascript_str} -l ${language}`;
|
|
}
|
|
|
|
if (flags) {
|
|
console.log(`Flags: ${flags}`);
|
|
osascript_str = `${osascript_str} -s ${flags}`;
|
|
}
|
|
|
|
console.log(`OSA Script String: ${osascript_str}`);
|
|
child_process.exec(osascript_str, (err, stdout, stdin) => {
|
|
if (err) throw err;
|
|
console.log(stdout);
|
|
console.log(stdin);
|
|
});
|
|
|
|
console.log('Finished');
|
|
return true;
|
|
}
|
|
|
|
|
|
// Run raw command
|
|
// Updated 2022-05-07
|
|
exports.run_cmd = async function ({cmd=null, return_stdout=null, return_stdin=null, sync=null}) {
|
|
console.log('*** Electron framework export: run_cmd() ***');
|
|
|
|
console.log(`Command String: ${cmd}`);
|
|
|
|
let result;
|
|
|
|
if (!sync) {
|
|
result = child_process.exec(cmd, (err, stdout, stdin) => {
|
|
// if (err) throw err;
|
|
if (err) {
|
|
console.log('Error:', err);
|
|
return false;
|
|
};
|
|
|
|
console.log('stdout:', stdout);
|
|
// console.log('stdin:', stdin);
|
|
|
|
if (return_stdout) {
|
|
console.log('Finished and returning stdout');
|
|
return stdout;
|
|
} else {
|
|
console.log('Finished and returning true');
|
|
return true;
|
|
}
|
|
});
|
|
} else {
|
|
result = child_process.execSync(cmd, (err, stdout, stdin) => {
|
|
// if (err) throw err;
|
|
if (err) {
|
|
console.log('Error:', err);
|
|
return false;
|
|
};
|
|
|
|
console.log('stdout:', stdout);
|
|
// console.log('stdin:', stdin);
|
|
|
|
if (return_stdout) {
|
|
console.log('Finished and returning stdout');
|
|
return stdout;
|
|
} else {
|
|
console.log('Finished and returning true');
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
console.log('Result:', result);
|
|
return result;
|
|
}
|
|
|
|
|
|
// Run raw command sync
|
|
// Updated 2022-05-07
|
|
exports.run_cmd_sync = function ({cmd=null, return_stdout=null, return_stdin=null}) {
|
|
console.log('*** Electron framework export: run_cmd() ***');
|
|
|
|
console.log(`Command String: ${cmd}`);
|
|
|
|
let stdout;
|
|
|
|
try {
|
|
stdout = child_process.execSync(cmd, {encoding: 'utf8'});
|
|
console.log('Std Out:', stdout);
|
|
} catch (err) {
|
|
console.error('Error:', err);
|
|
return false;
|
|
}
|
|
|
|
if (return_stdout) {
|
|
console.log('Finished and returning stdout');
|
|
return stdout;
|
|
} else {
|
|
console.log('Finished and returning true');
|
|
return true;
|
|
}
|
|
|
|
// let result;
|
|
// let stdout;
|
|
// let stderr;
|
|
// try {
|
|
// let { stdout, stderr } = child_process.execSync(cmd, (err, stdout, stdin) => {
|
|
// // if (err) throw err;
|
|
// if (err) {
|
|
// console.log('Error:', err);
|
|
// return false;
|
|
// };
|
|
|
|
// console.log('stdout:', stdout);
|
|
// // console.log('stdin:', stdin);
|
|
|
|
// if (return_stdout) {
|
|
// console.log('Finished and returning stdout');
|
|
// return stdout;
|
|
// } else {
|
|
// console.log('Finished and returning true');
|
|
// return true;
|
|
// }
|
|
// });
|
|
// } catch (err) {
|
|
// console.error(err);
|
|
// return false;
|
|
// }
|
|
|
|
// console.log('Result:', result);
|
|
// return result;
|
|
}
|
|
|
|
|
|
// Run raw command
|
|
// Updated 2022-05-25
|
|
exports.get_device_info = async function () {
|
|
console.log('*** Electron framework export: get_device_info() ***');
|
|
|
|
// https://nodejs.org/api/os.html
|
|
|
|
let data = {};
|
|
data['arch'] = os.arch();
|
|
data['hostname'] = os.hostname();
|
|
data['cpus'] = os.cpus();
|
|
data['freemem'] = os.freemem();
|
|
data['totalmem'] = os.totalmem();
|
|
data['loadavg'] = os.loadavg();
|
|
data['networkInterfaces'] = os.networkInterfaces();
|
|
data['platform'] = os.platform();
|
|
data['release'] = os.release();
|
|
data['uptime'] = os.uptime();
|
|
data['version'] = os.version();
|
|
|
|
console.log(data);
|
|
return data;
|
|
}
|
|
|
|
|
|
|
|
// For loading JS file
|
|
function loadJS(){
|
|
|
|
// Gives -1 when the given input is not in the string
|
|
// i.e this file has not been added
|
|
|
|
if(filesAdded.indexOf('script.js') !== -1)
|
|
return
|
|
|
|
// Head tag
|
|
var head = document.getElementsByTagName('head')[0]
|
|
|
|
// Creating script element
|
|
var script = document.createElement('script')
|
|
script.src = 'script.js'
|
|
script.type = 'text/javascript'
|
|
|
|
// Adding script element
|
|
head.append(script)
|
|
|
|
// Adding the name of the file to keep record
|
|
filesAdded += ' script.js'
|
|
}
|
|
|
|
// To load CSS file
|
|
function loadCSS() {
|
|
|
|
if(filesAdded.indexOf('styles.css') !== -1)
|
|
return
|
|
|
|
var head = document.getElementsByTagName('head')[0]
|
|
|
|
// Creating link element
|
|
var style = document.createElement('link')
|
|
style.href = 'styles.css'
|
|
style.type = 'text/css'
|
|
style.rel = 'stylesheet'
|
|
head.append(style);
|
|
|
|
// Adding the name of the file to keep record
|
|
filesAdded += ' styles.css'
|
|
}
|