Skip to content
Extraits de code Groupes Projets
main.js 10,30 Kio
const logger = require.main.require('./common/logger.js'),
    electron = require('electron'),
    { app, BrowserWindow, globalShortcut, ipcMain } = require('electron'),
    { fork, spawn } = require('child_process'),
    fs = require('fs'),
    lkt = require.main.require('./common/lkt.js'),
    isRunning = require('./common/isRunning.js');

let electronEjs = require('electron-ejs');
let ejs = new electronEjs({ app: 'Amadeus' }, {});

const packageConfig = require('./package.json').config;
logger.debug('main', 'Package config is ' + JSON.stringify(packageConfig));

var config = require('./common/config.js');
var db = require.main.require('./common/db.js');
var tail = require('tail').Tail;

var client; /* Sub process for the express server */

class Lektor {
    constructor() {
        this.closed = true;
        isRunning({ win: 'lektord.exe', linux: 'lektord', mac: 'lektord' }).then(v => {
            if (v && config.attachmode) {
                logger.info('main', `Lektord is running! Attach to it`);
            } else if (v) {
                logger.error('error', `Lektord is running and attach mode is disable, exit!`);
                app.quit();
            } else {
                logger.debug('main', `Lektord not running, start it!`);
                this.closed = false;
                this.process = spawn('lektord', ['-F']);
                this.process.stderr.on('data', data => {
                    logger.lektord(data);
                });
                this.process.on('close', code => {
                    logger.warn('main', `Lektor exited with code ${code}`);
                    this.lektor_closed = true;
                    app.quit();
                });
            }
        });
    }

    exit() {
        if (this.closed) {
            logger.warning('main', 'Lektord is already closed');
            return;
        }
        logger.info('main', 'Closing lektord');
        this.closed = true;
        this.process.kill('SIGTERM');
    }
}

/* The last thing we got from the search bar */
var __lastFilter = '';

var win = null; /* The main window */

/**********************
 * Reinit the logfile *
 **********************/

fs.truncate(logger.logfile, 0, () => {});
var tail = new tail(logger.logfile);
tail.on('line', function (data) {
    console.log(data);
});

/***************************************************************
 * Creates the main window and process for the admin interface *
 ***************************************************************/

function createInstanceWindow() {
    /* Main window */
    win = new BrowserWindow({
        width: 1280,
        height: 720,
        minWidth: 1000,
        minHeight: 360,
        hasShadow: false,
        frame: false,
        menuBarVisible: true,
        webPreferences: {
            nodeIntegration: true,
            worldSafeExecuteJavaScript: true,
            contextIsolation: false /* XXX: Otherwise 'require' is not defined in instance/index.html */,
        },
    });
    win.loadURL(`file://${__dirname}/instance/index.ejs`);
    // win.loadFile('instance/index.html');
}

function createUserViewWindow() {
    /* User view window */
    const uv = new BrowserWindow({
        width: 720,
        title: 'Kurisu',
        height: 360,
        frame: false,
        parent: win,
        webPreferences: {
            nodeIntegration: true,
            worldSafeExecuteJavaScript: true,
            contextIsolation: true,
        },
    });
    uv.loadURL(`http://localhost:${config.clientport}/`);
    uv.once('ready-to-show', () => {
        uv.show();
    });
}

function createKurisuWindow() {
    /* Kurisu window */
    const kurisu = new BrowserWindow({
        width: 1280,
        title: 'Kurisu',
        height: 720,
        frame: false,
        parent: win,
        webPreferences: {
            nodeIntegration: true,
            worldSafeExecuteJavaScript: true,
            contextIsolation: true,
        },
    });
    kurisu.loadURL(config.kurisuurl);
    kurisu.once('ready-to-show', () => {
        kurisu.show();
    });
}

/******************************
 * The end of the application *
 ******************************/

ipcMain.on('close-app', (evt, arg) => {
    app.quit();
});

app.on('quit', () => {
    logger.info('main', 'Send SIGTERM to express process, lektord and tailler process');
    client.kill('SIGTERM');
    lektor.exit();
});

/*********************************
 * The beggin of the application *
 *********************************/

app.on('ready', () => {
    logger.info('main', 'Main window is ready');
    createInstanceWindow();
    client = fork('client/main.js');
    lektor = new Lektor();

    globalShortcut.register('CommandOrControl+D', () => {
        var win = BrowserWindow.getFocusedWindow();
        if (win === null) {
            return;
        }
        logger.info('main', 'Reloading DB');
        let contents = win.webContents;
        db.all().then(karas => {
            contents.send('reload-db-responce', karas);
        });
    });
    globalShortcut.register('F12', () => {
        var focused = BrowserWindow.getFocusedWindow();
        if (focused) {
            focused.webContents.openDevTools();
        }
    });

    setTimeout(() => {
        lkt.idleActualisation();
    }, 1000);
    setTimeout(() => {
        lkt.statusActualisation();
    }, 1500);
});

/***************
 * Kurisu View *
 ***************/

ipcMain.on('toggle-kurisu', (event, arg) => {
    logger.debug('main', 'Open kurisu view');
    createKurisuWindow();
});

ipcMain.on('toggle-client-view', (event, arg) => {
    logger.debug('main', 'Open client view');
    createUserViewWindow();
});

/*********************************
 * Messages from the main window *
 *********************************/

var songTimeData = { elapsed: 0, total: 100, state: 'stop', song: '0' };
var counterTime = 0;

ipcMain.on('cmd-play', (event, arg) => {
    lkt.commandPlay().then(arg => {
        logger.debug('main', 'Returned from cmd-play');
    });
});
ipcMain.on('cmd-stop', (event, arg) => {
    lkt.commandStop().then(arg => {
        logger.debug('main', 'Returned from cmd-stop');
    });
});
ipcMain.on('cmd-clear', (event, arg) => {
    lkt.commandClear().then(arg => {
        logger.debug('main', 'Cleared queue with cmd-clear');
    });
});

/* Fill the pannel with the content of the DB.
 * The `arg` is the HTML object of the pannel */
ipcMain.on('reload-db-request', (event, arg) => {
    logger.info('main', 'Reloading the DB content');
    var callback = karas => {
        event.reply('reload-db-responce', karas);
    };
    if (arg && (arg.search || arg.search == '')) {
        __lastFilter = arg.search;
        logger.debug('main', `Reload DB with search '${arg}'`);
        db.search(__lastFilter, 0, 100).then(callback);
    } else {
        logger.debug('main', `Reload DB with last filter '${__lastFilter}'`);
        db.search(__lastFilter, 0, 100).then(callback);
    }
});

/* Send the queue to the webpage when asked to */
ipcMain.on('reload-queue-request', (event, arg) => {
    logger.info('main', 'Reloading next karas in queue');
    db.queueAll().then(karas => {
        event.reply('reload-queue-responce', karas);
    });
});

ipcMain.on('verify-queue-reloaded-request', (event, arg) => {
    if (lkt.isQueueUpdated()) {
        lkt.setQueueUpdated(false);
        db.queueAll().then(karas => {
            event.reply('reload-queue-responce', karas);
        });
    }
});

ipcMain.on('queue-moved-kara', (event, movement) => {
    if (movement.to != movement.from) {
        lkt.commandMove(movement.from, movement.to);
    }
});

ipcMain.on('play-kara-queue-pos', (event, arg) => {
    lkt.commandPlayPos(arg.position);
});

ipcMain.on('add-kara-queue-id', (event, arg) => {
    lkt.commandQueueAddId(arg.id);
});

ipcMain.on('insert-kara-queue-id', (event, arg) => {
    lkt.commandQueueInsertId(arg.id);
});

ipcMain.on('delete-kara-queue-pos', (event, arg) => {
    lkt.commandQueueDelPos(arg.position);
});

ipcMain.on('add-kara-queue-pos', (event, addparams) => {
    lkt.commandQueueAddId(addparams.id).then(() => lkt.commandMove(addparams.queueSize + 1, addparams.position));
});

ipcMain.on('verify-state', (event, arg) => {
    if (lkt.isStatusUpdated()) {
        event.reply('send-state', lkt.getStatus().state);
    }
});

ipcMain.on('verify-lektord', (event, arg) => {
    lkt.ping().then(data => {
        lkt.reloadState();
        event.reply('send-lektord');
    });
});

ipcMain.on('get-song-time-data', (event, arg) => {
    var newSongTimeData = lkt.getSongTimeData();
    if (newSongTimeData.elapsed != songTimeData.elapsed || newSongTimeData.song != songTimeData.song) {
        songTimeData = newSongTimeData;
        event.reply('send-song-time-data', {
            elapsed: songTimeData.elapsed,
            total: songTimeData.total,
            song: songTimeData.song,
            state: songTimeData.state,
        });
        counterTime = 0;
    } else if (newSongTimeData.state == 'play') {
        counterTime++;
        event.reply('send-song-time-data', {
            elapsed: songTimeData.elapsed + counterTime / 20.0,
            total: songTimeData.total,
            song: songTimeData.song,
            state: songTimeData.state,
        });
    } else {
        event.reply('send-song-time-data', {
            elapsed: songTimeData.elapsed + counterTime / 20.0,
            total: songTimeData.total,
            song: songTimeData.song,
            state: songTimeData.state,
        });
    }
});

ipcMain.on('get-runnings', (event, arg) => {
    isRunning({ win: 'klkt.exe', mac: 'klkt', linux: 'klkt' }).then(vklkt => {
        isRunning({ win: 'lektord.exe', mac: 'lektord', linux: 'lektord' }).then(vlektord => {
            event.reply('send-runnings', {
                klkt: vklkt,
                lektord: vlektord,
            });
        });
    });
});

ipcMain.on('set-settings', (event, arg) => {
    logger.info('main', `Settings are now: ${JSON.stringify(arg)}`);
    config.host = arg.host;
    config.port = arg.port;
    config.database = arg.db;
    config.loglektord = arg.loglektord;
    config.attachmode = arg.attachmode;
    config.kurisuurl = arg.kurisuurl;
    config.clientport = arg.clientport;

    /* prettier-ignore */
    config.loglevel = arg.loglevel.ERROR   ? 'error'
                    : arg.loglevel.WARNING ? 'warning'
                    : arg.loglevel.INFO    ? 'info'
                    :                        'debug';

    config.flush();
});