From de048a084bb9509ceb83493d546e46644a49e3f4 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Tue, 2 Jun 2026 14:04:28 -0400 Subject: [PATCH] chore: remove axios + deprecated electron_native.js; track lucide-svelte migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Uninstall axios — only consumer was electron_native.js (legacy V2 file) - Delete electron_native.js — deprecated 2026-02-10, no active imports; replaced by aether_app_native_electron repo + electron_relay.ts contextBridge - Add TODO: migrate remaining lucide-svelte → @lucide/svelte (5 files) then uninstall Co-Authored-By: Claude Sonnet 4.6 --- documentation/TODO__Agents.md | 10 + package-lock.json | 263 +--- package.json | 1 - src/lib/electron/electron_native.js | 1805 --------------------------- 4 files changed, 12 insertions(+), 2067 deletions(-) delete mode 100644 src/lib/electron/electron_native.js diff --git a/documentation/TODO__Agents.md b/documentation/TODO__Agents.md index 5831f7bb..7b8271e0 100644 --- a/documentation/TODO__Agents.md +++ b/documentation/TODO__Agents.md @@ -88,6 +88,16 @@ Documented in `GUIDE__SvelteKit2_Svelte5_DexieJS.md` (IDB Sort section). - [ ] **[Journals] Entry passcode secondary auth** — implement `passcode_hash` comparison. - [ ] **[Journals] Summary AI shortcut** — add button to modal. +### [Cleanup] Migrate remaining `lucide-svelte` imports to `@lucide/svelte` +5 files still import via `import * as Lucide from 'lucide-svelte'` (the old package name). +Migrate each to `@lucide/svelte`, then uninstall `lucide-svelte` from `package.json`. +Files: +- `src/lib/ae_core/ae_comp__hosted_files_download_button.svelte` +- `src/lib/ae_core/ae_comp__hosted_files_upload.svelte` +- `src/lib/ae_utils/ae_utils__file_extension_icon_lucide.ts` +- `src/routes/testing/hosted_files/+page.svelte` +- `src/routes/idaa/(idaa)/archives/[archive_id]/ae_idaa_comp__archive_content_obj_id_edit.svelte` + --- ### [Pres Mgmt] Sessions hide/show toggle diff --git a/package-lock.json b/package-lock.json index 5b57e0c5..fc019e90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "osit-aether-app-svelte", - "version": "3.00.10", + "version": "3.00.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "osit-aether-app-svelte", - "version": "3.00.10", + "version": "3.00.20", "dependencies": { "@codemirror/autocomplete": "^6.20.0", "@codemirror/commands": "^6.10.0", @@ -26,7 +26,6 @@ "@lucide/svelte": "^0.*.0", "@popperjs/core": "^2.11.0", "@tailwindcss/vite": "^4.1.10", - "axios": "^1.7.0", "dayjs": "^1.11.10", "dexie": "^4.0.0", "flowbite-svelte": "^1.28.1", @@ -3929,23 +3928,6 @@ "node": ">=12" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", - "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -3976,19 +3958,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4101,18 +4070,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -4240,15 +4197,6 @@ "node": ">=0.10.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -4299,20 +4247,6 @@ "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", "license": "MIT" }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -4332,24 +4266,6 @@ "node": ">=10.13.0" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/es-module-lexer": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", @@ -4357,33 +4273,6 @@ "dev": true, "license": "MIT" }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/esbuild": { "version": "0.27.3", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", @@ -4935,42 +4824,6 @@ "mini-svg-data-uri": "^1.4.3" } }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -5003,43 +4856,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5065,18 +4881,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -5092,33 +4896,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -5693,36 +5470,6 @@ "node": ">= 20" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mini-svg-data-uri": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", @@ -6317,12 +6064,6 @@ "dev": true, "license": "MIT" }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/package.json b/package.json index c6cfcf9f..492df5e1 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,6 @@ "@lucide/svelte": "^0.*.0", "@popperjs/core": "^2.11.0", "@tailwindcss/vite": "^4.1.10", - "axios": "^1.7.0", "dayjs": "^1.11.10", "dexie": "^4.0.0", "flowbite-svelte": "^1.28.1", diff --git a/src/lib/electron/electron_native.js b/src/lib/electron/electron_native.js deleted file mode 100644 index dfe27c6e..00000000 --- a/src/lib/electron/electron_native.js +++ /dev/null @@ -1,1805 +0,0 @@ -// [DEPRECATED] 2026-02-10: This file is a legacy reference from Aether V2/V4. -// Do NOT import this into the SvelteKit frontend. -// The active native logic resides in the 'aether_app_native_electron' repository. - -// @ts-nocheck -'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 app_root_path = path.join(home_directory, 'OSIT/native_app'); // macOS default - -let config = null; - -let default_osit_sync_app_root_relative_path = - 'OSIT/Speaker Ready System/Admin Share/Custom Applications'; // Mainly for macOS laptops -let default_osit_sync_app_root_path = path.join( - home_directory, - default_osit_sync_app_root_relative_path -); // macOS default -let default_osit_sync_native_app_relative_path = - 'OSIT/Speaker Ready System/Admin Share/Custom Applications/osit_binaries/osit_aether.current.app'; // Mainly for macOS laptops -let default_native_app_relative_path = 'OSIT/native_app/osit_aether.app'; // Mainly for macOS laptops -let default_current_native_app_relative_path = - 'OSIT/native_app/osit_aether.current.app'; // Mainly for macOS laptops -let test_native_app_relative_path = 'OSIT/native_app/osit_aether.remote.app'; // Mainly for macOS laptops - -// exports.check_for_native_app_update = function () { -// console.log('*** Aether App Native export: check_for_native_app_update() ***'); -// -// let config_directory = null; -// -// if (os.platform == 'darwin') { -// config_directory = path.join(home_directory, 'OSIT/native_app'); -// console.log('macOS config directory: '+config_directory); -// -// let electron_app_path = path.join(home_directory, default_native_app_relative_path); -// let test_stats = fs.statSync(electron_app_path); -// console.log(test_stats); -// -// if (test_stats.ctimeMs < 1684182140759) { -// console.log(`This may be an old version!`); -// } -// } else if (os.platform == 'linux') { -// config_directory = path.join(home_directory, '.config/OSIT'); -// console.log('Linux config directory: '+config_directory); -// } else { -// console.log('Unknown OS... Is this Windows?'); -// return false; -// } -// -// } - -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); - - let electron_app_path = path.join( - home_directory, - default_native_app_relative_path - ); - let test_stats = fs.statSync(electron_app_path); - console.log(test_stats); - } 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}` - ); - } - - // NOTE: This is not ideal... - if (!config.account_id) { - if ( - config.event_id == 'pjrcghqwert' || - config.event_id == 'nmBfuGFeR0k' - ) { - config.account_id = '_XY7DXtc9MY'; - } else if (config.event_id == 'r8c-rr-I4-52') { - // CMSC - config.account_id = '8Gfxbxr19Nw'; - } else if (config.event_id == 'NeC-hm-MF-Q3') { - // LCI - config.account_id = 'xFP7AhU8Zlc'; - } else if (config.event_id == 'Y7v-Zg-fe-gu') { - // NCSD - config.account_id = 'FrodrLD7B4w'; - } else if (config.event_id == '9jW-Db-SF-wt') { - // AAPOR - config.account_id = 'j5EBhRDqPuw'; - } else if (config.event_id == 'zJP-Ld-A7-I4') { - // BGH - config.account_id = 'GpLf_bnywCs'; - } else { - console.log( - 'WARNING WARNING WARNING: The account ID could not be guessed. Using the default of 1. <<< WARNING' - ); - config.account_id = '_XY7DXtc9MY'; - } - } - - 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 2023-05-26 -exports.download_hash_file_to_cache_v2 = async function ({ - api_base_url, - api_base_url_backup, - 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}; Base URL Backup: ${api_base_url_backup}; 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; - } - } - } - } - - const tmp_full_save_path = full_cached_hash_path + '.tmp'; - - if (fs.existsSync(tmp_full_save_path)) { - console.log(`A temp download file was found! ${tmp_full_save_path}`); - - let stats = null; - try { - stats = fs.statSync(tmp_full_save_path); - - // console.log(`File Accessed Last: ${stats.atime}`); // File data last changed (actual contents) - console.log(`File Data Last Modified: ${stats.mtime}`); // File data last changed (actual contents) - console.log(`File Metadata Last Modified: ${stats.ctime}`); // File metadata last changed (filename, permissions, etc) - } catch (error) { - console.log(error); - } - - let current_datetime = new Date(); - let offset_minutes = 3; // In minutes. 5 minutes of no changes to the file content seems reasonable? Trying with 3 minutes 2022-10-12 - let offset_datetime = new Date( - current_datetime.getTime() - offset_minutes * 60000 - ); - - // console.log(`Times: ${current_datetime} ${offset_datetime} | File ${stats.mtime}`); - if (stats.mtime < offset_datetime) { - // console.log(`Marking as expired temp file based on modified datetime. Expire after: ${offset_minutes} minutes`); - // overwrite_existing = true; - } else { - console.log( - `Temp download file has not expired yet. Expire after: ${offset_minutes} minutes` - ); - // return false; - return 'tmp'; - } - } - - console.log(`Trying IPC API download from: ${api_base_url}`); - let download_file_result = await ipcRenderer - .invoke( - 'download_file', - api_base_url, - endpoint, - full_cached_hash_path, - hash, - verify_hash, - overwrite_existing - ) - .then(async (result) => { - if (result) { - console.log( - `IPC API download file process finished successfully: ${hash}` - ); - return true; - } else if (result == null) { - console.log( - `IPC API download result (file not found?):`, - result - ); - return null; - } else if (result === 'in_progress') { - console.log(`IPC API primary download IN PROGRESS: ${hash}`); - // return false; // Should return result instead??? - return result; - } else if (result === 'tmp') { - console.log(`IPC API primary download FOUND TMP: ${hash}`); - // return false; // Should return result instead??? - return result; - } else { - console.log( - `IPC API download result (file being downloaded or something went wrong): ${hash}`, - result - ); - return false; - - // if (api_base_url_backup) { - // console.log(`Download FAILED! Trying again with backup API server. API Backup: ${api_base_url_backup}`); - // let download_backup_file_result = await ipcRenderer.invoke('download_file', api_base_url_backup, endpoint, full_cached_hash_path, hash, verify_hash, overwrite_existing).then((result_backup) => { - // if (result_backup) { - // console.log('IPC download file (from backup) process finished successfully'); - // return true; - // } else if (result_backup == null) { - // console.log('IPC Download Result (from backup) (file not found?):', result_backup); - // return null; - // } else { - // console.log('IPC Download Result (from backup) (file being downloaded or something went wrong):', result_backup); - // return false; - // } - // }); - // } else { - // return false; - // } - } - return true; - // }); - }) - .then(async (result) => { - if (result === false) { - console.log(`IPC API primary download FAILED!`); // Trying again with backup API server. API Backup: ${api_base_url_backup}`); - if (api_base_url_backup) { - console.log( - `IPC API primary download FAILED! Trying again with backup API server. API Backup: ${api_base_url_backup}` - ); - console.log( - `Trying IPC API backup download from: ${api_base_url_backup}` - ); - let download_backup_file_result = await ipcRenderer - .invoke( - 'download_file', - api_base_url_backup, - endpoint, - full_cached_hash_path, - hash, - verify_hash, - overwrite_existing - ) - .then((result_backup) => { - if (result_backup) { - console.log( - `IPC API backup download file (from backup) process finished successfully: ${hash}` - ); - return true; - } else if (result_backup == null) { - console.log( - 'IPC API backup download result (file not found?):', - result_backup - ); - return null; - } else { - console.log( - `IPC API backup download result (file being downloaded or something went wrong): ${hash}`, - result_backup - ); - return false; - } - }); - return download_backup_file_result; - } else { - console.log( - `IPC Download FAILED! No backup API server passed. Returning false.` - ); - return false; - } - } else if (result === 'in_progress') { - console.log(`IPC API primary download IN PROGRESS: ${hash}`); - return false; // Should return result instead??? - } else if (result === 'tmp') { - console.log(`IPC API primary download FOUND TMP: ${hash}`); - return false; // Should return result instead??? - } else { - return result; - } - }); - - // if (download_file_result === false) { - // console.log(`Download FAILED! Trying again with backup API server. API Backup: ${api_base_url_backup}`) - // download_file_result = await ipcRenderer.invoke('download_file', api_base_url_backup, endpoint, full_cached_hash_path, hash, verify_hash, overwrite_existing).then((result) => { - // if (result) { - // console.log('IPC download file (from backup) process finished successfully'); - // return true; - // } else if (result == null) { - // console.log('IPC Download Result (from backup) (file not found?):', result); - // return null; - // } else { - // console.log('IPC Download Result (from backup) (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: any) { -// // 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: any) { - // 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 2026-01-26 -exports.run_cmd = async function ({ - cmd = null, - return_stdout = null, - return_stdin = null, - sync = null -}) { - console.log('*** Electron framework export: run_cmd() ***'); - - // Resolve placeholders in the command string - let cleaned_cmd = cmd; - if (cmd && typeof cmd === 'string') { - cleaned_cmd = cmd - .replace(/\[home\]/g, home_directory) - .replace(/\[tmp\]/g, tmp_directory); - } - - console.log(`Command String: ${cleaned_cmd}`); - - let result; - - if (!sync) { - result = child_process.exec(cleaned_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(cleaned_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 2026-01-26 -exports.run_cmd_sync = function ({ - cmd = null, - return_stdout = null, - return_stdin = null -}) { - console.log('*** Electron framework export: run_cmd_sync() ***'); - - // Resolve placeholders in the command string - let cleaned_cmd = cmd; - if (cmd && typeof cmd === 'string') { - cleaned_cmd = cmd - .replace(/\[home\]/g, home_directory) - .replace(/\[tmp\]/g, tmp_directory); - } - - console.log(`Command String: ${cleaned_cmd}`); - - let stdout; - - try { - stdout = child_process.execSync(cleaned_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; - } -}; - -// Run raw command -// Updated 2026-01-26 -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(); - - // Add directory info for placeholder resolution in UI - data['home_directory'] = home_directory; - data['tmp_directory'] = tmp_directory; - - console.log(data); - return data; -}; - -/** - * Atomic Copy-and-Launch (Phase 2/5) - * Moves a file from the hashed cache to the operational temp directory - * and triggers the system launcher. - */ -exports.launch_from_cache = async function ({ - cache_root, - hash, - temp_root, - filename, - hash_prefix_length = 2 -}) { - console.log('*** Aether App Native export: launch_from_cache() ***'); - - // 1. Resolve Path Placeholders (using global regex) - const clean_cache_root = cache_root - .replace(/\[home\]/g, home_directory) - .replace(/\[tmp\]/g, tmp_directory); - const clean_temp_root = temp_root - .replace(/\[home\]/g, home_directory) - .replace(/\[tmp\]/g, tmp_directory); - - const hash_filename = `${hash}.file`; - const prefix = hash.substring(0, hash_prefix_length); - const source_path = path.join(clean_cache_root, prefix, hash_filename); - const dest_path = path.join(clean_temp_root, filename); - - console.log(`Source: ${source_path}`); - console.log(`Dest: ${dest_path}`); - - try { - // 2. Ensure temp directory exists - if (!fs.existsSync(clean_temp_root)) { - fs.mkdirSync(clean_temp_root, { recursive: true }); - } - - // 3. Verify Source - if (!fs.existsSync(source_path)) { - throw new Error(`Source file not found in cache: ${source_path}`); - } - - // 4. Perform atomic copy - fs.copyFileSync(source_path, dest_path); - console.log('File copied to temp successfully.'); - - // 5. Trigger Specialized Launcher (if presentation) - const ext = path.extname(filename).toLowerCase().replace('.', ''); - const is_pres = ['pptx', 'ppt', 'key', 'pdf', 'odp'].includes(ext); - - if (is_pres) { - return await exports.launch_presentation({ - path: dest_path, - app: ext === 'key' ? 'keynote' : 'default' - }); - } - - // 6. Default Fallback - return await ipcRenderer.invoke('open_local_file', '', dest_path); - } catch (err) { - console.error('Launch Error:', err); - return { success: false, error: err.message }; - } -}; - -/** - * Specialized Presentation Launcher (Phase 5) - * Handles platform-specific application selection (LibreOffice on Linux, - * PowerPoint/Keynote on macOS). - * Updated 2026-01-26 - */ -exports.launch_presentation = async function ({ - path: raw_path, - app = 'default', - os_platform = 'auto' -}) { - console.log('*** Aether App Native export: launch_presentation() ***'); - - // Resolve placeholders if they exist in the incoming path (using global regex) - let cleaned_path = raw_path - .replace(/\[home\]/g, home_directory) - .replace(/\[tmp\]/g, tmp_directory); - - console.log( - `Raw Path: ${raw_path}; Cleaned Path: ${cleaned_path}; App: ${app}; OS: ${os_platform}` - ); - - // 1. Detect OS - let platform = os_platform; - if (platform === 'auto') { - platform = os.platform(); - } - - // 2. Handle Linux (LibreOffice Testing) - if (platform === 'linux') { - console.log( - `Native: Launching LibreOffice on Linux for path: ${cleaned_path}` - ); - const cmd = `libreoffice --impress "${cleaned_path}"`; - - return new Promise((resolve) => { - child_process.exec(cmd, (err, stdout, stderr) => { - if (err) { - console.error('LibreOffice Launch Error:', err); - resolve({ success: false, error: err.message }); - } else { - resolve({ success: true, stdout, stderr }); - } - }); - }); - } - - // 3. Handle macOS (Production) - if (platform === 'darwin') { - if (app === 'keynote') { - const script = `tell application "Keynote" to open POSIX file "${cleaned_path}"`; - return exports.run_osascript({ cmd: script }); - } - - // Default to shell open - return ipcRenderer.invoke('open_local_file', '', cleaned_path); - } - - // 4. Default Fallback (Windows/Others) - return ipcRenderer.invoke('open_local_file', '', cleaned_path); -}; - -// 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'; -} - -exports.check_and_get_updated_native_app_config = function ({ - file_path = 'device_configs/ae_native_app_config.default.json', - overwrite = false -}) { - console.log( - '*** Aether App Native export: check_and_get_updated_native_app_config() ***' - ); - - if (os.platform == 'darwin') { - let default_osit_sync_app_config_path = path.join( - default_osit_sync_app_root_path, - file_path - ); - - let default_app_config_path = path.join( - app_root_path, - 'ae_native_app_config.default.json' - ); - console.log( - 'macOS app root and config directory: ' + default_app_config_path - ); - - fs.copyFileSync( - default_osit_sync_app_config_path, - default_app_config_path - ); - - if (overwrite) { - console.log('Overwriting the current active config file...'); - let active_app_config_path = path.join( - app_root_path, - 'ae_native_app_config.json' - ); - console.log( - 'macOS app root and config directory: ' + active_app_config_path - ); - - fs.copyFileSync( - default_osit_sync_app_config_path, - active_app_config_path - ); - } - } else if (os.platform == 'linux') { - app_root_path = path.join(home_directory, '.config/OSIT'); - console.log('Linux config directory: ' + app_root_path); - return false; - } else { - console.log('Unknown OS... Is this Windows?'); - return false; - } - - return true; -};