Documented manager code

This commit is contained in:
Pax1601
2024-01-03 15:08:06 +01:00
parent 7bf6c1bb23
commit a0634a7f99
11 changed files with 263 additions and 82 deletions

View File

@@ -13,6 +13,7 @@ const { Octokit } = require('octokit');
const VERSION = "{{OLYMPUS_VERSION_NUMBER}}";
function checkVersion() {
/* Check if we are running the latest version */
const request = new Request("https://raw.githubusercontent.com/Pax1601/DCSOlympus/main/version.json");
fetch(request).then((response) => {
@@ -22,12 +23,15 @@ function checkVersion() {
throw new Error("Error connecting to Github to retrieve latest version");
}
}).then((res) => {
/* If we are running a development version of the script (not from a compiled package), skip version checking */
if (VERSION.includes("OLYMPUS_VERSION_NUMBER")) {
console.log("Development build detected, skipping version checks...")
} else {
/* Check if there is a newer version available */
var reg1 = res["version"].match(/\d+/g).map((str) => { return Number(str) });
var reg2 = VERSION.match(/\d+/g).map((str) => { return Number(str) });
/* If a newer version is available update Olympus in Release mode */
if (reg1[0] > reg2[0] || (reg1[0] == reg2[0] && reg1[1] > reg2[1]) || (reg1[0] == reg2[0] && reg1[1] == reg2[1] && reg1[2] > reg2[2])) {
console.log(`New version available: ${res["version"]}`);
showConfirmPopup(`You are currently running DCS Olympus ${VERSION}, but ${res["version"]} is available. Do you want to update DCS Olympus automatically? <div style="max-width: 100%; color: orange">Note: DCS and Olympus MUST be stopped before proceeding.</div>`,
@@ -37,6 +41,7 @@ function checkVersion() {
console.log("Update canceled");
})
}
/* If the current version is newer than the latest release, the user is probably a developer. Ask for a beta update */
else if (reg2[0] > reg1[0] || (reg2[0] == reg1[0] && reg2[1] > reg1[1]) || (reg2[0] == reg1[0] && reg2[1] == reg1[1] && reg2[2] > reg1[2])) {
console.log(`Beta version detected: ${res["version"]}`);
showConfirmPopup(`You are currently running DCS Olympus ${VERSION}, which is newer than the latest release version. Do you want to download the latest beta version? <div style="max-width: 100%; color: orange">Note: DCS and Olympus MUST be stopped before proceeding.</div>`,
@@ -50,9 +55,12 @@ function checkVersion() {
})
}
/** Update Olympus in "beta" mode. The user will be provided with the option to update from a build artifact
*
*/
async function updateOlympusBeta() {
/* Get a list of build artifacts */
const octokit = new Octokit({});
const res = await octokit.request('GET /repos/{owner}/{repo}/actions/artifacts', {
owner: 'Pax1601',
repo: 'DCSOlympus',
@@ -60,19 +68,22 @@ async function updateOlympusBeta() {
'X-GitHub-Api-Version': '2022-11-28'
}
});
const artifacts = res.data.artifacts;
/* Select the newest artifact */
var artifact = artifacts.find((artifact) => { return artifact.name = "development_build_not_a_release" });
showConfirmPopup(`Latest beta artifact has a timestamp of ${artifact.updated_at}. Do you want to continue?`, () => {
/* Run the browser and download the artifact */ //TODO: try and directly download the file from code rather than using the browser
exec(`start https://github.com/Pax1601/DCSOlympus/actions/runs/${artifact.workflow_run.id}/artifacts/${artifact.id}`)
showConfirmPopup('A browser window was opened to download the beta artifact. Please wait for the download to complete, then press "Accept" and select the downloaded beta artifact.',
() => {
/* Ask the user to select the downloaded file */
var input = document.createElement('input');
input.type = 'file';
input.click();
input.onchange = e => {
console.log(e.target.files[0]);
/* Run the update process */
updateOlympus(e.target.files[0])
}
},
@@ -85,6 +96,9 @@ async function updateOlympusBeta() {
})
}
/** Update Olympus to the lastest release
*
*/
async function updateOlympusRelease() {
const octokit = new Octokit({})
@@ -96,11 +110,14 @@ async function updateOlympusRelease() {
}
})
/* Run the update process */
updateOlympus(res.data.assets[0].browser_download_url)
}
function updateOlympus(location) {
showWaitPopup("Please wait while Olympus is being updated. The Manager will be closed and reopened automatically when updating is completed.")
/* If the location is a string, it is interpreted as a download url. Else, it is interpreted as a File (on disk)*/
if (typeof location === "string") {
console.log(`Updating Olympus with package from ${location}`)
} else {
@@ -110,20 +127,24 @@ function updateOlympus(location) {
let tmpDir;
const appPrefix = 'dcs-olympus-';
try {
/* Create a temporary folder */
const folder = path.join(os.tmpdir(), appPrefix);
tmpDir = fs.mkdtempSync(folder);
if (typeof location === "string") {
/* Download the file */
const file = fs.createWriteStream(path.join(tmpDir, "temp.zip"));
console.log(`Downloading update package in ${path.join(tmpDir, "temp.zip")}`)
const request = https.get(location, (response) => {
if (response.statusCode === 200) {
response.pipe(file);
// after download completed close filestream
/* Either on success or on error close the file stream */
file.on("finish", () => {
file.close();
console.log("Download completed");
/* Extract and copy the files */
extractAndCopy(tmpDir);
});
file.on("error", (err) => {
@@ -137,16 +158,47 @@ function updateOlympus(location) {
}
});
} else {
/* Copy the archive to the temporary folder */
fs.copyFileSync(location.path, path.join(tmpDir, "temp.zip"));
/* Extract and copy the files */
extractAndCopy(tmpDir);
}
}
catch (err) {
/* Show the failed update message */
failUpdate();
console.error(err)
}
}
/** Extract the contents of the zip and update Olympus by deleting all files from the current installation and copying the new files over.
*
*/
function extractAndCopy(folder) {
/* Extract all the files */
const zip = new AdmZip(path.join(folder, "temp.zip"));
zip.extractAllTo(path.join(folder, "temp"));
/* Create a batch file that:
1) waits for 5 seconds to allow the old process to close;
2) deletes the existing installation;
3) copies the new installation;
4) cds into the new installation;
5) runs the install.bat script */
fs.writeFileSync(path.join(folder, 'update.bat'),
`timeout /t 5 \nrmdir "${path.join(__dirname, "..", "..")}" /s /q \necho D|xcopy /Y /S /E "${path.join(folder, "temp")}" "${path.join(__dirname, "..", "..")}" \ncd "${path.join(__dirname, "..", "..")}" \ninstall.bat`
)
/* Launch the update script then close gracefully */
var proc = spawn('cmd.exe', ["/c", path.join(folder, 'update.bat')], { cwd: folder, shell: true, detached: true });
proc.unref();
ipcRenderer.send('window:close');
}
/** Something went wrong. Tell the user to update manually.
*
*/
function failUpdate() {
showErrorPopup("An error has occurred while updating Olympus. Please delete Olympus and update it manually. A browser window will open automatically on the download page.", () => {
exec(`start https://github.com/Pax1601/DCSOlympus/releases`, () => {
@@ -155,19 +207,6 @@ function failUpdate() {
})
}
function extractAndCopy(folder) {
const zip = new AdmZip(path.join(folder, "temp.zip"));
zip.extractAllTo(path.join(folder, "temp"));
fs.writeFileSync(path.join(folder, 'update.bat'),
`timeout /t 5 \nrmdir "${path.join(__dirname, "..", "..")}" /s /q \necho D|xcopy /Y /S /E "${path.join(folder, "temp")}" "${path.join(__dirname, "..", "..")}" \ncd "${path.join(__dirname, "..", "..")}" \ninstall.bat`
)
var proc = spawn('cmd.exe', ["/c", path.join(folder, 'update.bat')], { cwd: folder, shell: true, detached: true });
proc.unref();
ipcRenderer.send('window:close');
}
/* White-listed channels. */
const ipc = {
'render': {
@@ -216,15 +255,22 @@ contextBridge.exposeInMainWorld(
}
});
/* New instance of the manager app */
const manager = new Manager();
/* On content loaded */
window.addEventListener('DOMContentLoaded', async () => {
/* Check if a new version is available */
checkVersion();
/* Compute the height of the content page */
computePagesHeight();
document.getElementById("loader").classList.remove("hide");
await manager.start();
/* Compute the height of the content page to account for the pages created by the manager*/
computePagesHeight();
/* Create event listeners for the hyperlinks */
var links = document.querySelectorAll(".link");
for (let i = 0; i < links.length; i++) {
links[i].addEventListener("click", (e) => {
@@ -233,11 +279,13 @@ window.addEventListener('DOMContentLoaded', async () => {
}
})
checkVersion();
window.addEventListener('resize', () => {
computePagesHeight();
})
/** Computes the height of the content area
*
*/
function computePagesHeight() {
var pages = document.querySelectorAll(".manager-page");
var titleBar = document.querySelector("#title-bar");