Skip to content
Snippets Groups Projects
main.js 6.22 KiB
Newer Older
const fs = require('fs');
const {spawn} = require('child_process');

DFN2's avatar
DFN2 committed
const {app, BrowserWindow, ipcMain} = require('electron');
const ElectronStore = require('electron-store');
const request = require('request');

const appPackage = require('../package.json');
const appConfig = require('./configs/application.json');
const ocsManagerConfig = require('./configs/ocs-manager.json');

const isDebugMode = process.argv.includes('--debug');
const previewpicDirectory = `${app.getPath('userData')}/previewpic`;
DFN2's avatar
DFN2 committed
const windowIcon = `${__dirname}/images/app-icons/pling-store.png`;
DFN2's avatar
DFN2 committed
const indexFileUrl = `file://${__dirname}/index.html`;
const appConfigStoreStorage = 'application';

let mainWindow = null;
let ocsManager = null;
let ocsManagerUrl = '';

async function startOcsManager() {
    return new Promise((resolve) => {
        const resolveOcsManagerUrl = (data) => {
            const matches = data.toString().match(/Websocket server started at: "(wss?:\/\/.+)"/);
            if (matches) {
                ocsManagerUrl = matches[1];
                resolve(true);
            }
        };

        ocsManager = spawn(ocsManagerConfig.bin, ['-p', ocsManagerConfig.port]);

        ocsManager.stdout.on('data', (data) => {
            console.log(`[${ocsManagerConfig.bin}] ${data}`);
            if (!ocsManagerUrl) {
                resolveOcsManagerUrl(data);
            }
        });

        ocsManager.stderr.on('data', (data) => {
            console.error(`[${ocsManagerConfig.bin}] ${data}`);
            if (!ocsManagerUrl) {
                resolveOcsManagerUrl(data);
            }
        });

        ocsManager.on('close', (code) => {
            console.log(`${ocsManagerConfig.bin} exited with code ${code}`);
        });

        ocsManager.on('error', () => {
            console.error(`Failed to start ${ocsManagerConfig.bin}`);
            resolve(false);
        });
    });
}

function stopOcsManager() {
    if (ocsManager) {
        ocsManager.kill();
        ocsManagerUrl = '';
    }
}

function createWindow() {
    const appConfigStore = new ElectronStore({
        name: appConfigStoreStorage,
        defaults: appConfig.defaults
    });

    const windowBounds = appConfigStore.get('windowBounds');

    mainWindow = new BrowserWindow({
        title: appPackage.productName,
        icon: windowIcon,
azubieta's avatar
azubieta committed
        x: windowBounds.x,
        y: windowBounds.y,
        width: windowBounds.width,
        height: windowBounds.height,
        webPreferences: {
            nodeIntegration: true
        }
    });

DFN2's avatar
DFN2 committed
    if (!isDebugMode) {
        mainWindow.setMenu(null);
    }

    mainWindow.loadURL(indexFileUrl);
DFN2's avatar
DFN2 committed
    mainWindow.maximize();
    mainWindow.on('close', () => {
        const appConfigStore = new ElectronStore({name: appConfigStoreStorage});
        appConfigStore.set('windowBounds', mainWindow.getBounds());
    });

    mainWindow.on('closed', () => {
        mainWindow = null;
    });

    if (isDebugMode) {
DFN2's avatar
DFN2 committed
        mainWindow.webContents.openDevTools();
    }
}

function isFile(path) {
    try {
        const stats = fs.statSync(path);
        return stats.isFile();
    } catch (error) {
        console.error(error);
        return false;
    }
}

function isDirectory(path) {
    try {
        const stats = fs.statSync(path);
        return stats.isDirectory();
    } catch (error) {
        console.error(error);
        return false;
    }
}

function btoa(string) {
    const buffer = (string instanceof Buffer) ? string : Buffer.from(string.toString(), 'binary');
    return buffer.toString('base64');
}

//function atob(string) {
//    return Buffer.from(string, 'base64').toString('binary');
//}

function previewpicFilename(itemKey) {
    // "itemKey" will be URL to product file
    return btoa(itemKey).slice(-255);
}

DFN2's avatar
DFN2 committed
function downloadPreviewpic(itemKey, url) {
    if (!isDirectory(previewpicDirectory)) {
        fs.mkdirSync(previewpicDirectory);
    }
    const path = `${previewpicDirectory}/${previewpicFilename(itemKey)}`;
    request.get(url).on('error', (error) => {
        console.error(error);
    }).pipe(fs.createWriteStream(path));
}

function removePreviewpic(itemKey) {
    const path = `${previewpicDirectory}/${previewpicFilename(itemKey)}`;
    if (isFile(path)) {
        fs.unlinkSync(path);
    }
}

app.on('ready', async () => {
    if (await startOcsManager()) {
        createWindow();
        app.quit();
    }
});

app.on('quit', () => {
    stopOcsManager();
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('activate', () => {
    if (mainWindow === null) {
        createWindow();
    }
});

DFN2's avatar
DFN2 committed
app.on('web-contents-created', (event, webContents) => {
    if (webContents.getType() === 'webview') {
        webContents.on('will-navigate', (event, url) => {
            if (url.startsWith('ocs://') || url.startsWith('ocss://')) {
                // Cancel ocs protocol navigation
                event.preventDefault();
            }
        });
    }
DFN2's avatar
DFN2 committed
});
// Set configs dir
app.setPath("userData", app.getPath("appData") + "/OCS-Store")

ipcMain.on('app', (event, key) => {
    const data = {
        package: appPackage,
        config: appConfig,
        isDebugMode: isDebugMode
    };
    event.returnValue = key ? data[key] : data;
});

ipcMain.on('ocs-manager', (event, key) => {
    const data = {
        config: ocsManagerConfig,
        url: ocsManagerUrl
    };
    event.returnValue = key ? data[key] : data;
});

ipcMain.on('store', (event, key, value) => {
    const appConfigStore = new ElectronStore({name: appConfigStoreStorage});
    if (key && value) {
        appConfigStore.set(key, value);
    }
    event.returnValue = key ? appConfigStore.get(key) : appConfigStore.store;
});

ipcMain.on('previewpic', (event, kind, itemKey, url) => {
    if (kind === 'directory') {
        event.returnValue = previewpicDirectory;
    } else if (kind === 'path' && itemKey) {
        event.returnValue = `${previewpicDirectory}/${previewpicFilename(itemKey)}`;
    } else if (kind === 'download' && itemKey && url) {
        downloadPreviewpic(itemKey, url);
        event.returnValue = undefined;
    } else if (kind === 'remove' && itemKey) {
        removePreviewpic(itemKey);
        event.returnValue = undefined;
        event.returnValue = false;
    }
});