diff --git a/common/config.js b/common/config.js index 2a3552431d3018e76cbb43f256584aa408302125..de3ac116d6cc15759e98dc5f1274a91daaa91b87 100644 --- a/common/config.js +++ b/common/config.js @@ -6,6 +6,7 @@ const packageConfig = require('../package.json').config; const __configDir = `${os.homedir()}/.config/lektor`; const __configFile = `${__configDir}/amadeus.ini`; +const __configLektord = `${__configDir}/lektor.ini`; fs.mkdirSync(__configDir, { recursive: true }); __dir = fs.opendirSync(__configDir); @@ -14,68 +15,33 @@ __dir.close(err => { }); var config = { - database: null, - host: null, - port: null, - loglevel: null, - loglektord: null, - attachmode: null, - clientport: null, + content: null, reload() { var fd = fs.openSync(__configFile, 'a'); fs.close(fd, err => {}); - var __config = ini.parse(fs.readFileSync(__configFile, 'utf-8')); + this.content = ini.parse(fs.readFileSync(__configFile, 'utf-8')); - __config.database ??= {}; - __config.lektord ??= {}; - __config.kurisu ??= {}; - __config.client ??= {}; - __config.log ??= {}; + this.content.database ??= {}; + this.content.lektord ??= {}; + this.content.kurisu ??= {}; + this.content.client ??= {}; + this.content.log ??= {}; - __config.kurisu.url ??= packageConfig.kurisu; - __config.client.port ??= packageConfig.port; - __config.log.level ??= 'debug'; - __config.log.lektord ??= true; - __config.database.path ??= '/home/kara/kara.db'; - __config.lektord.host ??= 'localhost'; - __config.lektord.port ??= '6600'; - __config.lektord.attach ??= true; + this.content.kurisu.url ??= packageConfig.kurisu; + this.content.client.port ??= packageConfig.port; + this.content.log.level ??= 'debug'; + this.content.log.lektord ??= true; + this.content.database.path ??= '/home/kara/kara.db'; + this.content.lektord.host ??= 'localhost'; + this.content.lektord.port ??= '6600'; + this.content.lektord.attach ??= true; - this.clientport = __config.client.port; - this.kurisuurl = __config.kurisu.url; - this.database = __config.database.path; - this.host = __config.lektord.host; - this.port = __config.lektord.port; - this.attachmode = __config.lektord.attach; - this.loglevel = __config.log.level; - this.loglektord = __config.log.lektord; - - fs.writeFileSync(__configFile, ini.stringify(__config)); + fs.writeFileSync(__configFile, ini.stringify(this.content)); this.flush(); }, flush() { - const __config = { - kurisu: { - url: this.kurisuurl, - }, - database: { - path: this.database, - }, - client: { - port: this.clientport, - }, - lektord: { - host: this.host, - port: this.port, - attach: this.attachmode, - }, - log: { - level: this.loglevel, - lektord: this.loglektord, - }, - }; - fs.writeFileSync(__configFile, ini.stringify(__config)); + fs.writeFileSync(__configFile, ini.stringify(this.content)); }, }; diff --git a/common/db.js b/common/db.js index 138ae129e5eb27f572125c38f6d7fe0ff6fd415c..0f608fbd00d8cc0d4b2ee7e601aa76000732832b 100644 --- a/common/db.js +++ b/common/db.js @@ -45,9 +45,9 @@ class KaraDatabase { * - m_karaPath: String * - m_db: sqlite3 database */ constructor() { - this.m_karaPath = config.database; + this.m_karaPath = config.content.database.path; this.m_db = new sqlite3.Database(this.m_karaPath); - logger.info('db', 'Create database from file ' + config.database); + logger.info('db', 'Create database from file ' + config.content.database.path); } /* Call this as a destructor */ diff --git a/common/lkt.js b/common/lkt.js index 126a49d38750c5b5036c9cd9e733a3aaf24f36bf..6f65b1e02d8d5ef80f18407aa4d8207b211d15e8 100644 --- a/common/lkt.js +++ b/common/lkt.js @@ -24,8 +24,8 @@ class LktClient { this.m_socket = new net.Socket(); this.m_closed = true; const sockopt = { - port: config.port, - host: config.host, + port: config.content.lektord.port, + host: config.content.lektord.host, readable: true, writable: true, }; @@ -34,17 +34,17 @@ class LktClient { this.m_socket.setTimeout(3000); this.m_socket.setEncoding('utf8'); this.m_socket.on('timeout', () => { - logger.error('lkt', `Got timeout while connecting to localhost:${config.port}`); + logger.error('lkt', `Got timeout while connecting to localhost:${config.content.lektord.port}`); this.m_socket.end(); }); this.m_socket.on('ready', () => { - logger.debug('lkt', `Ready to use socker with localhost:${config.port}`); + logger.debug('lkt', `Ready to use socket with localhost:${config.content.lektord.port}`); this.m_online = true; }); this.m_socket.on('end', () => { - logger.info('lkt', `Disconnected from server localhost:${config.port}`); + logger.info('lkt', `Disconnected from server localhost:${config.content.lektord.port}`); this.m_online = false; }); @@ -57,12 +57,12 @@ class LktClient { }); this.m_socket.on('close', () => { - logger.info('lkt', `Socket localhost:${config.port} closed`); + logger.info('lkt', `Socket localhost:${config.content.lektord.port} closed`); this.m_online = false; }); this.m_socket.connect(sockopt, () => { - logger.info('lkt', `Socket connected to localhost:${config.port}`); + logger.info('lkt', `Socket connected to localhost:${config.content.lektord.port}`); this.m_online = true; }); @@ -186,6 +186,14 @@ class LktClient { return __getResult(client); } + static reloadState() { + LktClient.commandStatus().then(data => { + LktClient.__status = data; + LktClient.status_updated = true; + logger.debug('lkt', `Got update in status ${JSON.stringify(data)}`); + }); + } + static idleActualisation() { var client = new this(); client.m_socket.setTimeout(0); @@ -193,13 +201,14 @@ class LktClient { return new Promise((resolve, reject) => { client.m_socket.on('data', data => { if (String(data).includes(' playlist')) { - logger.info("queue","cc"); LktClient.setQueueUpdated(true); } if(String(data).includes(' stored_playlist')) { - logger.info("playlist", "cc2"); LktClient.setPlaylistsUpdated(true); } + if (String(data).includes(' player')) { + LktClient.reloadState(); + } client.m_socket.write(`idle\n`); return null; }); @@ -309,6 +318,9 @@ class LktClient { static isPlaylistsUpdated() { return this.playlists_updated; } + static isStatusUpdated() { + return this.status_updated; + } static timeData = { elapsed: 0, total: 100, state: 'stop', song: 0 }; @@ -316,6 +328,11 @@ class LktClient { this.timeData.state = state; } + static getStatus() { + LktClient.status_updated = false; + return this.__status; + } + static setSongTimeData(elapsed, total, state, song) { this.timeData = { elapsed: elapsed, @@ -324,9 +341,56 @@ class LktClient { song: song, }; } + static getSongTimeData() { return this.timeData; } + + static ping() { + var socket = new net.Socket(); + var result = {}; + function __getResult(socket) { + return new Promise(resolv => { + const sockopt = { + port: config.content.lektord.port, + host: config.content.lektord.host, + readable: true, + writable: true, + }; + logger.debug('lkt', 'Try to ping'); + + socket.setTimeout(3000); + socket.setEncoding('utf8'); + + socket.on('timeout', () => { + logger.error('lkt', `Got timeout while ping to localhost:${config.content.lektord.port}`); + result = false; + resolv(result); + }); + + socket.on('ready', () => { + logger.debug('lkt', `Ping success with localhost:${config.content.lektord.port}`); + result = true; + resolv(result); + }); + + socket.on('error', err => { + logger.error('lkt', `${err}`); + result = false; + resolv(result); + }); + + socket.connect(sockopt, () => { + logger.info('lkt', `Pinged localhost:${config.content.lektord.port}`); + socket.destroy(); + result = true; + resolv(result); + }); + }); + } + + return __getResult(socket); + } } function __mpdToObject(string) { diff --git a/common/logger.js b/common/logger.js index c91112ff30a1d6e5052bca70ea4f13edebeb6d7e..fdd93b79ad7f65dbcc042aaf5f01c07ffa56b015 100644 --- a/common/logger.js +++ b/common/logger.js @@ -44,7 +44,7 @@ var __logger = winston.createLogger({ tailable: true, }), ], - level: `${config.loglevel}`, + level: `${config.content.log.level}`, json: false, handleExceptions: true, levels: __loggerCustomLevels.levels, @@ -88,7 +88,7 @@ var __lektord = data => { var logger = { logfile: __logFile, - lektord: config.loglektord ? __lektord : __nopLektord, + lektord: config.content.log.lektord ? __lektord : __nopLektord, debug: (cat, lg) => { __logger.debug(`${cat.padEnd(10)} | ${lg}`); }, diff --git a/instance/main.js b/instance/main.js index 679cf61fd816c4077ace8a5b0388f63bc152a6c5..264603febaff3fc61175509fabaac84e58c58bed 100644 --- a/instance/main.js +++ b/instance/main.js @@ -12,6 +12,19 @@ var dragCounter = 0; var leavedElement; var isDnDFromDB = false; +function updatePlayPauseButton(state) { + logger.debug('instance', `State was ${state}`); + if (state === 'play') { + /* Play */ + $('#commandPlay').children().addClass('fa-pause'); + $('#commandPlay').children().removeClass('fa-play'); + } else { + /* Pause or Stop */ + $('#commandPlay').children().addClass('fa-play'); + $('#commandPlay').children().removeClass('fa-pause'); + } +} + function addIpcToButton(btnId, ipc) { document.getElementById(btnId).addEventListener('click', () => { ipc.forEach(ipc => { @@ -21,14 +34,14 @@ function addIpcToButton(btnId, ipc) { } function autoFillSettings() { - $('#inputHost').val(config.host); - $('#inputPort').val(config.port); + $('#inputHost').val(config.content.lektord.host); + $('#inputPort').val(config.content.lektord.port); $('#inputAttachMode').prop('checked', true); - $('#inputDbPath').val(config.database); - $('#inputLogLektord').prop('checked', config.loglektord); - $(`#log${config.loglevel.toUpperCase()}`).prop('checked', true); - $('#inputKurisuUrl').val(config.kurisuurl); - $('#inputClientPort').val(config.clientport); + $('#inputDbPath').val(config.content.database.path); + $('#inputLogLektord').prop('checked', config.content.log.lektord); + $(`#log${config.content.log.level.toUpperCase()}`).prop('checked', true); + $('#inputKurisuUrl').val(config.content.kurisu.url); + $('#inputClientPort').val(config.content.client.port); } function flushFillSettings() { @@ -86,13 +99,7 @@ window.onload = () => { addIpcToButton('openKurisu', ['toggle-kurisu']); addIpcToButton('openUserView', ['toggle-client-view']); - - setTimeout(() => ipcRenderer.send('reload-queue-request'), 1000); - //setTimeout(() => ipcRenderer.send('reload-playlist-request'),1000); - setInterval(() => ipcRenderer.send('verify-queue-reloaded-request'), 50); - setTimeout(()=>setInterval(() => ipcRenderer.send('verify-playlists-reloaded-request'),50),1500); - setInterval(() => ipcRenderer.send('get-song-time-data'), 50); - setInterval(() => ipcRenderer.send('get-runnings'), 10000); + ipcRenderer.send('verify-lektord'); logger.debug('instance', 'Window loaded'); $('#filterInput').on('keypress', e => { @@ -205,6 +212,8 @@ ipcRenderer.on('reload-queue-responce', (event, arg) => { [].forEach.call(document.querySelectorAll('#panelRight .karaCard'), addQueueKaraEventHandlers); }); +ipcRenderer.on('send-state', (event, state) => updatePlayPauseButton(state)); + ipcRenderer.on('send-song-time-data', (event, timeData) => { document.getElementById('progressBar').style.width = `${ (timeData.elapsed / timeData.total) * document.documentElement.clientWidth @@ -215,10 +224,8 @@ ipcRenderer.on('send-song-time-data', (event, timeData) => { currentSong = timeData.song; } document.getElementsByClassName('karaQueue')[timeData.song].style.background = '#6b7d8e'; - } else { - if (document.getElementsByClassName('karaQueue')[timeData.song]) { - document.getElementsByClassName('karaQueue')[timeData.song].style.background = '#4e5d6c'; - } + } else if (document.getElementsByClassName('karaQueue')[timeData.song]) { + document.getElementsByClassName('karaQueue')[timeData.song].style.background = '#4e5d6c'; } }); @@ -254,6 +261,13 @@ ipcRenderer.on('playlist-data-responce', (event,karas) => { }); }); }); +ipcRenderer.on('send-lektord-is-attached', (event, arg) => { + logger.debug('instance', `Lektord is in attached mode? ${arg}`); +}); + +/* + * Drag'n'drop functions + */ function addDBKaraEventHandlers(element) { element.addEventListener('dragstart', onDragStartDB, false); diff --git a/instance/views/progressBar.ejs b/instance/views/progressBar.ejs index fefec9b813b67f153d00ebbcea4231cc21a6f295..74523e43313f9d1abd84ea1054ecd662549f66c2 100644 --- a/instance/views/progressBar.ejs +++ b/instance/views/progressBar.ejs @@ -1,7 +1,7 @@ <%# vim: ts=4 syntax=html The template for the progress bar at the bottom of the screen %> -<div id="progress" class="progress" style="z-index: 666; position: fixed !important; right: 0; left: 0; bottom: 0; height: 14px"> +<span id="progress" class="progress" style="z-index: 666; position: fixed !important; right: 0; left: 0; bottom: 0; height: 14px; border-top: 2px solid rgba(0, 0, 0, 0.125);"> <div class="progress-bar" id="progressBar" role="progressbar" style="-webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none; transition: none;"> </div> -</div> +</span> diff --git a/main.js b/main.js index aef438ab26692502f5cc028c5a384804d657fa5b..790fbf0af0d9882eee0635f8b42d4eb195233867 100644 --- a/main.js +++ b/main.js @@ -21,9 +21,11 @@ var client; /* Sub process for the express server */ class Lektor { constructor() { this.closed = true; + this.attached = false; isRunning({ win: 'lektord.exe', linux: 'lektord', mac: 'lektord' }).then(v => { - if (v && config.attachmode) { + if (v && config.content.lektord.attach) { logger.info('main', `Lektord is running! Attach to it`); + this.attached = true; } else if (v) { logger.error('error', `Lektord is running and attach mode is disable, exit!`); app.quit(); @@ -90,7 +92,6 @@ function createInstanceWindow() { }, }); win.loadURL(`file://${__dirname}/instance/index.ejs`); - // win.loadFile('instance/index.html'); } function createUserViewWindow() { @@ -107,7 +108,7 @@ function createUserViewWindow() { contextIsolation: true, }, }); - uv.loadURL(`http://localhost:${config.clientport}/`); + uv.loadURL(`http://localhost:${config.content.client.port}/`); uv.once('ready-to-show', () => { uv.show(); }); @@ -127,7 +128,7 @@ function createKurisuWindow() { contextIsolation: true, }, }); - kurisu.loadURL(config.kurisuurl); + kurisu.loadURL(config.content.kurisu.url); kurisu.once('ready-to-show', () => { kurisu.show(); }); @@ -153,9 +154,28 @@ app.on('quit', () => { app.on('ready', () => { logger.info('main', 'Main window is ready'); - createInstanceWindow(); client = fork('client/main.js'); lektor = new Lektor(); + createInstanceWindow(); + + win.webContents.on('did-finish-load', () => { + logger.debug('main', 'webContents got "did-finish-load"'); + win.webContents.send('send-lektord-is-attached', lektor.attached); + win.webContents.on('console-message', (event, level, message, line, sourceId) => { + switch (level) { + case 0: + logger.debug('console-instance', `[${sourceId}+${line}] ${message.replace(/\n|\r/g, '')}`); + break; + case 1: + logger.warn('console-instance', `[${sourceId}+${line}] ${message.replace(/\n|\r/g, '')}`); + break; + case 2: + default: + logger.error('console-instance', `[${sourceId}+${line}] ${message.replace(/\n|\r/g, '')}`); + break; + } + }); + }); globalShortcut.register('CommandOrControl+D', () => { var win = BrowserWindow.getFocusedWindow(); @@ -171,19 +191,13 @@ app.on('ready', () => { globalShortcut.register('F12', () => { var focused = BrowserWindow.getFocusedWindow(); if (focused) { - focused.webContents.openDevTools(); + if (!focused.isDevToolsOpened()) { + focused.webContents.openDevTools({ mode: 'detach' }); + } else { + focused.webContents.closeDevTools(); + } } }); - - setTimeout(() => { - lkt.idleActualisation(); - }, 1000); - setTimeout(() => { - lkt.statusActualisation(); - }, 1500); - /*setTimeout(() => { - lkt.commandPlaylistList(); - }, 1500);*/ }); /*************** @@ -240,29 +254,6 @@ ipcMain.on('reload-db-request', (event, arg) => { } }); -/* 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('reload-playlists-request', (event,arg) => { - lkt.commandPlaylistList().then(playlists => { - event.reply('playlists') - }); -}); - ipcMain.on('queue-moved-kara', (event, movement) => { if (movement.to != movement.from) { lkt.commandMove(movement.from, movement.to); @@ -289,61 +280,101 @@ ipcMain.on('add-kara-queue-pos', (event, addparams) => { lkt.commandQueueAddId(addparams.id).then(() => lkt.commandMove(addparams.queueSize + 1, addparams.position)); }); -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('verify-lektord', (event, arg) => { + lkt.ping().then(sta => { + logger.debug('main', `Status from ping is ${sta}`); + lkt.reloadState(); + setTimeout(() => lkt.idleActualisation(), 1000); + setTimeout(() => lkt.statusActualisation(), 1500); + + setTimeout(() => db.queueAll().then(karas => win.webContents.send('reload-queue-responce', karas)), 1000); + setInterval(() => { + if (lkt.isQueueUpdated()) { + lkt.setQueueUpdated(false); + db.queueAll().then(karas => win.webContents.send('reload-queue-responce', karas)); + } + }, 50); + + setInterval(() => { + var newSongTimeData = lkt.getSongTimeData(); + if (newSongTimeData.elapsed != songTimeData.elapsed || newSongTimeData.song != songTimeData.song) { + songTimeData = newSongTimeData; + win.webContents.send('send-song-time-data', { + elapsed: songTimeData.elapsed, + total: songTimeData.total, + song: songTimeData.song, + state: songTimeData.state, + }); + counterTime = 0; + } else if (newSongTimeData.state == 'play') { + counterTime++; + win.webContents.send('send-song-time-data', { + elapsed: songTimeData.elapsed + counterTime / 20.0, + total: songTimeData.total, + song: songTimeData.song, + state: songTimeData.state, + }); + } else { + win.webContents.send('send-song-time-data', { + elapsed: songTimeData.elapsed + counterTime / 20.0, + total: songTimeData.total, + song: songTimeData.song, + state: songTimeData.state, + }); + } + }, 50); + + setInterval( + () => + isRunning({ win: 'klkt.exe', mac: 'klkt', linux: 'klkt' }).then(vklkt => + isRunning({ win: 'lektord.exe', mac: 'lektord', linux: 'lektord' }).then(vlektord => + win.webContents.send('send-runnings', { + klkt: vklkt, + lektord: vlektord, + }) + ) + ), + 1000 + ); + + setInterval(() => { + if (lkt.isStatusUpdated()) { + win.webContents.send('send-state', lkt.getStatus().state); + } + }, 50); -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, - }); - }); + setInterval(() => { + if(lkt.isPlaylistsUpdated()) { + lkt.setPlaylistsUpdated(false); + lkt.commandPlaylistsList().then((playlists) => { + win.webContents.send('playlists-updated', playlists); + }); + } + }, 50) }); }); 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; + + config.content.lektord.host = arg.host; + config.content.lektord.port = arg.port; + config.content.lektord.attach = arg.attachmode; + + config.content.database.path = arg.db; + + config.content.kurisu.url = arg.kurisuurl; + + config.content.client.port = arg.clientport; /* prettier-ignore */ - config.loglevel = arg.loglevel.ERROR ? 'error' - : arg.loglevel.WARNING ? 'warning' - : arg.loglevel.INFO ? 'info' - : 'debug'; + { + config.content.log.lektord = arg.loglektord; + config.content.log.level = arg.loglevel.ERROR ? 'error' + : arg.loglevel.WARNING ? 'warning' + : arg.loglevel.INFO ? 'info' + : 'debug'; + } config.flush(); }); diff --git a/package.json b/package.json index 40aaa64f365d4b9870f274735cbac1719f00f527..8f06963896305ee3aab1960ec432742b077c4d4c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ ], "license": "ISC", "scripts": { - "start": "ELECTRON_ENABLE_LOGGING=0 ELECTRON_NO_ATTACH_CONSOLE=true electron --trace-uncaught ." + "start": "electron --trace-uncaught ." }, "dependencies": { "ejs": "^3.1.5",