diff --git a/package.json b/package.json index b88cd65..b377841 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loquendo-bot", - "version": "2.1.0", + "version": "2.2.0", "description": "Bot assistant for streamers over different platforms", "main": "src/main.js", "scripts": { diff --git a/src/js/logger.js b/src/js/logger.js index 0f36c94..ff4c5a3 100644 --- a/src/js/logger.js +++ b/src/js/logger.js @@ -6,76 +6,75 @@ const path = require('path'); const consoleloggerLevel = process.env.WINSTON_LOGGER_LEVEL || 'info'; const consoleFormat = format.combine( - format.colorize(), - format.timestamp(), - format.align(), - format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message - } ${JSON.stringify(info.metadata)}`), + format.colorize(), + format.timestamp(), + format.align(), + format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message} ${JSON.stringify(info.metadata)}`), ); const fileFormat = format.combine( - format.timestamp(), - format.metadata({ fillExcept: ['message', 'level', 'timestamp', 'label'] }), - format.json(), + format.timestamp(), + format.metadata({ fillExcept: ['message', 'level', 'timestamp', 'label'] }), + format.json(), ); const logger = createLogger({ - level: 'info', - format: fileFormat, - transports: [ - new transports.File({ - filename: path.join(resourcesPath, '../logs/error.log'), - level: 'error', - }), - new transports.File({ - filename: path.join(resourcesPath, '../logs/activity.log'), - maxsize: 5242880, - maxFiles: 5, - }), - ], + level: 'info', + format: fileFormat, + transports: [ + new transports.File({ + filename: path.join(__dirname, '../logs/error.log'), + level: 'error', + }), + new transports.File({ + filename: path.join(__dirname, '../logs/activity.log'), + maxsize: 5242880, + maxFiles: 5, + }), + ], }); if (process.env.NODE_ENV !== 'production') { - logger.add( - new transports.Console({ - level: consoleloggerLevel, - format: consoleFormat, - }), - ); + logger.add( + new transports.Console({ + level: consoleloggerLevel, + format: consoleFormat, + }), + ); } -fetch(path.join(resourcesPath, '../logs/activity.log')) - .then((response) => response.text()) - .then((logData) => { - const logLines = logData.trim().split('\n'); - const tableBody = document.getElementById('logContent'); +fetch(path.join(__dirname, '../logs/activity.log')) + .then((response) => response.text()) + .then((logData) => { + const logLines = logData.trim().split('\n'); + const tableBody = document.getElementById('logContent'); - logLines.forEach((logLine) => { - const logObject = JSON.parse(logLine); - const row = document.createElement('tr'); + logLines.forEach((logLine) => { + const logObject = JSON.parse(logLine); + const row = document.createElement('tr'); - const levelCell = document.createElement('td'); - levelCell.textContent = logObject.level; - levelCell.classList.add(logObject.level); // Add class for styling - row.appendChild(levelCell); + const levelCell = document.createElement('td'); + levelCell.textContent = logObject.level; + levelCell.classList.add(logObject.level); // Add class for styling + row.appendChild(levelCell); - const messageCell = document.createElement('td'); - messageCell.textContent = logObject.message; - row.appendChild(messageCell); + const messageCell = document.createElement('td'); + messageCell.textContent = logObject.message; + row.appendChild(messageCell); - const metadataCell = document.createElement('td'); - metadataCell.textContent = JSON.stringify(logObject.metadata, null, 2); - row.appendChild(metadataCell); + const metadataCell = document.createElement('td'); + metadataCell.textContent = JSON.stringify(logObject.metadata, null, 2); + row.appendChild(metadataCell); - const timestampCell = document.createElement('td'); - timestampCell.textContent = logObject.timestamp; - row.appendChild(timestampCell); + const timestampCell = document.createElement('td'); + timestampCell.textContent = logObject.timestamp; + row.appendChild(timestampCell); - tableBody.appendChild(row); - }); - }) - .catch((error) => { - // console.error('Error fetching log file:', error); - }); + tableBody.appendChild(row); + }); + }) + .catch((error) => { + // console.error('Error fetching log file:', error); + }); module.exports = logger; diff --git a/src/js/renderer.js b/src/js/renderer.js index 112f7c9..2944c5d 100644 --- a/src/js/renderer.js +++ b/src/js/renderer.js @@ -23,11 +23,11 @@ const settingsPath = main.settingsPath.toString(); const settings = main.settings; // TODO: remove gooogle voices txt and use api instead -const googleVoices = fs.readFileSync(path.join(resourcesPath, './config/googleVoices.txt')).toString().split('\r\n'); +const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n'); // TODO: remove amazon voices txt and use api instead (sakura project has it) -const amazonVoices = fs.readFileSync(path.join(resourcesPath, './config/amazonVoices.txt')).toString().split('\r\n'); +const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n'); -const languagesObject = fs.readFileSync(path.join(resourcesPath, './config/languages.txt')).toString().split('\r\n'); +const languagesObject = fs.readFileSync(path.join(__dirname, './config/languages.txt')).toString().split('\r\n'); // html elements const root = document.documentElement; @@ -39,17 +39,15 @@ const notificationSound = document.querySelector('#notification'); // obtain the const ttsAudioDevices = document.querySelector('#ttsAudioDevice'); // obtain the html reference of the installedTTS comboBox // laod local javascript files -const chat = require(path.join(resourcesPath, './js/chat')); +const chat = require(path.join(__dirname, './js/chat')); -const messageTemplates = require(path.join(resourcesPath, './js/messageTemplates')); -const logger = require(path.join(resourcesPath, './js/logger')); -const sound = require(path.join(resourcesPath, './js/sound')); -const talk = require(path.join(resourcesPath, './js/voiceQueue')); // Voice queue system -const config = require(path.join(resourcesPath, './js/settings')); +const messageTemplates = require(path.join(__dirname, './js/messageTemplates')); +const logger = require(path.join(__dirname, './js/logger')); +const sound = require(path.join(__dirname, './js/sound')); +const talk = require(path.join(__dirname, './js/voiceQueue')); // Voice queue system +const config = require(path.join(__dirname, './js/settings')); -let notificationSounds = path.join(resourcesPath, './sounds/notifications'); - -let twitch = require(path.join(resourcesPath, './js/twitch')); +let notificationSounds = path.join(__dirname, './sounds/notifications'); function reset() { ipcRenderer.send('restart'); @@ -62,16 +60,17 @@ function setServer() { if (!settings.SERVER.USE_SERVER) { return; } - server = require(path.join(resourcesPath, './js/server')); + server = require(path.join(__dirname, './js/server')); socket = io(`http://localhost:${settings.SERVER.PORT}`); // Connect to your Socket.IO server } setServer(); -const Polly = settings.AMAZON.USE_AMAZON ? require(path.join(resourcesPath, './js/amazon')) : ''; -const google = settings.GOOGLE.USE_GOOGLE ? require(path.join(resourcesPath, './js/amazon')) : ''; +let twitch = settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './js/twitch')) : ''; +const Polly = settings.AMAZON.USE_AMAZON ? require(path.join(__dirname, './js/amazon')) : ''; +const google = settings.GOOGLE.USE_GOOGLE ? require(path.join(__dirname, './js/google')) : ''; -const theme = require(path.join(resourcesPath, './js/theme')); +const theme = require(path.join(__dirname, './js/theme')); // initialize values config.getGeneralSettings(); diff --git a/src/js/server.js b/src/js/server.js index 4eef702..ac6a2e8 100644 --- a/src/js/server.js +++ b/src/js/server.js @@ -19,7 +19,7 @@ function startVtuber() { return; } - app.use('/vtuber', express.static(path.join(resourcesPath, './modules/vtuber/'))); + app.use('/vtuber', express.static(path.join(__dirname, '../modules/vtuber/'))); let vtuber = document.body.querySelector('#BrowsersourceVtuber'); let vtuberframe = document.createElement('iframe'); @@ -37,7 +37,7 @@ function startChatBubble() { return; } - app.use('/chat', express.static(path.join(resourcesPath, './modules/chat'))); + app.use('/chat', express.static(path.join(__dirname, '../modules/chat'))); let chat = document.body.querySelector('#BrowsersourceChat'); let chatframe = document.createElement('iframe'); diff --git a/src/js/settings.js b/src/js/settings.js index 387a944..5adc41e 100644 --- a/src/js/settings.js +++ b/src/js/settings.js @@ -204,6 +204,11 @@ document.body.querySelector('#Info_USERNAME').addEventListener('click', () => { let element = document.body.querySelector('#TWITCH_OAUTH_TOKEN'); element.value = key; + + settings.TWITCH.OAUTH_TOKEN = key; + + fs.writeFileSync(settingsPath, ini.stringify(settings)); + createNotification('Saved OAuth token!', 'success'); }); document.body.querySelector('#Info_VTUBER').addEventListener('click', () => { @@ -226,7 +231,7 @@ document.body.querySelector('#close-button').addEventListener('click', (event) = // #region Notification sound test document.body.querySelector('#SoundTestButton').addEventListener('click', () => { - sound.playAudio(); + sound.playNotificationSound(); }); document.body.querySelector('#TestTwitchCredentials').addEventListener('click', () => { @@ -248,7 +253,7 @@ document.body.querySelector('#USE_TWITCH').addEventListener('click', () => { fs.writeFileSync(settingsPath, ini.stringify(settings)); const inputs = document.getElementsByClassName('inputTwitch'); toggleRadio(toggle, inputs); - twitch = settings.TWITCH.USE_TWITCH ? require(path.join(resourcesPath, './js/twitch')) : null; + twitch = settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './twitch')) : null; createNotification(`${toggle ? 'Enabled' : 'Disabled'} Twitch settings!`, 'success'); }); diff --git a/src/js/sound.js b/src/js/sound.js index 9f5e18c..e4421b1 100644 --- a/src/js/sound.js +++ b/src/js/sound.js @@ -47,19 +47,21 @@ function add(ttsData) { } } -// Play sound function -function playAudio(data) { +function playNotificationSound() { if (settings.AUDIO.USE_NOTIFICATION_SOUNDS) { let notfication = new Audio( - path.join(resourcesPath, `../src/sounds/notifications/${notificationSound.options[settings.AUDIO.NOTIFICATION_SOUND].text}`), + path.join(resourcesPath, `./sounds/notifications/${notificationSound.options[settings.AUDIO.NOTIFICATION_SOUND].text}`), ); notfication.volume = settings.AUDIO.NOTIFICATION_VOLUME / 100; notfication.play(); } +} +// Play sound function +function playAudio(data) { if (settings.TTS.USE_TTS) { add(data); - } else if (settings.SERVER.USE_SERVER) { + } else if (settings.SERVER.USE_SERVER && settings.SERVER.USE_CHATBUBBLE) { socket.emit('xxx', currentLogoUrl, currentUsername, data); } } @@ -86,8 +88,8 @@ function playVoice(filteredMessage, logoUrl, username, message) { if (settings.TTS.USE_TTS) { talk.add(textObject, voice); } else { - playAudio(textObject); + playNotificationSound(); } } -module.exports = { playAudio, playVoice }; +module.exports = { playAudio, playVoice, playNotificationSound }; diff --git a/src/js/twitch.js b/src/js/twitch.js index 32c35c4..09bfe5a 100644 --- a/src/js/twitch.js +++ b/src/js/twitch.js @@ -29,13 +29,10 @@ function ping(element) { client .ping() .then((data) => { - console.log(client.readyState()); - console.log(data); value.classList.add('success'); value.innerText = 'Success!'; }) .catch((e) => { - console.log(e); value.classList.add('error'); value.innerText = 'Failed!'; }); diff --git a/src/js/voiceQueue.js b/src/js/voiceQueue.js index 0dd9c98..cee80bd 100644 --- a/src/js/voiceQueue.js +++ b/src/js/voiceQueue.js @@ -6,13 +6,14 @@ const speak = (textObject) => new Promise((resolve) => { // say.setEncoding(Encoding); counter += 1; - let savePath = path.join(resourcesPath, '../src/sounds/tts/internal_audio_' + counter + '.mp3'); + let savePath = path.join(resourcesPath, './sounds/tts/internal_audio_' + counter + '.mp3'); say.export(textObject.filtered, SelectedVoice, 1, savePath, (err) => { if (err) { console.error(err); } else { sound.playAudio({ path: savePath, message: textObject }); + sound.playNotificationSound(); } resolve('finished'); }); diff --git a/src/main.js b/src/main.js index 7353f0f..ab964c5 100644 --- a/src/main.js +++ b/src/main.js @@ -1,19 +1,21 @@ const { app, shell, BrowserWindow, ipcMain } = require('electron'); -const writeIniFile = require('write-ini-file'); +const { writeIniFile } = require('write-ini-file'); const path = require('path'); const ini = require('ini'); const fs = require('fs'); -let resourcesPath; +let resourcesPath = __dirname; let settingsPath; + let settings; let window; if (app.isPackaged) { + settingsPath = path.join(process.resourcesPath, './settings.ini'); resourcesPath = process.resourcesPath; } else { - resourcesPath = __dirname; + settingsPath = path.join(resourcesPath, './config/settings.ini'); } // Handle creating/removing shortcuts on Windows when installing/uninstalling. @@ -22,15 +24,15 @@ if (require('electron-squirrel-startup')) { } async function createWindow() { - if (!fs.existsSync(resourcesPath)) { - await createIniFile(path.join(resourcesPath, '../config/settings.ini')); + if (!fs.existsSync(settingsPath)) { + console.log(resourcesPath); + await createIniFile(); } else { - settingsPath = path.join(resourcesPath, './config/settings.ini'); settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8')); } window = new BrowserWindow({ - icon: path.join(resourcesPath, '/images/icon.png'), + icon: path.join(__dirname, '/images/icon.png'), width: parseInt(settings.SETTINGS.WIDTH), height: parseInt(settings.SETTINGS.HEIGHT), x: parseInt(settings.SETTINGS.POSITION_X), @@ -44,7 +46,7 @@ async function createWindow() { }); window.loadURL('https://github.com'); - window.loadFile(path.join(resourcesPath, 'index.html')); + window.loadFile(path.join(__dirname, 'index.html')); if (!app.isPackaged) { window.webContents.openDevTools(); @@ -112,7 +114,7 @@ ipcMain.on('restart', (event) => { }); ipcMain.on('environment', (event) => { - event.returnValue = { resourcesPath: resourcesPath, settingsPath: settingsPath, settings: settings }; + event.returnValue = { resourcesPath: resourcesPath, settingsPath: settingsPath, settings: settings, isPackaged: app.isPackaged }; }); let twitchAuthentication = () => @@ -203,7 +205,7 @@ ipcMain.on('chatBubble', async (event) => { }); async function createIniFile() { - await writeIniFile(resourcesPath, { + await writeIniFile(settingsPath, { SETTINGS: { VOICE_ENABLED: true, NOTIFICATION_ENABLED: true, @@ -268,6 +270,6 @@ async function createIniFile() { API_KEY: '', }, }).then(() => { - settings = ini.parse(fs.readFileSync(resourcesPath, 'utf-8')); + settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8')); }); } diff --git a/src/sounds/tts/internal_audio_6.mp3 b/src/sounds/tts/internal_audio_6.mp3 deleted file mode 100644 index 8c2ff6b..0000000 Binary files a/src/sounds/tts/internal_audio_6.mp3 and /dev/null differ