// Debug const { DebugBuilder } = require("../utilities/debugBuilder.js"); const log = new DebugBuilder("client", "botController"); const botLog = new DebugBuilder("client", "botController:bot"); // Modules const spawn = require('child_process').spawn; const { resolve } = require("path"); require('dotenv').config(); const { closeProcessWrapper } = require("../utilities/utilities"); // Global vars let pythonProcess; let recordingProcess; /** * Get Status of the discord process */ exports.getStatus = (req, res) => { log.INFO("Getting the status of the bot"); if (pythonProcess) return res.sendStatus(200); return res.sendStatus(201); } /** * Start the bot and join the server and preset specified */ exports.joinServer = async (req, res) => { if (!req.body.clientId || !req.body.channelId) return res.status(500).json({"message": "You must include the client ID (discord token), channel ID (The discord ID of the channel to connect to)"}); const deviceId = process.env.AUDIO_DEVICE_ID; const channelId = req.body.channelId; const clientId = req.body.clientId; const presetName = req.body.presetName; const NGThreshold = req.body.NGThreshold ?? 50 // Joining the discord server log.INFO("Join requested to: ", deviceId, channelId, clientId, presetName, NGThreshold); if (process.platform === "win32") { log.DEBUG("Starting Windows Python"); pythonProcess = await spawn('python.exe', [resolve(__dirname, "../pdab/main.py"), deviceId, channelId, clientId, '-n', NGThreshold, '-p', presetName ], { cwd: resolve(__dirname, "../pdab/").toString() }); //pythonProcess = await spawn('C:\\Python310\\python.exe', [resolve(__dirname, "../PDAB/main.py"), deviceId, channelId, clientId, NGThreshold ]); } else { log.DEBUG("Starting Linux Python"); pythonProcess = await spawn('python3', [resolve(__dirname, "../pdab/main.py"), deviceId, channelId, clientId,'-n', NGThreshold, '-p', presetName ], { cwd: resolve(__dirname, "../pdab/") }); } log.VERBOSE("Python Process: ", pythonProcess); let fullOutput; pythonProcess.stdout.setEncoding('utf8'); pythonProcess.stdout.on("data", (data) => { botLog.VERBOSE("From Process: ", data); fullOutput += data.toString(); }); pythonProcess.stderr.on('data', (data) => { botLog.VERBOSE(`stderr: ${data}`); fullOutput += data.toString(); }); pythonProcess.on('close', (code) => { log.DEBUG(`child process exited with code ${code}`); log.VERBOSE("Full output from bot: ", fullOutput); }); pythonProcess.on("error", (code, signal) => { log.ERROR("Error from the discord bot process: ", code, signal); }); // Starting the radio application return res.sendStatus(200); } /** * Leaves the server if it's in one */ exports.leaveServer = async (req, res) => { log.INFO("Leaving the server"); if (!pythonProcess) return res.sendStatus(200) pythonProcess = await closeProcessWrapper(pythonProcess); return res.sendStatus(202); } /** * Start a recording of what the bot is listening to, if it's currently connected * * @param {*} req * @param {*} res */ exports.startRecording = async (req, res) => { log.INFO("Starting recording") //if (pythonProcess === undefined) return res.sendStatus(204); if (!recordingProcess === undefined) return res.sendStatus(202); const deviceId = process.env.AUDIO_DEVICE_ID; const filename = "./recordings/" + new Date().toJSON().slice(0,10) + ".wav"; // Joining the server to record log.INFO("Start recording: ", deviceId, filename); if (process.platform === "win32") { log.DEBUG("Starting Windows Python"); recordingProcess = await spawn('python', [resolve(__dirname, "../pdab/recorder.py"), deviceId, filename ], { cwd: resolve(__dirname, "../pdab/").toString() }); } else { log.DEBUG("Starting Linux Python"); recordingProcess = await spawn('python3', [resolve(__dirname, "../pdab/recorder.py"), deviceId, filename ], { cwd: resolve(__dirname, "../pdab/") }); } await this.getProcessOutput(recordingProcess); return res.sendStatus(200); } /** * Stop the recording if the bot is currently recording * * @param {*} req * @param {*} res */ exports.stopRecording = async (req, res) => { log.INFO("Stopping recording the server"); if (!recordingProcess) return res.sendStatus(202) recordingProcess = await closeProcessWrapper(recordingProcess); return res.sendStatus(200); } /** * Get the output of a running process * * @param {*} runningProcess * @returns */ exports.getProcessOutput = async (runningProcess) => { let fullOutput; runningProcess.stdout.setEncoding('utf8'); runningProcess.stdout.on("data", (data) => { botLog.VERBOSE("From Process: ", data); fullOutput += data.toString(); }); runningProcess.stderr.on('data', (data) => { botLog.VERBOSE(`stderr: ${data}`); fullOutput += data.toString(); }); runningProcess.on('close', (code) => { log.DEBUG(`child process exited with code ${code}`); log.VERBOSE("Full output from bot: ", fullOutput); }); runningProcess.on("error", (code, signal) => { log.ERROR("Error from the process: ", code, signal); }); }