Merge pull request #4 from Khyretos/develop

Develop
This commit is contained in:
Kees Rodriguez 2023-12-25 22:11:50 +01:00 committed by GitHub
commit 76136c1808
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 153 additions and 68 deletions

View file

@ -1,6 +1,6 @@
{
"name": "loquendo-bot",
"version": "2.3.0",
"version": "2.4.0",
"description": "Bot assistant for streamers over different platforms",
"main": "src/main.js",
"scripts": {
@ -21,6 +21,7 @@
"electron-squirrel-startup": "^1.0.0",
"express": "^4.18.2",
"ini": "^2.0.0",
"kill-process-by-name": "^1.0.5",
"node-google-tts-api": "^1.1.1",
"querystring": "^0.2.1",
"socket.io": "^4.7.1",

View file

@ -32,17 +32,15 @@ SetLogLevel(-1)
settings = configparser.ConfigParser()
app = Flask(__name__)
if len(sys.argv) > 1:
settingsPath = os.path.normpath(sys.argv[1])
environment = sys.argv[2]
settingsPath = os.path.normpath(sys.argv[1])
environment = sys.argv[2]
q = queue.Queue()
# gobal functions
# classes
class LanguageDetection:
def __init__(self):
if environment == "dev":
@ -79,7 +77,7 @@ class STT:
def __init__(self):
settings.read(settingsPath)
device_info = sd.query_devices(int(settings["STT"]["MICROPHONE"]), "input")
self.samplerate = int(device_info["default_samplerate"])
self.samplerate = int(device_info["default_samplerate"])
if environment == "dev":
settings_folder = os.path.dirname(settingsPath)
@ -182,7 +180,6 @@ text_to_speech_service = TTS()
# endpoints
@app.route("/stream", methods=["GET"])
def stream_recognition():
def generate():
@ -277,3 +274,4 @@ if __name__ == "__main__":
stream_recognition()
app.run(host="127.0.0.1", port=port)
app.terminate()

View file

@ -15,8 +15,9 @@ h1 {
flex-direction: column;
background-color: var(--mid-section);
margin-left: 50px;
margin-right: 50px;
font-family: 'FRAMDCN';
position: relative;
z-index: 1;
}
.input-box {
@ -172,16 +173,25 @@ h1 {
}
.msg-container {
direction: ltr;
position: static;
display: inline-block;
width: 100%;
margin: 0px 0px 0px 0px;
padding: 0px 0px 10px 0px;
}
.msg-container-user {
direction: rtl;
position: static;
display: inline-block;
width: 100%;
margin-top: 10px;
}
.msg-box {
background: var(--chat-bubble);
color: white;
min-width: 150px;
border-radius: 5px;
padding: 20px 5px 5px 25px;
margin: 20px 0px 0px 25px;
@ -191,15 +201,14 @@ h1 {
.msg-box-user {
background: var(--chat-bubble);
padding: 5px 5px 5px 5px;
border-radius: 6px 6px 6px 6px;
margin-right: -20px;
margin-top: 10px;
max-width: 80%;
width: auto;
float: right;
word-wrap: break-word;
color: white;
text-align: -webkit-left;
min-width: 150px;
border-radius: 5px;
padding: 20px 15px 10px 5px;
margin: 0px 35px 0px 25px;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.24);
width: fit-content;
}
.msg-box-user-temp {
@ -211,14 +220,16 @@ h1 {
border-radius: 50%;
height: 50px;
width: 50px;
z-index: 5;
}
.user-img-user {
display: inline-block;
border-radius: 50%;
height: 40px;
width: 40px;
margin: 0 0px 10px 10px;
height: 50px;
width: 50px;
position: absolute;
z-index: 5;
}
.messages {
@ -256,15 +267,26 @@ h1 {
.username {
float: left;
color: var(--chat-bubble-header);
background-color: var(--main-color4);
margin-left: 25px;
color: white;
position: relative;
z-index: 2;
padding: 5px 5px 5px 30px;
border-radius: 5px;
top: 10px;
z-index: 1;
}
.username-user {
background-color: var(--main-color4);
margin-right: 25px;
color: white;
padding: 5px 40px 5px 15px;
border-radius: 5px;
margin: 0px 30px 5px 5px;
top: 15px;
position: relative;
z-index: 1;
}
.username-temp {
@ -272,13 +294,35 @@ h1 {
}
.post-time {
float: right;
font-size: 8pt;
padding: 10px 0px 0px 5px;
padding: 3px 5px 0px 15px;
color: white;
display: inline-block;
background-color: var(--main-color4);
right: 15px;
top: -19px;
position: relative;
z-index: 2;
border-radius: 5px;
text-align: center;
}
.msg-self .msg-box {
.post-time-user {
font-size: 8pt;
padding: 3px 15px 0px 5px;
margin: 5px -15px 0px -10px;
color: white;
display: inline-block;
background-color: var(--main-color4);
right: 60px;
top: -19px;
position: relative;
z-index: 2;
border-radius: 5px;
text-align: center;
}
/* .msg-self .msg-box {
border-radius: 6px 6px 6px 6px;
background: var(--main-color1);
float: right;
@ -291,30 +335,26 @@ h1 {
.msg-self .msg {
text-align: justify;
text-justify: inter-word;
}
} */
.mmg {
display: flex;
}
.icon-container {
width: 50px;
height: 50px;
position: absolute;
float: left;
left: 0;
display: flex;
align-items: center;
z-index: 3;
}
.icon-container-user {
width: 50px;
direction: ltr;
height: 50px;
position: relative;
float: right;
position: absolute;
display: flex;
align-items: center;
z-index: 3;
}
.img {
@ -328,6 +368,7 @@ h1 {
height: 20px;
border-radius: 50%;
margin-left: -15px;
z-index: 6;
margin-top: -30px;
}
@ -335,13 +376,8 @@ h1 {
width: 20px;
height: 20px;
border-radius: 50%;
bottom: 0;
right: 0;
margin-left: -50px;
margin-top: 10px;
}
select {
z-index: 6;
margin-top: -30px;
}
.menu-select {

View file

@ -388,6 +388,7 @@ input[type='lol'] {
transition: opacity 0.3s, visibility 0s;
color: var(--main-color2);
font-family: 'xxii_avenmedium';
z-index: 999;
}
/* .tooltip .tooltiptext {

View file

@ -152,6 +152,11 @@
<div class="AdvancedMenuRow">
<div class="AdvancedMenuLabel">TTS Output Device</div>
<select class="menu-select" name="ttsAudioDevice" id="ttsAudioDevice"></select>
<i
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
id="Info_OUTPUT_TTS"
tip="Outputting to specific device will NOT work with voicemeter"
></i>
</div>
<div class="AdvancedMenuRow">
<div class="AdvancedMenuLabel">TTS Volume</div>

View file

@ -72,8 +72,30 @@ const twitchAuthentication = () =>
}
});
function getTwitchUserId() {
// Get user Logo with access token
options = {
method: 'GET',
url: `https://api.twitch.tv/helix/users`,
headers: { 'Client-ID': settings.TWITCH.CLIENT_ID, Authorization: `Bearer ${settings.TWITCH.OAUTH_TOKEN}` },
};
axios
.request(options)
.then((responseLogoUrl) => {
console.log(responseLogoUrl.data.data[0]);
settings.TWITCH.USERNAME = responseLogoUrl.data.data[0].display_name;
settings.TWITCH.USER_LOGO_URL = responseLogoUrl.data.data[0].profile_image_url;
settings.TWITCH.USER_ID = responseLogoUrl.data.data[0].id;
fs.writeFileSync(settingsPath, ini.stringify(settings));
})
.catch((error) => {
console.error(error);
});
}
function getTwitchOauthToken() {
return twitchAuthentication().then((res) => {
getTwitchUserId();
return res;
});
}

View file

@ -1,4 +1,5 @@
const spawn = require('child_process').spawn;
var kill = require('kill-process-by-name');
let python;
async function getInstalledVoices() {
@ -145,17 +146,21 @@ async function initiateBackend() {
initiateBackend();
//TODO: convert to restartServer function
ipcRenderer.on('quit-event', async () => {
try {
const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/terminate`, { method: 'GET' });
if (response.ok) {
const responseData = await response.json();
console.log('Response:', responseData);
kill('loquendoBot_backend');
} else {
console.error('Failed to send termination signal to Flask server.');
kill('loquendoBot_backend');
}
} catch (error) {
console.error('Error sending termination signal:', error);
kill('loquendoBot_backend');
}
});

View file

@ -8,22 +8,31 @@ function getResponse() {
// Create chat message from received data
const article = document.createElement('article');
article.className = 'msg-container msg-self';
article.className = 'msg-container-user';
article.innerHTML = messageTemplates.userTemplate;
const postTime = article.querySelector('.post-time');
const userImg = article.querySelector('.icon-container-user > .user-img-user');
if (userImg) {
userImg.src = settings.TWITCH.USER_LOGO_URL;
}
const postTime = article.querySelector('.post-time-user');
const iconContainer = article.querySelector('.icon-container-user');
iconContainer.appendChild(postTime);
if (postTime) {
postTime.innerText = getPostTime();
}
const msg = article.querySelector('.msg');
const msg = article.querySelector('.msg-box-user');
if (msg) {
msg.innerText = userText;
}
// Appends the message to the main chat box (shows the message)
showChatMessage(article);
showChatMessage(article, true);
twitch.sendMessage(userText);

View file

@ -9,21 +9,14 @@ const twitchTemplate = `
`.trim();
const userTemplate = `
<div class="icon-container-user">
<img class="user-img-user" src="https://gravatar.com/avatar/56234674574535734573000000000001?d=retro" />
<div class="icon-container-user">
<span class="post-time-user">You</span>
<img class="status-circle-user" src="./images/twitch-icon.png" />
</div>
<div class="msg-box-user">
<div class="flr">
<div class="messages-user">
<span class="timestamp">
<span class="username">You</span>
<span class="post-time"></span>
</span>
<p class="msg"></p>
</div>
</div>
</div>
<img class="user-img-user" src="https://gravatar.com/avatar/56234674574535734573000000000001?d=retro" />
</div>
<span class="username-user">You</span>
<div class="msg-box-user">
</div>
`.trim();
const messageTemplate = `

View file

@ -1,6 +1,7 @@
const fs = require('fs');
const ini = require('ini');
const path = require('path'); // get directory path
const axios = require('axios');
const { ipcRenderer, shell } = require('electron'); // necessary electron libraries to send data to the app
const io = require('socket.io-client');
@ -195,16 +196,23 @@ Array.from(document.body.querySelectorAll('[tip]')).forEach((el) => {
};
});
function showChatMessage(article) {
function showChatMessage(article, isUser) {
document.querySelector('#chatBox').appendChild(article);
let usernameHtml;
let msg;
let messages = Array.from(document.body.querySelectorAll('.msg-container'));
if (isUser) {
usernameHtml = article.querySelector('.username-user');
msg = article.querySelector('.msg-box-user');
} else {
usernameHtml = article.querySelector('.username');
msg = article.querySelector('.msg-box');
}
const usernameHtml = article.querySelector('.username');
var style = getComputedStyle(usernameHtml);
var style2 = getComputedStyle(usernameHtml);
const msg = article.querySelector('.msg-box');
const messages = Array.from(document.body.querySelectorAll('.msg-container'));
const lastMessage = messages[messages.length - 1];
lastMessage.scrollIntoView({ behavior: 'smooth' });
}

View file

@ -29,7 +29,7 @@ function getGeneralSettings() {
document.body.querySelector('#USE_VTUBER').checked = settings.MODULES.USE_VTUBER;
document.body.querySelector('#VTUBER_URL').value = `http://localhost:${settings.GENERAL.PORT}/vtuber/`;
showMenuButton('#btnBrowsersourceVtuber', settings.MODULES.USE_VTUBER);
document.body.querySelector('#USE_CHATBUBBLE').checked = settings.GENERAL.USE_CHATBUBBLE;
document.body.querySelector('#USE_CHATBUBBLE').checked = settings.MODULES.USE_CHATBUBBLE;
document.body.querySelector('#CHATBUBBLE_URL').value = `http://localhost:${settings.GENERAL.PORT}/chat/`;
showMenuButton('#btnBrowsersourceChat', settings.GENERAL.USE_CHATBUBBLE);

View file

@ -61,6 +61,9 @@ function displayTwitchMessage(logoUrl, username, messageObject, fileteredMessage
postTime.innerText = getPostTime();
}
const iconContainer = article.querySelector('.icon-container');
iconContainer.appendChild(postTime);
const msg = article.querySelector('.msg-box');
if (msg) {
messageObject.forEach((entry) => {
@ -70,11 +73,11 @@ function displayTwitchMessage(logoUrl, username, messageObject, fileteredMessage
msg.innerHTML += entry.html;
}
});
msg.appendChild(postTime);
// msg.appendChild(postTime);
}
// Appends the message to the main chat box (shows the message)
showChatMessage(article);
showChatMessage(article, false);
if (fileteredMessage) {
sound.playVoice(fileteredMessage, logoUrl, username, msg);

View file

@ -2,6 +2,7 @@ const { app, BrowserWindow, ipcMain } = require('electron');
const { writeIniFile } = require('write-ini-file');
const path = require('path');
const http = require('http');
const kill = require('kill-process-by-name');
const ini = require('ini');
const fs = require('fs');
@ -109,6 +110,7 @@ ipcMain.on('maximize-window', (event) => {
ipcMain.on('close-window', (event) => {
const browserWindow = BrowserWindow.fromWebContents(event.sender);
kill('loquendoBot_backend');
browserWindow.close();
app.quit();
});
@ -176,7 +178,9 @@ async function createIniFile() {
TWITCH: {
USE_TWITCH: false,
CHANNEL_NAME: '',
USERNAME: 'loquendo',
USERNAME: '',
USER_ID: '',
USER_LOGO_URL: '',
OAUTH_TOKEN: '',
CLIENT_ID: '2t206sj7rvtr1rutob3p627d13jch9',
},