#2 implement debugger

This commit is contained in:
Logan Cusano
2024-06-02 20:10:55 -04:00
parent e54c80a95b
commit f706ac89b4
15 changed files with 190 additions and 94 deletions

View File

@@ -1,3 +1,6 @@
import { DebugBuilder } from "./modules/debugger.mjs";
const log = new DebugBuilder("client", "client");
import { ClientNodeConfig } from './modules/clientObjectDefinitions.mjs'; import { ClientNodeConfig } from './modules/clientObjectDefinitions.mjs';
import { initSocketConnection } from './modules/socketClient.mjs'; import { initSocketConnection } from './modules/socketClient.mjs';
import { checkForUpdates } from './modules/selfUpdater.mjs' import { checkForUpdates } from './modules/selfUpdater.mjs'
@@ -26,9 +29,9 @@ boot().then((openSocket) => {
startServer(process.env.WEB_SERVER_PORT || 3000, openSocket); startServer(process.env.WEB_SERVER_PORT || 3000, openSocket);
if (!openSocket) { if (!openSocket) {
console.log(openSocket, "Waiting for setup"); log.INFO(openSocket, "Waiting for setup");
} }
else { else {
console.log(openSocket, "Booted Sucessfully"); log.INFO(openSocket, "Booted Sucessfully");
} }
}) })

View File

@@ -1,4 +1,6 @@
// server.js // server.js
import { DebugBuilder } from "../modules/debugger.mjs";
const log = new DebugBuilder("client", "pdabHandler.mjs");
import express from 'express'; import express from 'express';
import http from 'http'; import http from 'http';
import { Server } from 'socket.io'; import { Server } from 'socket.io';
@@ -29,21 +31,21 @@ export const initDiscordBotClient = (clientId, callback, runPDAB = true) => {
export const startPdabSocketServer = () => { export const startPdabSocketServer = () => {
io.on('connection', (socket) => { io.on('connection', (socket) => {
console.log('A user connected'); log.INFO('A user connected');
socket.on('disconnect', () => { socket.on('disconnect', () => {
console.log('User disconnected'); log.INFO('User disconnected');
}); });
// Listen for the discord client ready event // Listen for the discord client ready event
socket.on('discord_ready', (message) => { socket.on('discord_ready', (message) => {
console.log("Message from local client", message); log.INFO("Message from local client", message);
botCallback(); botCallback();
}); });
}); });
server.listen(port, async () => { server.listen(port, async () => {
console.log(`Server is running on port ${port}`); log.INFO(`Server is running on port ${port}`);
}); });
return return
} }
@@ -61,7 +63,7 @@ export const closePdabSocketServer = () => {
export const connectToChannel = (channelId) => { export const connectToChannel = (channelId) => {
return new Promise((res) => { return new Promise((res) => {
io.timeout(25000).emit('join_server', { channelId: channelId }, (status, value) => { io.timeout(25000).emit('join_server', { channelId: channelId }, (status, value) => {
console.log("Status returned from bot:", status, value); log.INFO("Status returned from bot:", status, value);
res(value[0]); res(value[0]);
}); });
}); });
@@ -71,7 +73,7 @@ export const connectToChannel = (channelId) => {
export const leaveVoiceChannel = async (guildId) => { export const leaveVoiceChannel = async (guildId) => {
return await new Promise((res) => { return await new Promise((res) => {
io.timeout(25000).emit('leave_server', { guildId: guildId }, (status, clientRemainsOpen) => { io.timeout(25000).emit('leave_server', { guildId: guildId }, (status, clientRemainsOpen) => {
console.log("Discord client remains open?", clientRemainsOpen); log.INFO("Discord client remains open?", clientRemainsOpen);
res(clientRemainsOpen[0]) res(clientRemainsOpen[0])
}); });
}); });
@@ -88,13 +90,13 @@ export const setDiscordClientPrsense = (system) => {
// Placeholder functions (replace with actual implementation) // Placeholder functions (replace with actual implementation)
export const checkIfConnectedToVC = async (guildId) => { export const checkIfConnectedToVC = async (guildId) => {
console.log("Pdab process var:", pdabProcess); log.INFO("Pdab process var:", pdabProcess);
if (!pdabProcess) return false; if (!pdabProcess) return false;
return await new Promise((res) => { return await new Promise((res) => {
io.timeout(25000).emit('check_discord_vc_connected', { guildId: guildId }, (status, result) => { io.timeout(25000).emit('check_discord_vc_connected', { guildId: guildId }, (status, result) => {
console.log(`Discord VC connected for guild ${guildId}: ${result}`); log.INFO(`Discord VC connected for guild ${guildId}: ${result}`);
res((result[0])); res((result[0]));
}); });
}) })
@@ -103,7 +105,7 @@ export const checkIfConnectedToVC = async (guildId) => {
export const requestDiscordUsername = (guildId) => { export const requestDiscordUsername = (guildId) => {
return new Promise((res) => { return new Promise((res) => {
io.timeout(25000).emit('request_discord_username', { guildId: guildId }, (status, result) => { io.timeout(25000).emit('request_discord_username', { guildId: guildId }, (status, result) => {
console.log(`Discord username: ${result[0]}`); log.INFO(`Discord username: ${result[0]}`);
res(result[0]); res(result[0]);
}); });
}) })
@@ -112,7 +114,7 @@ export const requestDiscordUsername = (guildId) => {
export const checkIfClientIsOpen = () => { export const checkIfClientIsOpen = () => {
return new Promise((res) => { return new Promise((res) => {
io.timeout(25000).emit('check_client_is_open', (status, result) => { io.timeout(25000).emit('check_client_is_open', (status, result) => {
console.log(`Client is open: ${result}`); log.INFO(`Client is open: ${result}`);
res(result[0]) res(result[0])
}); });
}); });
@@ -121,7 +123,7 @@ export const checkIfClientIsOpen = () => {
export const requestDiscordID = () => { export const requestDiscordID = () => {
return new Promise((res) => { return new Promise((res) => {
io.timeout(25000).emit('request_discord_id', (status, result) => { io.timeout(25000).emit('request_discord_id', (status, result) => {
console.log(`Discord ID: ${result}`); log.INFO(`Discord ID: ${result}`);
res(result[0]); res(result[0]);
}); });
}); });

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "../modules/debugger.mjs";
const log = new DebugBuilder("client", "pdabWrappers");
import { connectToChannel, leaveVoiceChannel, checkIfConnectedToVC, initDiscordBotClient, requestDiscordUsername, requestDiscordID, requestDiscordClientClose, closePdabSocketServer, setDiscordClientPrsense, startPdabSocketServer } from './pdabHandler.mjs'; import { connectToChannel, leaveVoiceChannel, checkIfConnectedToVC, initDiscordBotClient, requestDiscordUsername, requestDiscordID, requestDiscordClientClose, closePdabSocketServer, setDiscordClientPrsense, startPdabSocketServer } from './pdabHandler.mjs';
import { openOP25, closeOP25 } from '../op25Handler/op25Handler.mjs'; import { openOP25, closeOP25 } from '../op25Handler/op25Handler.mjs';
@@ -8,38 +10,38 @@ let activeDiscordClient = undefined;
* @param {object} joinData The object containing all the information to join the server * @param {object} joinData The object containing all the information to join the server
*/ */
export const joinDiscordVC = async (joinData) => { export const joinDiscordVC = async (joinData) => {
console.log("Join requested: ", joinData); log.INFO("Join requested: ", joinData);
const connection = await new Promise(async (res) => { const connection = await new Promise(async (res) => {
// Check if a client already exists // Check if a client already exists
console.log("Checking if there is a client open"); log.INFO("Checking if there is a client open");
if (!await checkIfClientIsOpen()) { if (!await checkIfClientIsOpen()) {
console.log("There is no open client, starting it now"); log.INFO("There is no open client, starting it now");
await startPdabSocketServer(); await startPdabSocketServer();
// Open an instance of OP25 // Open an instance of OP25
console.log("Starting OP25") log.INFO("Starting OP25")
openOP25(joinData.system); openOP25(joinData.system);
// Open a new client and join the requested channel with the requested ID // Open a new client and join the requested channel with the requested ID
initDiscordBotClient(joinData.clientID, () => { initDiscordBotClient(joinData.clientID, () => {
console.log("Started PDAB"); log.INFO("Started PDAB");
console.log("Setting the presense of the bot"); log.INFO("Setting the presense of the bot");
setDiscordClientPrsense(joinData.system); setDiscordClientPrsense(joinData.system);
// Add the client object to the IO instance // Add the client object to the IO instance
console.log("Connecting to channel") log.INFO("Connecting to channel")
connectToChannel(joinData.channelID, (connectionStatus) => { connectToChannel(joinData.channelID, (connectionStatus) => {
console.log("Bot Connected to VC:", connectionStatus); log.INFO("Bot Connected to VC:", connectionStatus);
res(connectionStatus); res(connectionStatus);
}); });
}); });
} else { } else {
// Join the requested channel with the requested ID // Join the requested channel with the requested ID
console.log("There is an open client"); log.INFO("There is an open client");
console.log("Connecting to channel") log.INFO("Connecting to channel")
const connection = connectToChannel(joinData.channelID); const connection = connectToChannel(joinData.channelID);
console.log("Bot Connected to VC::"); log.INFO("Bot Connected to VC::");
res(connection); res(connection);
} }
}); });
@@ -52,12 +54,12 @@ export const joinDiscordVC = async (joinData) => {
* @param {string} guildId The guild ID to disconnect from VC * @param {string} guildId The guild ID to disconnect from VC
*/ */
export const leaveDiscordVC = async (guildId) => { export const leaveDiscordVC = async (guildId) => {
console.log("Leave requested"); log.INFO("Leave requested");
if (await checkIfConnectedToVC(guildId)) { if (await checkIfConnectedToVC(guildId)) {
const clientRemainsOpen = await leaveVoiceChannel(guildId); const clientRemainsOpen = await leaveVoiceChannel(guildId);
console.log("Client should remain open: ", clientRemainsOpen); log.INFO("Client should remain open: ", clientRemainsOpen);
if (!clientRemainsOpen) { if (!clientRemainsOpen) {
console.log("There are no open VC connections"); log.INFO("There are no open VC connections");
await closeOP25(); await closeOP25();
// Close the python client // Close the python client
@@ -75,9 +77,9 @@ export const leaveDiscordVC = async (guildId) => {
* @returns {boolean} If the node is connected to VC in the given guild * @returns {boolean} If the node is connected to VC in the given guild
*/ */
export const checkIfDiscordVCConnected = async (guildId) => { export const checkIfDiscordVCConnected = async (guildId) => {
console.log("Requested status check"); log.INFO("Requested status check");
if (await checkIfConnectedToVC(guildId)) { if (await checkIfConnectedToVC(guildId)) {
console.log("There is an open VC connection"); log.INFO("There is an open VC connection");
return (true); return (true);
} else { } else {
return (false); return (false);
@@ -91,7 +93,7 @@ export const checkIfDiscordVCConnected = async (guildId) => {
* @returns {string} The username of the bot in the given guild's VC * @returns {string} The username of the bot in the given guild's VC
*/ */
export const getDiscordUsername = async (guildId) => { export const getDiscordUsername = async (guildId) => {
console.log("Requested username"); log.INFO("Requested username");
if (checkIfClientIsOpen()) { if (checkIfClientIsOpen()) {
return await requestDiscordUsername(guildId) return await requestDiscordUsername(guildId)
} else return (undefined); } else return (undefined);
@@ -102,7 +104,7 @@ export const getDiscordUsername = async (guildId) => {
* @returns {string} The ID of the active client * @returns {string} The ID of the active client
*/ */
export const getDiscordID = async () => { export const getDiscordID = async () => {
console.log("Requested ID"); log.INFO("Requested ID");
if (checkIfClientIsOpen()) { if (checkIfClientIsOpen()) {
return await requestDiscordID(); return await requestDiscordID();
} }

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "../../modules/debugger.mjs";
const log = new DebugBuilder("client", "client.express.setupRoutes");
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import express from 'express'; import express from 'express';
@@ -15,7 +17,7 @@ let nodeData = {};
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
const output = await launchProcess('python', ['./discordAudioBot/pdab/getDevices.py'], true, true) const output = await launchProcess('python', ['./discordAudioBot/pdab/getDevices.py'], true, true)
console.log("Device List", output); log.INFO("Device List", output);
res.render('setup/setup', { deviceList: output }); res.render('setup/setup', { deviceList: output });
}); });
@@ -28,7 +30,7 @@ router.post('/', (req, res) => {
// Handle form submission here // Handle form submission here
const { clientName, clientLocation, clientCapabilities, audioDeviceId } = req.body; const { clientName, clientLocation, clientCapabilities, audioDeviceId } = req.body;
console.log(clientName, clientLocation, clientCapabilities, audioDeviceId); log.INFO(clientName, clientLocation, clientCapabilities, audioDeviceId);
nodeData.clientName = clientName; nodeData.clientName = clientName;
nodeData.clientLocation = clientLocation; nodeData.clientLocation = clientLocation;
@@ -44,11 +46,11 @@ router.post('/add-system', (req, res) => {
// Store system information for later use // Store system information for later use
// For now, let's just log the information // For now, let's just log the information
console.log('System Name:', systemName); log.INFO('System Name:', systemName);
console.log('Frequencies:', frequencies); log.INFO('Frequencies:', frequencies);
console.log('Mode:', mode); log.INFO('Mode:', mode);
console.log('Trunk File:', trunkFile); log.INFO('Trunk File:', trunkFile);
console.log('Whitelist File:', whitelistFile); log.INFO('Whitelist File:', whitelistFile);
// Store system information in the array // Store system information in the array
systemsData.push({ systemsData.push({
@@ -67,7 +69,7 @@ router.post('/add-system', (req, res) => {
router.post('/finish-setup', async (req, res) => { router.post('/finish-setup', async (req, res) => {
// Write collected information to .env file // Write collected information to .env file
// For now, let's just log the collected information // For now, let's just log the collected information
console.log('Collected System Information:', nodeData, systemsData); log.INFO('Collected System Information:', nodeData, systemsData);
if (!await exportCsv(nodeData)) return res.status(500).send('Error writing to .env file'); if (!await exportCsv(nodeData)) return res.status(500).send('Error writing to .env file');
@@ -82,7 +84,7 @@ export default router;
const exportCsv = (nodeData) => { const exportCsv = (nodeData) => {
const nuid = generateUniqueID(); const nuid = generateUniqueID();
console.log(`Generated a new unique ID for this node: '${nuid}'`); log.INFO(`Generated a new unique ID for this node: '${nuid}'`);
const envData = { const envData = {
CLIENT_NUID: nuid, CLIENT_NUID: nuid,
CLIENT_NAME: nodeData.clientName, CLIENT_NAME: nodeData.clientName,
@@ -109,10 +111,10 @@ const exportCsv = (nodeData) => {
// File doesn't exist, create it // File doesn't exist, create it
fs.writeFile('.env', envContent, (writeErr) => { fs.writeFile('.env', envContent, (writeErr) => {
if (writeErr) { if (writeErr) {
console.error('Error writing to .env file:', writeErr); log.ERROR('Error writing to .env file:', writeErr);
res(false); res(false);
} else { } else {
console.log('.env file created successfully'); log.INFO('.env file created successfully');
res(true); res(true);
} }
}); });
@@ -120,10 +122,10 @@ const exportCsv = (nodeData) => {
// File exists, update it // File exists, update it
fs.writeFile('.env', envContent, (writeErr) => { fs.writeFile('.env', envContent, (writeErr) => {
if (writeErr) { if (writeErr) {
console.error('Error writing to .env file:', writeErr); log.ERROR('Error writing to .env file:', writeErr);
res(false); res(false);
} else { } else {
console.log('.env file updated successfully'); log.INFO('.env file updated successfully');
res(true); res(true);
} }
}); });
@@ -155,10 +157,10 @@ const exportSystems = (systemsData) => {
// File doesn't exist, create it // File doesn't exist, create it
fs.writeFile(radioPresetsPath, JSON.stringify(radioPresetsData, null, 4), (writeErr) => { fs.writeFile(radioPresetsPath, JSON.stringify(radioPresetsData, null, 4), (writeErr) => {
if (writeErr) { if (writeErr) {
console.error('Error writing to radioPresets.json:', writeErr); log.ERROR('Error writing to radioPresets.json:', writeErr);
res(false); res(false);
} else { } else {
console.log('radioPresets.json created successfully'); log.INFO('radioPresets.json created successfully');
res(true); res(true);
} }
}); });
@@ -166,10 +168,10 @@ const exportSystems = (systemsData) => {
// File exists, update it // File exists, update it
fs.writeFile(radioPresetsPath, JSON.stringify(radioPresetsData, null, 4), (writeErr) => { fs.writeFile(radioPresetsPath, JSON.stringify(radioPresetsData, null, 4), (writeErr) => {
if (writeErr) { if (writeErr) {
console.error('Error writing to radioPresets.json:', writeErr); log.ERROR('Error writing to radioPresets.json:', writeErr);
res(false); res(false);
} else { } else {
console.log('radioPresets.json updated successfully'); log.INFO('radioPresets.json updated successfully');
res(true); res(true);
} }
}); });

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "../modules/debugger.mjs";
const log = new DebugBuilder("client", "client.express.server");
import express from 'express'; import express from 'express';
import http from 'http'; import http from 'http';
import path from 'path'; import path from 'path';
@@ -19,7 +21,7 @@ const startServer = (port, openSocket) => {
if (openSocket) isSetupComplete = true; if (openSocket) isSetupComplete = true;
server.listen(port, () => { server.listen(port, () => {
console.log(`Server running on port ${port}`); log.INFO(`Server running on port ${port}`);
}); });
}; };

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "./modules/debugger.mjs";
const log = new DebugBuilder("client", "cliHandler");
import { spawn } from "child_process"; import { spawn } from "child_process";
/** /**
@@ -18,7 +20,7 @@ export const executeCommand = (command, args) => {
childProcess.stderr.on('data', (data) => { childProcess.stderr.on('data', (data) => {
// Log any errors to stderr // Log any errors to stderr
console.error(data.toString()); log.ERROR(data.toString());
}); });
childProcess.on('error', (error) => { childProcess.on('error', (error) => {

67
modules/debugger.mjs Normal file
View File

@@ -0,0 +1,67 @@
// Import necessary modules
import debug from 'debug';
import { config } from 'dotenv';
import { writeFile } from 'fs';
import { inspect } from 'util';
// Load environment variables
config();
const logLocation = process.env.LOG_LOCATION;
const writeToLog = async (logMessage, appName) => {
logMessage = `${String(logMessage)}\n`;
writeFile(
logLocation ?? `./${appName}.log`,
logMessage,
{ encoding: "utf-8", flag: 'a+' },
(err) => {
if (err) console.error(err);
}
);
};
/**
* Create the different logging methods for a function
* Namespace template = ("[app]:[fileName]:['INFO', 'WARNING', 'DEBUG', 'ERROR']")
* @param {string} appName The name of the app to be used in the 'app' portion of the namespace
* @param {string} fileName The name of the file calling the builder to be used in the 'fileName' portion of the namespace
*/
export class DebugBuilder {
constructor(appName, fileName) {
this.INFO = (...messageParts) => {
const _info = debug(`${appName}:${fileName}:INFO`);
_info(messageParts);
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:INFO\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
};
this.DEBUG = (...messageParts) => {
const _debug = debug(`${appName}:${fileName}:DEBUG`);
_debug(messageParts);
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:DEBUG\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
};
this.VERBOSE = (...messageParts) => {
const _verbose = debug(`${appName}:${fileName}:VERBOSE`);
_verbose(messageParts);
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:VERBOSE\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
};
this.WARN = (...messageParts) => {
const _warn = debug(`${appName}:${fileName}:WARNING`);
_warn(messageParts);
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:WARNING\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
};
this.ERROR = (...messageParts) => {
const _error = debug(`${appName}:${fileName}:ERROR`);
_error(messageParts);
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:ERROR\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
if (process.env.EXIT_ON_ERROR && process.env.EXIT_ON_ERROR > 0) {
writeToLog("!--- EXITING ---!", appName);
setTimeout(() => process.exit(), process.env.EXIT_ON_ERROR_DELAY ?? 0);
}
};
}
}

View File

@@ -1,4 +1,6 @@
// Modules // Modules
import { DebugBuilder } from "../modules/debugger.mjs";
const log = new DebugBuilder("client", "radioPresetsHandler");
import { writeFile, existsSync, readFileSync } from 'fs'; import { writeFile, existsSync, readFileSync } from 'fs';
import { resolve } from "path"; import { resolve } from "path";
import { ensureDirectoryExists } from "./baseUtils.mjs"; import { ensureDirectoryExists } from "./baseUtils.mjs";
@@ -16,12 +18,12 @@ const configFilePath = process.env.CONFIG_PATH;
* @param {function} callback The function to be called when this wrapper completes * @param {function} callback The function to be called when this wrapper completes
*/ */
const writePresets = async (presets, callback = undefined) => { const writePresets = async (presets, callback = undefined) => {
console.log(`${__dirname}`); log.INFO(`${__dirname}`);
await ensureDirectoryExists(configFilePath); await ensureDirectoryExists(configFilePath);
writeFile(configFilePath, JSON.stringify(presets), (err) => { writeFile(configFilePath, JSON.stringify(presets), (err) => {
// Error checking // Error checking
if (err) throw err; if (err) throw err;
console.log("Write Complete"); log.INFO("Write Complete");
if (callback) callback(); else return if (callback) callback(); else return
}); });
} }
@@ -38,7 +40,7 @@ const sanitizeFrequencies = async (frequenciesArray) => {
sanitizedFrequencyArray.push(convertFrequencyToHertz(freq)); sanitizedFrequencyArray.push(convertFrequencyToHertz(freq));
} }
console.log("Sanitized Frequency Array", sanitizedFrequencyArray); log.INFO("Sanitized Frequency Array", sanitizedFrequencyArray);
return sanitizedFrequencyArray; return sanitizedFrequencyArray;
} }
@@ -51,19 +53,19 @@ const convertFrequencyToHertz = async (frequency) => {
// check if the passed value is a number // check if the passed value is a number
if (typeof frequency == 'number' && !isNaN(frequency)) { if (typeof frequency == 'number' && !isNaN(frequency)) {
if (Number.isInteger(frequency)) { if (Number.isInteger(frequency)) {
console.log(`${frequency} is an integer.`); log.INFO(`${frequency} is an integer.`);
// Check to see if the frequency has the correct length // Check to see if the frequency has the correct length
if (frequency >= 1000000) return frequency if (frequency >= 1000000) return frequency
if (frequency >= 100 && frequency <= 999) return frequency * 1000000 if (frequency >= 100 && frequency <= 999) return frequency * 1000000
console.log("Frequency hasn't matched filters: ", frequency); log.INFO("Frequency hasn't matched filters: ", frequency);
} }
else { else {
console.log(`${frequency} is a float value.`); log.INFO(`${frequency} is a float value.`);
// Convert to a string to remove the decimal in place and then correct the length // Convert to a string to remove the decimal in place and then correct the length
return parseInt(converter(frequency).from("MHz").to("Hz")); return parseInt(converter(frequency).from("MHz").to("Hz"));
} }
} else { } else {
console.log(`${frequency} is not a number`); log.INFO(`${frequency} is not a number`);
frequency = convertFrequencyToHertz(parseFloat(frequency)); frequency = convertFrequencyToHertz(parseFloat(frequency));
return parseInt(frequency) return parseInt(frequency)
@@ -79,7 +81,7 @@ export const getAllPresets = () => {
if (!configFilePath) return {}; if (!configFilePath) return {};
const presetDir = resolve(configFilePath); const presetDir = resolve(configFilePath);
console.log(`Getting presets from directory: '${presetDir}'`); log.INFO(`Getting presets from directory: '${presetDir}'`);
if (existsSync(presetDir)) return JSON.parse(readFileSync(presetDir)); if (existsSync(presetDir)) return JSON.parse(readFileSync(presetDir));
else return {}; else return {};
} }

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "./debugger.mjs";
const log = new DebugBuilder("client", "selfUpdater");
import simpleGit from 'simple-git'; import simpleGit from 'simple-git';
import { restartService } from './serviceHandler.mjs' import { restartService } from './serviceHandler.mjs'
import { launchProcess } from './subprocessHandler.mjs' import { launchProcess } from './subprocessHandler.mjs'
@@ -17,14 +19,14 @@ export const checkForUpdates = async () => {
const localCommitHash = await git.revparse(['HEAD']); const localCommitHash = await git.revparse(['HEAD']);
if (latestCommitHash !== localCommitHash) { if (latestCommitHash !== localCommitHash) {
console.log('An update is available. Updating...'); log.INFO('An update is available. Updating...');
// Check if there have been any changes to the code // Check if there have been any changes to the code
const gitStatus = await git.status() const gitStatus = await git.status()
console.log(gitStatus); log.INFO(gitStatus);
if (gitStatus.modified.length > 0){ if (gitStatus.modified.length > 0){
// There is locally modified code // There is locally modified code
console.log("There is locally modified code, resetting..."); log.INFO("There is locally modified code, resetting...");
await git.stash(); await git.stash();
await git.reset('hard', ['origin/master']); await git.reset('hard', ['origin/master']);
} }
@@ -33,25 +35,25 @@ export const checkForUpdates = async () => {
await git.pull(); await git.pull();
// Run the post-update script // Run the post-update script
console.log('Running post-update script...'); log.INFO('Running post-update script...');
await launchProcess("bash", ['./post-update.sh'], true); await launchProcess("bash", ['./post-update.sh'], true);
// Restart the application to apply the updates // Restart the application to apply the updates
console.log('Update completed successfully. Restarting the application...'); log.INFO('Update completed successfully. Restarting the application...');
restartApplication(); restartApplication();
return true return true
} else { } else {
console.log('The application is up to date.'); log.INFO('The application is up to date.');
return false return false
} }
} catch (error) { } catch (error) {
console.error('Error checking for updates:', error); log.ERROR('Error checking for updates:', error);
} }
} }
// Function to restart the application // Function to restart the application
export const restartApplication = () => { export const restartApplication = () => {
console.log('Restarting the application...'); log.INFO('Restarting the application...');
restartService('discord-radio-bot'); restartService('discord-radio-bot');
} }

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "./modules/debugger.mjs";
const log = new DebugBuilder("client", "serviceHandler");
import { exec } from 'child_process'; import { exec } from 'child_process';
/** /**
@@ -9,7 +11,7 @@ const executeCommand = (command) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => { exec(command, (error, stdout, stderr) => {
if (error) { if (error) {
console.error(`Command failed with error: ${error.message}`); log.ERROR(`Command failed with error: ${error.message}`);
resolve({ stdout, stderr }); resolve({ stdout, stderr });
} else { } else {
resolve({ stdout, stderr }); resolve({ stdout, stderr });
@@ -27,7 +29,7 @@ export const startService = async (serviceName) => {
try { try {
await executeCommand(`sudo systemctl start ${serviceName}.service`); await executeCommand(`sudo systemctl start ${serviceName}.service`);
} catch (error) { } catch (error) {
console.error(`Failed to start service: ${error.message}`); log.ERROR(`Failed to start service: ${error.message}`);
} }
}; };
@@ -40,7 +42,7 @@ export const restartService = async (serviceName) => {
try { try {
await executeCommand(`sudo systemctl restart ${serviceName}.service`); await executeCommand(`sudo systemctl restart ${serviceName}.service`);
} catch (error) { } catch (error) {
console.error(`Failed to restart service: ${error.message}`); log.ERROR(`Failed to restart service: ${error.message}`);
} }
}; };
@@ -53,6 +55,6 @@ export const stopService = async (serviceName) => {
try { try {
await executeCommand(`sudo systemctl stop ${serviceName}.service`); await executeCommand(`sudo systemctl stop ${serviceName}.service`);
} catch (error) { } catch (error) {
console.error(`Failed to stop service: ${error.message}`); log.ERROR(`Failed to stop service: ${error.message}`);
} }
}; };

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "./debugger.mjs";
const log = new DebugBuilder("client", "socketClient");
import { io } from "socket.io-client"; import { io } from "socket.io-client";
import { logIntoServerWrapper, nodeCheckStatus, nodeJoinServer, nodeLeaveServer, nodeGetUsername, nodeCheckDiscordClientStatus, nodeCheckCurrentSystem, nodeUpdate, nodeGetDiscordID } from "./socketClientWrappers.mjs"; import { logIntoServerWrapper, nodeCheckStatus, nodeJoinServer, nodeLeaveServer, nodeGetUsername, nodeCheckDiscordClientStatus, nodeCheckCurrentSystem, nodeUpdate, nodeGetDiscordID } from "./socketClientWrappers.mjs";
@@ -14,13 +16,13 @@ export const initSocketConnection = async (localNodeConfig) => {
// Socket Events ('system' events persay) // Socket Events ('system' events persay)
// When the socket connects to the node server // When the socket connects to the node server
socket.on('connect', async () => { socket.on('connect', async () => {
console.log('Connected to the server'); log.INFO('Connected to the server');
await logIntoServerWrapper(socket, localNodeConfig); await logIntoServerWrapper(socket, localNodeConfig);
}); });
// When the socket disconnects from the node server // When the socket disconnects from the node server
socket.on('disconnect', () => { socket.on('disconnect', () => {
console.log('Disconnected from the server'); log.INFO('Disconnected from the server');
}); });
// Node events/commands // Node events/commands

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "./debugger.mjs";
const log = new DebugBuilder("client", "subprocessHandler");
import { spawn } from "child_process"; import { spawn } from "child_process";
import dotenv from 'dotenv'; import dotenv from 'dotenv';
dotenv.config() dotenv.config()
@@ -35,14 +37,14 @@ export const launchProcess = (processName, args, waitForClose = false, returnOut
// Get the stdout from the child process // Get the stdout from the child process
childProcess.stdout.setEncoding('utf8'); childProcess.stdout.setEncoding('utf8');
childProcess.stdout.on('data', (data) => { childProcess.stdout.on('data', (data) => {
if (process.env.NODE_ENV === "development") console.log(`Data from ${processName}:`, data); if (process.env.NODE_ENV === "development") log.INFO(`Data from ${processName}:`, data);
scriptOutput += data.toString(); scriptOutput += data.toString();
}); });
// Get the stderr from the child process // Get the stderr from the child process
childProcess.stderr.setEncoding('utf8'); childProcess.stderr.setEncoding('utf8');
childProcess.stderr.on('data', (data) => { childProcess.stderr.on('data', (data) => {
if (process.env.NODE_ENV === "development") console.log(`Data from ${processName}:`, data); if (process.env.NODE_ENV === "development") log.INFO(`Data from ${processName}:`, data);
scriptOutput += data.toString(); scriptOutput += data.toString();
}) })
@@ -50,8 +52,8 @@ export const launchProcess = (processName, args, waitForClose = false, returnOut
childProcess.on('exit', (code, signal) => { childProcess.on('exit', (code, signal) => {
// Remove reference to the process when it exits // Remove reference to the process when it exits
delete runningProcesses[processName]; delete runningProcesses[processName];
console.log(`${processName} process exited with code ${code} and signal ${signal}`); log.INFO(`${processName} process exited with code ${code} and signal ${signal}`);
console.log("Child process console output: ", scriptOutput); log.INFO("Child process console output: ", scriptOutput);
// Return the full script output if requested // Return the full script output if requested
if (returnOutput === true) { if (returnOutput === true) {
return res(scriptOutput) return res(scriptOutput)
@@ -64,9 +66,9 @@ export const launchProcess = (processName, args, waitForClose = false, returnOut
return output return output
} }
console.log(`${processName} process started.`); log.INFO(`${processName} process started.`);
} else { } else {
console.log(`${processName} process is already running.`); log.INFO(`${processName} process is already running.`);
} }
} }
@@ -97,9 +99,9 @@ export const killProcess = (processName) => {
const childProcess = runningProcesses[processName]; const childProcess = runningProcesses[processName];
if (childProcess) { if (childProcess) {
childProcess.kill(); childProcess.kill();
console.log(`${processName} process killed.`); log.INFO(`${processName} process killed.`);
} else { } else {
console.log(`${processName} process is not running.`); log.INFO(`${processName} process is not running.`);
} }
} }

View File

@@ -1,4 +1,6 @@
// Modules // Modules
import { DebugBuilder } from "./debugger.mjs";
const log = new DebugBuilder("client", "updateConfig");
import replace from 'replace-in-file'; import replace from 'replace-in-file';
class Options { class Options {
@@ -19,7 +21,7 @@ class Options {
export const updateId = async (updatedId) => { export const updateId = async (updatedId) => {
await updateConfig('CLIENT_NUID', updatedId); await updateConfig('CLIENT_NUID', updatedId);
process.env.CLIENT_NUID = updatedId; process.env.CLIENT_NUID = updatedId;
console.log("Updated NUID to: ", updatedId); log.INFO("Updated NUID to: ", updatedId);
} }
/** /**
@@ -49,7 +51,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
this.updateConfig('CLIENT_NAME', newConfigObject.name); this.updateConfig('CLIENT_NAME', newConfigObject.name);
updatedKeys.push({ 'CLIENT_NAME': newConfigObject.name }); updatedKeys.push({ 'CLIENT_NAME': newConfigObject.name });
process.env.CLIENT_NAME = newConfigObject.name; process.env.CLIENT_NAME = newConfigObject.name;
console.log("Updated name to: ", newConfigObject.name); log.INFO("Updated name to: ", newConfigObject.name);
} }
} }
if (configKeys.includes("ip")) { if (configKeys.includes("ip")) {
@@ -57,7 +59,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
this.updateConfig('CLIENT_IP', newConfigObject.ip); this.updateConfig('CLIENT_IP', newConfigObject.ip);
updatedKeys.push({ 'CLIENT_IP': newConfigObject.ip }); updatedKeys.push({ 'CLIENT_IP': newConfigObject.ip });
process.env.CLIENT_IP = newConfigObject.ip; process.env.CLIENT_IP = newConfigObject.ip;
console.log("Updated ip to: ", newConfigObject.ip); log.INFO("Updated ip to: ", newConfigObject.ip);
} }
} }
if (configKeys.includes("port")) { if (configKeys.includes("port")) {
@@ -65,7 +67,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
this.updateConfig('CLIENT_PORT', newConfigObject.port); this.updateConfig('CLIENT_PORT', newConfigObject.port);
updatedKeys.push({ 'CLIENT_PORT': newConfigObject.port }); updatedKeys.push({ 'CLIENT_PORT': newConfigObject.port });
process.env.CLIENT_PORT = newConfigObject.port; process.env.CLIENT_PORT = newConfigObject.port;
console.log("Updated port to: ", newConfigObject.port); log.INFO("Updated port to: ", newConfigObject.port);
} }
} }
if (configKeys.includes("location")) { if (configKeys.includes("location")) {
@@ -73,7 +75,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
this.updateConfig('CLIENT_LOCATION', newConfigObject.location); this.updateConfig('CLIENT_LOCATION', newConfigObject.location);
updatedKeys.push({ 'CLIENT_LOCATION': newConfigObject.location }); updatedKeys.push({ 'CLIENT_LOCATION': newConfigObject.location });
process.env.CLIENT_LOCATION = newConfigObject.location; process.env.CLIENT_LOCATION = newConfigObject.location;
console.log("Updated location to: ", newConfigObject.location); log.INFO("Updated location to: ", newConfigObject.location);
} }
} }
@@ -88,7 +90,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
export function updateConfig (key, value) { export function updateConfig (key, value) {
const options = new Options(key, value); const options = new Options(key, value);
console.log("Options:", options); log.INFO("Options:", options);
updateConfigFile(options, (updatedFiles) => { updateConfigFile(options, (updatedFiles) => {
// Do Something // Do Something
@@ -102,8 +104,8 @@ export function updateConfig (key, value) {
*/ */
function updateConfigFile(options, callback) { function updateConfigFile(options, callback) {
replace(options, (error, changedFiles) => { replace(options, (error, changedFiles) => {
if (error) return console.error('Error occurred:', error); if (error) return log.ERROR('Error occurred:', error);
console.log('Updated config file: ', changedFiles); log.INFO('Updated config file: ', changedFiles);
callback(changedFiles); callback(changedFiles);
}); });
} }

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "../../modules/debugger.mjs";
const log = new DebugBuilder("client", "op25ConfigGenerator");
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
class OP25ConfigObject { class OP25ConfigObject {
@@ -7,9 +9,9 @@ class OP25ConfigObject {
try { try {
const jsonConfig = JSON.stringify(this, null, 2); const jsonConfig = JSON.stringify(this, null, 2);
await fs.writeFile(filename, jsonConfig); await fs.writeFile(filename, jsonConfig);
console.log(`Config exported to ${filename}`); log.INFO(`Config exported to ${filename}`);
} catch (error) { } catch (error) {
console.error(`Error exporting config to ${filename}: ${error}`); log.ERROR(`Error exporting config to ${filename}: ${error}`);
} }
} }
} }
@@ -17,7 +19,7 @@ class OP25ConfigObject {
export class P25ConfigGenerator extends OP25ConfigObject { export class P25ConfigGenerator extends OP25ConfigObject {
constructor({ systemName, controlChannels, tagsFile, whitelistFile = undefined }) { constructor({ systemName, controlChannels, tagsFile, whitelistFile = undefined }) {
super(); super();
console.log("Generating P25 Config for:", systemName); log.INFO("Generating P25 Config for:", systemName);
const controlChannelsString = controlChannels.join(','); const controlChannelsString = controlChannels.join(',');
this.channels = [new channelConfig({ this.channels = [new channelConfig({
"channelName": systemName, "channelName": systemName,

View File

@@ -1,3 +1,5 @@
import { DebugBuilder } from "../modules/debugger.mjs";
const log = new DebugBuilder("client", "op25Handler");
import { P25ConfigGenerator, NBFMConfigGenerator } from './modules/op25ConfigGenerators.mjs'; import { P25ConfigGenerator, NBFMConfigGenerator } from './modules/op25ConfigGenerators.mjs';
import { getAllPresets } from '../modules/radioPresetHandler.mjs'; import { getAllPresets } from '../modules/radioPresetHandler.mjs';
import { startService, stopService } from '../modules/serviceHandler.mjs'; import { startService, stopService } from '../modules/serviceHandler.mjs';
@@ -17,7 +19,7 @@ const createConfigAndRestartService = async (systemName, preset) => {
let generator; let generator;
if (mode === 'p25') { if (mode === 'p25') {
console.log("Using P25 Config Generator based on preset mode", systemName, mode); log.INFO("Using P25 Config Generator based on preset mode", systemName, mode);
generator = new P25ConfigGenerator({ generator = new P25ConfigGenerator({
systemName, systemName,
controlChannels: frequencies, controlChannels: frequencies,
@@ -25,7 +27,7 @@ const createConfigAndRestartService = async (systemName, preset) => {
whitelistFile: whitelistFile !== 'none' ? whitelistFile : undefined whitelistFile: whitelistFile !== 'none' ? whitelistFile : undefined
}); });
} else if (mode === 'nbfm') { } else if (mode === 'nbfm') {
console.log("Using NBFM Config Generator based on preset mode", systemName, mode); log.INFO("Using NBFM Config Generator based on preset mode", systemName, mode);
generator = new NBFMConfigGenerator({ generator = new NBFMConfigGenerator({
systemName, systemName,
frequencies, frequencies,
@@ -56,7 +58,7 @@ export const openOP25 = async (systemName) => {
const presets = await getAllPresets(); const presets = await getAllPresets();
const preset = presets[systemName]; const preset = presets[systemName];
console.log("Found preset:", preset); log.INFO("Found preset:", preset);
if (!preset) { if (!preset) {
throw new Error(`Preset for system "${systemName}" not found.`); throw new Error(`Preset for system "${systemName}" not found.`);