compiled cxfreeze python app working inside electron with logging passed to web browser console
This commit is contained in:
BIN
electron/build/icon.png
Normal file
BIN
electron/build/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
@@ -2,45 +2,87 @@ const { app, BrowserWindow } = require('electron');
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('node:path');
|
||||
|
||||
// remember child process for exe so when can kill it when app exits
|
||||
// remember main window
|
||||
var mainWindow = null;
|
||||
|
||||
// remember child process for exe so we can kill it when app exits
|
||||
var exeChildProcess = null;
|
||||
|
||||
function log(message) {
|
||||
|
||||
// make sure main window exists
|
||||
if(!mainWindow){
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure window is not destroyed
|
||||
if(mainWindow.isDestroyed()){
|
||||
return;
|
||||
}
|
||||
|
||||
// log to electron console
|
||||
console.log(message);
|
||||
|
||||
// log to web console
|
||||
mainWindow.webContents.send('log', message);
|
||||
|
||||
}
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
|
||||
// create browser window
|
||||
const win = new BrowserWindow({
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1024,
|
||||
height: 768,
|
||||
})
|
||||
webPreferences: {
|
||||
// used to inject logging over ipc
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
},
|
||||
});
|
||||
|
||||
// open dev tools
|
||||
mainWindow.webContents.openDevTools();
|
||||
|
||||
// navigate to loading page
|
||||
await win.loadFile(path.join(__dirname, 'loading.html'));
|
||||
await mainWindow.loadFile(path.join(__dirname, 'loading.html'));
|
||||
|
||||
// find path to reticulum webchat python/cxfreexe executable
|
||||
const exe = path.join(__dirname, '..', 'build/exe.macosx-12.4-x86_64-3.11/ReticulumWebChat');
|
||||
// find path to python/cxfreeze reticulum webchat executable
|
||||
const exe = path.join(__dirname, 'build/exe/ReticulumWebChat');
|
||||
|
||||
// spawn exe
|
||||
exeChildProcess = spawn(exe, [
|
||||
'--headless',
|
||||
'--port', '9337', // FIXME: let system pick a random unused port?
|
||||
]);
|
||||
try {
|
||||
|
||||
// listen to stdout
|
||||
exeChildProcess.stdout.setEncoding('utf8');
|
||||
exeChildProcess.stdout.on('data', function(data) {
|
||||
console.log('stdout: ' + data);
|
||||
});
|
||||
// spawn executable
|
||||
exeChildProcess = await spawn(exe, [
|
||||
'--headless', // reticulum webchat usually launches default web browser, we don't want this when using electron
|
||||
'--port', '9337', // FIXME: let system pick a random unused port?
|
||||
'--storage-dir', path.join(app.getPath('home'), '.reticulum-webchat'), // ~/.reticulum-webchat
|
||||
]);
|
||||
|
||||
// listen to stderror
|
||||
exeChildProcess.stderr.setEncoding('utf8');
|
||||
exeChildProcess.stderr.on('data', function(data) {
|
||||
console.log('stderr: ' + data);
|
||||
});
|
||||
// log stdout
|
||||
exeChildProcess.stdout.setEncoding('utf8');
|
||||
exeChildProcess.stdout.on('data', function(data) {
|
||||
log(data.toString());
|
||||
});
|
||||
|
||||
// listen to process exit
|
||||
exeChildProcess.on('exit', function(code) {
|
||||
console.log("exit: " + code);
|
||||
});
|
||||
// log stderr
|
||||
exeChildProcess.stderr.setEncoding('utf8');
|
||||
exeChildProcess.stderr.on('data', function(data) {
|
||||
log(data.toString());
|
||||
});
|
||||
|
||||
// log errors
|
||||
exeChildProcess.on('error', function(error) {
|
||||
log(error);
|
||||
});
|
||||
|
||||
// quit electron app if exe dies
|
||||
exeChildProcess.on('exit', function(code) {
|
||||
quit();
|
||||
});
|
||||
|
||||
} catch(e) {
|
||||
log(e);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -56,6 +98,7 @@ function quit() {
|
||||
|
||||
}
|
||||
|
||||
// quit electron if all windows are closed
|
||||
app.on('window-all-closed', () => {
|
||||
quit();
|
||||
});
|
||||
|
||||
4
electron/preload.js
Normal file
4
electron/preload.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
// forward logs received from exe to web console
|
||||
ipcRenderer.on('log', (event, message) => console.log(message));
|
||||
2847
package-lock.json
generated
2847
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@@ -3,12 +3,32 @@
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "electron/main.js",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "electron ."
|
||||
"start": "electron .",
|
||||
"dist": "python setup.py build && electron-builder"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"electron": "^30.0.8"
|
||||
"electron": "^30.0.8",
|
||||
"electron-builder": "^24.13.3"
|
||||
},
|
||||
"build": {
|
||||
"appId": "com.liamcottle.reticulumwebchat",
|
||||
"asar": false,
|
||||
"files": [
|
||||
"electron/**/*"
|
||||
],
|
||||
"directories": {
|
||||
"buildResources": "electron/build"
|
||||
},
|
||||
"extraFiles": [
|
||||
{
|
||||
"from": "build/exe",
|
||||
"to": "Resources/app/electron/build/exe",
|
||||
"filter": ["**/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
2
setup.py
2
setup.py
@@ -36,6 +36,8 @@ setup(
|
||||
# it also prevents assert statements from executing, removes docstrings and sets __debug__ to False.
|
||||
# https://stackoverflow.com/a/57948104
|
||||
"optimize": 2,
|
||||
# change where exe is built to
|
||||
'build_exe': 'build/exe',
|
||||
},
|
||||
'build_msi': {
|
||||
# use a static upgrade code to allow installer to remove existing files on upgrade
|
||||
|
||||
Reference in New Issue
Block a user