Compare commits
1 Commits
597546b73d
...
feature/#1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77deb3ba2b |
@@ -35,12 +35,12 @@ exports.joinServer = async (req, res) => {
|
||||
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('python.exe', [resolve(__dirname, "../pdab/main.py"), deviceId, channelId, clientId, '-n', NGThreshold], { 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/") });
|
||||
pythonProcess = await spawn('python3', [resolve(__dirname, "../pdab/main.py"), deviceId, channelId, clientId,'-n', NGThreshold ], { cwd: resolve(__dirname, "../pdab/") });
|
||||
}
|
||||
|
||||
log.VERBOSE("Python Process: ", pythonProcess);
|
||||
|
||||
@@ -67,11 +67,6 @@ async function checkLocalIP() {
|
||||
* Checks the config file for all required fields or gets and updates the required fields
|
||||
*/
|
||||
exports.checkConfig = async function checkConfig() {
|
||||
if (!runningClientConfig.id || runningClientConfig.id == 0 || runningClientConfig.id == '0') {
|
||||
updateConfig('id', "");
|
||||
runningClientConfig.id = null;
|
||||
}
|
||||
|
||||
if (!runningClientConfig.ip) {
|
||||
const ipAddr = await checkLocalIP();
|
||||
updateConfig('ip', ipAddr);
|
||||
@@ -102,10 +97,10 @@ exports.checkIn = async () => {
|
||||
await this.checkConfig();
|
||||
// Check if there is an ID found, if not add the node to the server. If there was an ID, check in with the server to make sure it has the correct information
|
||||
try {
|
||||
if (!runningClientConfig?.id || runningClientConfig.id == null) {
|
||||
if (runningClientConfig.id === 0) {
|
||||
// ID was not found in the config, creating a new node
|
||||
reqOptions = new requestOptions("/nodes/newNode", "POST");
|
||||
sendHttpRequest(reqOptions, JSON.stringify({}), (responseObject) => {
|
||||
sendHttpRequest(reqOptions, JSON.stringify(), (responseObject) => {
|
||||
// Update the client's ID if the server accepted it
|
||||
if (responseObject.statusCode === 202) {
|
||||
runningClientConfig.id = responseObject.body.nodeId;
|
||||
@@ -114,7 +109,6 @@ exports.checkIn = async () => {
|
||||
|
||||
if (responseObject.statusCode >= 300) {
|
||||
// Server threw an error
|
||||
log.DEBUG("HTTP Error: ", responseObject);
|
||||
onHttpError(responseObject.statusCode);
|
||||
}
|
||||
|
||||
@@ -124,7 +118,6 @@ exports.checkIn = async () => {
|
||||
// ID is in the config, checking in with the server
|
||||
reqOptions = new requestOptions("/nodes/nodeCheckIn", "POST");
|
||||
sendHttpRequest(reqOptions, JSON.stringify(runningClientConfig), (responseObject) => {
|
||||
log.DEBUG("Check In Respose: ", responseObject);
|
||||
if (responseObject.statusCode === 202) {
|
||||
// Server accepted an update
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import argparse, platform, os
|
||||
from discord import Intents, Client, Member, opus, Activity, ActivityType
|
||||
from discord import Intents, Client, Member, opus
|
||||
from discord.ext import commands
|
||||
from NoiseGatev2 import NoiseGate
|
||||
|
||||
@@ -25,7 +25,7 @@ async def load_opus():
|
||||
return "armv7l"
|
||||
|
||||
|
||||
def main(clientId='OTQzNzQyMDQwMjU1MTE1MzA0.Yg3eRA.ZxEbRr55xahjfaUmPY8pmS-RHTY', channelId=367396189529833476, NGThreshold=50, deviceId=1, presence="the radio"):
|
||||
def main(clientId='OTQzNzQyMDQwMjU1MTE1MzA0.Yg3eRA.ZxEbRr55xahjfaUmPY8pmS-RHTY', channelId=367396189529833476, NGThreshold=50, deviceId=1):
|
||||
intents = Intents.default()
|
||||
|
||||
client = commands.Bot(command_prefix='!', intents=intents)
|
||||
@@ -33,8 +33,6 @@ def main(clientId='OTQzNzQyMDQwMjU1MTE1MzA0.Yg3eRA.ZxEbRr55xahjfaUmPY8pmS-RHTY',
|
||||
@client.event
|
||||
async def on_ready():
|
||||
print(f'We have logged in as {client.user}')
|
||||
# Set the presence of the bot (what it's listening to)
|
||||
await client.change_presence(activity=Activity(type=ActivityType.listening, name=presence))
|
||||
|
||||
channelIdToJoin = client.get_channel(channelId)
|
||||
print("Channel", channelIdToJoin)
|
||||
@@ -57,13 +55,11 @@ def main(clientId='OTQzNzQyMDQwMjU1MTE1MzA0.Yg3eRA.ZxEbRr55xahjfaUmPY8pmS-RHTY',
|
||||
|
||||
client.run(clientId)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("deviceId", type=int, help="The ID of the audio device to use")
|
||||
parser.add_argument("channelId", type=int, help="The ID of the voice channel to use")
|
||||
parser.add_argument("clientId", type=str, help="The discord client ID")
|
||||
parser.add_argument("-n", "--NGThreshold", type=int, help="Change the noisegate threshold. This defaults to 50")
|
||||
parser.add_argument("-p", "--presence", type=str, help="What the bot should be listening to")
|
||||
args = parser.parse_args()
|
||||
|
||||
if (not args.NGThreshold):
|
||||
@@ -75,6 +71,5 @@ if __name__ == "__main__":
|
||||
clientId=args.clientId,
|
||||
channelId=args.channelId,
|
||||
NGThreshold=args.NGThreshold,
|
||||
deviceId=args.deviceId,
|
||||
presence=args.presence
|
||||
deviceId=args.deviceId
|
||||
)
|
||||
@@ -13,6 +13,9 @@ ls -ld $SCRIPT_DIR | awk '{print $3}' >> ./config/installerName
|
||||
useradd -M RadioNode
|
||||
usermod -s -L RadioNode
|
||||
|
||||
# Create the .env file from the example
|
||||
cp $SCRIPT_DIR/.env.example $SCRIPT_DIR/.env
|
||||
|
||||
# Change the ownership of the directory to the service user
|
||||
chown RadioNode -R $SCRIPT_DIR
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ const debug = require('debug');
|
||||
require('dotenv').config();
|
||||
// Modules
|
||||
const { writeFile } = require('fs');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const logLocation = process.env.LOG_LOCATION;
|
||||
|
||||
@@ -35,31 +34,31 @@ exports.DebugBuilder = class DebugBuilder {
|
||||
this.INFO = (...messageParts) => {
|
||||
const _info = debug(`${appName}:${fileName}:INFO`);
|
||||
_info(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:INFO\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:INFO\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.DEBUG = (...messageParts) => {
|
||||
const _debug = debug(`${appName}:${fileName}:DEBUG`);
|
||||
_debug(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:DEBUG\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:DEBUG\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.VERBOSE = (...messageParts) => {
|
||||
const _verbose = debug(`${appName}:${fileName}:VERBOSE`);
|
||||
_verbose(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:VERBOSE\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:VERBOSE\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.WARN = (...messageParts) => {
|
||||
const _warn = debug(`${appName}:${fileName}:WARNING`);
|
||||
_warn(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:WARNING\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:WARNING\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.ERROR = (...messageParts) => {
|
||||
const _error = debug(`${appName}:${fileName}:ERROR`);
|
||||
_error(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:ERROR\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:ERROR\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(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);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||
const log = new DebugBuilder("server", "give-role");
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('give-role')
|
||||
.setDescription('Use this command to give a role you have to another member.')
|
||||
.addUserOption(option =>
|
||||
option.setName('user')
|
||||
.setDescription('The user you wish to give the role to ')
|
||||
.setRequired(true))
|
||||
.addRoleOption(option =>
|
||||
option.setName('role')
|
||||
.setDescription('The role you wish to give the selected user')
|
||||
.setRequired(true)),
|
||||
example: "give-role",
|
||||
isPrivileged: false,
|
||||
requiresTokens: false,
|
||||
defaultTokenUsage: 0,
|
||||
deferInitialReply: true,
|
||||
/*async autocomplete(interaction) {
|
||||
const focusedValue = interaction.options.getFocused();
|
||||
},*/
|
||||
async execute(interaction) {
|
||||
try{
|
||||
// The role to give to the user
|
||||
const selectedRole = interaction.options.getRole('role');
|
||||
|
||||
// The user who should be given the role
|
||||
var selectedUser = interaction.options.getUser("user");
|
||||
selectedUser = interaction.guild.members.cache.get(selectedUser.id);
|
||||
|
||||
|
||||
// The user who initiated the command
|
||||
const initUser = interaction.member;
|
||||
|
||||
log.DEBUG("Give Role DEBUG: ", initUser, selectedRole, selectedUser);
|
||||
|
||||
// Check if the user has the role selected
|
||||
if (!initUser.roles.cache.find(role => role.name === selectedRole.name)) return await interaction.editReply(`Sorry ${initUser}, you don't have the group ${selectedRole} and thus you cannot give it to ${selectedUser}`);
|
||||
|
||||
// Give the selected user the role and let both the user and the initiator know
|
||||
await selectedUser.roles.add(selectedRole);
|
||||
|
||||
return await interaction.editReply(`Ok ${initUser}, ${selectedUser} has been given the ${selectedRole} role!`)
|
||||
}catch(err){
|
||||
log.ERROR(err)
|
||||
//await interaction.reply(err.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
// Modules
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { customSlashCommandBuilder } = require('../utilities/customSlashCommandBuilder');
|
||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||
const { getMembersInRole, getAllClientIds, filterAutocompleteValues } = require("../utilities/utils");
|
||||
const { getMembersInRole, getAllClientIds } = require("../utilities/utils");
|
||||
const { requestOptions, sendHttpRequest } = require("../utilities/httpRequests");
|
||||
const { getOnlineNodes, updateNodeInfo, addNodeConnection, getConnectionByNodeId, getAllConnections } = require("../utilities/mysqlHandler");
|
||||
const { getOnlineNodes, updateNodeInfo, addNodeConnection, getConnectionByNodeId } = require("../utilities/mysqlHandler");
|
||||
|
||||
// Global Vars
|
||||
const log = new DebugBuilder("server", "join");
|
||||
@@ -13,10 +13,10 @@ const log = new DebugBuilder("server", "join");
|
||||
*
|
||||
* @param {*} presetName The preset name to listen to on the client
|
||||
* @param {*} channelId The channel ID to join the bot to
|
||||
* @param {*} connections EITHER A collection of clients that are currently connected OR a single discord client ID (NOT dev portal ID) that should be used to join the server with
|
||||
* @param {*} clientIdsUsed EITHER A collection of clients that are currently connected OR a single discord client ID (NOT dev portal ID) that should be used to join the server with
|
||||
* @returns
|
||||
*/
|
||||
async function joinServerWrapper(presetName, channelId, connections) {
|
||||
async function joinServerWrapper(presetName, channelId, clientIdsUsed) {
|
||||
// Get nodes online
|
||||
var onlineNodes = await new Promise((recordResolve, recordReject) => {
|
||||
getOnlineNodes((nodeRows) => {
|
||||
@@ -45,16 +45,16 @@ async function joinServerWrapper(presetName, channelId, connections) {
|
||||
log.DEBUG("All clients: ", Object.keys(availableClientIds));
|
||||
|
||||
var selectedClientId;
|
||||
if (typeof connections === 'string') {
|
||||
if (typeof clientIdsUsed === 'string') {
|
||||
for (const availableClientId of availableClientIds) {
|
||||
if (availableClientId.discordId != connections ) selectedClientId = availableClientId;
|
||||
if (availableClientId.discordId != clientIdsUsed ) selectedClientId = availableClientId;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.DEBUG("Open connections: ", connections);
|
||||
for (const connection of connections) {
|
||||
log.DEBUG("Used Client ID: ", connection);
|
||||
availableClientIds = availableClientIds.filter(cid => cid.discordId != connection.clientObject.discordId);
|
||||
log.DEBUG("Client IDs Used: ", clientIdsUsed.keys());
|
||||
for (const usedClientId of clientIdsUsed.keys()) {
|
||||
log.DEBUG("Used Client ID: ", usedClientId);
|
||||
availableClientIds = availableClientIds.filter(cid => cid.discordId != usedClientId);
|
||||
}
|
||||
|
||||
log.DEBUG("Available Client IDs: ", availableClientIds);
|
||||
@@ -84,48 +84,19 @@ async function joinServerWrapper(presetName, channelId, connections) {
|
||||
const nodeConnection = await addNodeConnection(selectedNode, selectedClientId);
|
||||
log.DEBUG("Node Connection: ", nodeConnection);
|
||||
});
|
||||
|
||||
return selectedClientId;
|
||||
}
|
||||
exports.joinServerWrapper = joinServerWrapper;
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
data: new customSlashCommandBuilder()
|
||||
.setName('join')
|
||||
.setDescription('Join the channel you are in with the preset you choose')
|
||||
.addStringOption(option =>
|
||||
option.setName("preset")
|
||||
.setDescription("The preset you would like to listen to")
|
||||
.setAutocomplete(true)
|
||||
.setRequired(true)),
|
||||
.addAllSystemPresetOptions(),
|
||||
example: "join",
|
||||
isPrivileged: false,
|
||||
requiresTokens: false,
|
||||
defaultTokenUsage: 0,
|
||||
deferInitialReply: true,
|
||||
async autocomplete(interaction) {
|
||||
const nodeObjects = await new Promise((recordResolve, recordReject) => {
|
||||
getOnlineNodes((nodeRows) => {
|
||||
recordResolve(nodeRows);
|
||||
});
|
||||
});
|
||||
log.DEBUG("Node objects: ", nodeObjects);
|
||||
var presetsAvailable = [];
|
||||
for (const nodeObject of nodeObjects) {
|
||||
log.DEBUG("Node object: ", nodeObject);
|
||||
for (const presetName in nodeObject.nearbySystems) presetsAvailable.push(nodeObject.nearbySystems[presetName]);
|
||||
}
|
||||
|
||||
log.DEBUG("All Presets available: ", presetsAvailable);
|
||||
|
||||
// Remove duplicates
|
||||
options = [...new Set(presetsAvailable)];
|
||||
log.DEBUG("DeDuped Presets available: ", options);
|
||||
|
||||
// Filter the results to what the user is entering
|
||||
filterAutocompleteValues(interaction, options);
|
||||
|
||||
},
|
||||
async execute(interaction) {
|
||||
try{
|
||||
const guildId = interaction.guild.id;
|
||||
@@ -134,13 +105,12 @@ module.exports = {
|
||||
const channelId = interaction.member.voice.channel.id;
|
||||
log.DEBUG(`Join requested by: ${interaction.user.username}, to: '${presetName}', in channel: ${channelId} / ${guildId}`);
|
||||
|
||||
const connections = await getAllConnections();
|
||||
const onlineBots = await getMembersInRole(interaction);
|
||||
|
||||
log.DEBUG("Current Connections: ", connections);
|
||||
log.DEBUG("Online Bots: ", onlineBots);
|
||||
|
||||
const selectedClientId = await joinServerWrapper(presetName, channelId, connections);
|
||||
|
||||
await interaction.editReply(`Ok, ${interaction.member}. **${selectedClientId.name}** is joining your channel.`);
|
||||
await joinServerWrapper(presetName, channelId, onlineBots.online);
|
||||
await interaction.editReply('**Pong.**');
|
||||
//await interaction.channel.send('**Pong.**'); // This will send a message to the channel of the interaction outside of the initial reply
|
||||
}catch(err){
|
||||
log.ERROR(err)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// Modules
|
||||
const { SlashCommandBuilder } = require('discord.js');
|
||||
const { customSlashCommandBuilder } = require('../utilities/customSlashCommandBuilder');
|
||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||
const { getAllClientIds, getKeyByArrayValue, filterAutocompleteValues } = require("../utilities/utils");
|
||||
const { getAllClientIds, getKeyByArrayValue } = require("../utilities/utils");
|
||||
const { requestOptions, sendHttpRequest } = require("../utilities/httpRequests");
|
||||
const { checkNodeConnectionByClientId, removeNodeConnectionByNodeId, getAllConnections } = require('../utilities/mysqlHandler');
|
||||
const { checkNodeConnectionByClientId, removeNodeConnectionByNodeId, updateNodeInfo, getConnectedNodes, getAllConnections } = require('../utilities/mysqlHandler');
|
||||
|
||||
// Global Vars
|
||||
const log = new DebugBuilder("server", "leave");
|
||||
const logAC = new DebugBuilder("server", "leave_autocorrect");
|
||||
|
||||
async function leaveServerWrapper(clientIdObject) {
|
||||
if (!clientIdObject.clientId || !clientIdObject.name) return log.ERROR("Tried to leave server without client ID and/or Name");
|
||||
@@ -33,7 +34,7 @@ async function leaveServerWrapper(clientIdObject) {
|
||||
exports.leaveServerWrapper = leaveServerWrapper;
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
data: new customSlashCommandBuilder()
|
||||
.setName('leave')
|
||||
.setDescription('Disconnect a bot from the server')
|
||||
.addStringOption(option =>
|
||||
@@ -47,12 +48,17 @@ module.exports = {
|
||||
defaultTokenUsage: 0,
|
||||
deferInitialReply: true,
|
||||
async autocomplete(interaction) {
|
||||
const focusedValue = interaction.options.getFocused();
|
||||
const connections = await getAllConnections();
|
||||
const options = connections.map(conn => conn.clientObject.name);
|
||||
await filterAutocompleteValues(interaction, options);
|
||||
const filtered = connections.filter(conn => String(conn.clientObject.name).startsWith(focusedValue)).map(conn => conn.clientObject.name);
|
||||
logAC.DEBUG("Focused Value: ", focusedValue, connections, filtered);
|
||||
await interaction.respond(
|
||||
filtered.map(option => ({ name: option, value: option })),
|
||||
);
|
||||
},
|
||||
async execute(interaction) {
|
||||
try{
|
||||
const guildId = interaction.guild.id;
|
||||
const botName = interaction.options.getString('bot');
|
||||
log.DEBUG("Bot Name: ", botName)
|
||||
const clinetIds = await getAllClientIds();
|
||||
|
||||
@@ -7,7 +7,7 @@ const log = new DebugBuilder("server", "remove");
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('remove')
|
||||
.setDescription('Remove an RSS source by it\'s title')
|
||||
.setDescription('Remove an RSS source by it\' title')
|
||||
.addStringOption(option =>
|
||||
option.setName('title')
|
||||
.setDescription('The title of the source to remove')
|
||||
|
||||
@@ -25,7 +25,7 @@ exports.listAllNodes = async (req, res) => {
|
||||
|
||||
// Add a new node to the storage
|
||||
exports.newNode = async (req, res) => {
|
||||
if (!req.body.name) return res.status(400).json("No name specified for new node");
|
||||
if (!req.body.name) return res.send(400)
|
||||
|
||||
try {
|
||||
// Try to add the new user with defaults if missing options
|
||||
@@ -38,9 +38,9 @@ exports.newNode = async (req, res) => {
|
||||
_online: req.body.online ?? 0
|
||||
});
|
||||
|
||||
addNewNode(newNode, (newNodeObject) => {
|
||||
addNewNode(newNode, (queryResults) => {
|
||||
// Send back a success if the user has been added and the ID for the client to keep track of
|
||||
res.status(202).json({"nodeId": newNodeObject.id});
|
||||
res.status(202).json({"nodeId": queryResults.insertId});
|
||||
})
|
||||
}
|
||||
catch (err) {
|
||||
@@ -108,7 +108,6 @@ exports.requestNodeJoinServer = async (req, res) => {
|
||||
*/
|
||||
exports.nodeMonitorService = class nodeMonitorService {
|
||||
constructor() {
|
||||
this.log = new DebugBuilder("server", "nodeMonitorService");
|
||||
}
|
||||
|
||||
async start(){
|
||||
@@ -131,21 +130,21 @@ exports.nodeMonitorService = class nodeMonitorService {
|
||||
|
||||
async checkInWithOnlineNodes(){
|
||||
getOnlineNodes((nodes) => {
|
||||
this.log.DEBUG("Online Nodes: ", nodes);
|
||||
log.DEBUG("Online Nodes: ", nodes);
|
||||
for (const node of nodes) {
|
||||
const reqOptions = new requestOptions("/client/requestCheckIn", "GET", node.ip, node.port)
|
||||
sendHttpRequest(reqOptions, "", (responseObj) => {
|
||||
const request = sendHttpRequest(reqOptions, "", (responseObj) => {
|
||||
if (responseObj) {
|
||||
this.log.DEBUG("Response from: ", node.name, responseObj);
|
||||
log.DEBUG("Response from: ", node.name, responseObj);
|
||||
}
|
||||
else {
|
||||
this.log.DEBUG("No response from node, assuming it's offline");
|
||||
log.DEBUG("No response from node, assuming it's offline");
|
||||
const offlineNode = new nodeObject({ _online: 0, _id: node.id });
|
||||
this.log.DEBUG("Offline node update object: ", offlineNode);
|
||||
log.DEBUG("Offline node update object: ", offlineNode);
|
||||
updateNodeInfo(offlineNode, (sqlResponse) => {
|
||||
if (!sqlResponse) this.log.ERROR("No response from SQL object");
|
||||
if (!sqlResponse) log.ERROR("No response from SQL object");
|
||||
|
||||
this.log.DEBUG("Updated offline node: ", sqlResponse);
|
||||
log.DEBUG("Updated node: ", sqlResponse);
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -148,7 +148,7 @@ client.on('ready', () => {
|
||||
runHTTPServer();
|
||||
|
||||
log.DEBUG("Starting Node Monitoring Service");
|
||||
runNodeMonitorService();
|
||||
//runNodeMonitorService();
|
||||
|
||||
log.DEBUG("Starting RSS watcher");
|
||||
runRssService();
|
||||
|
||||
@@ -5,7 +5,7 @@ const { FeedStorage, PostStorage } = require("./libStorage");
|
||||
const libUtils = require("./libUtils");
|
||||
const { DebugBuilder } = require("./utilities/debugBuilder");
|
||||
const log = new DebugBuilder("server", "libCore");
|
||||
const mysql = require("mysql2");
|
||||
const mysql = require("mysql");
|
||||
|
||||
const UserAgent = require("user-agents");
|
||||
process.env.USER_AGENT_STRING = new UserAgent({ platform: 'Win32' }).toString();
|
||||
|
||||
@@ -8,7 +8,7 @@ const { RSSSourceRecord, RSSPostRecord } = require("./utilities/recordHelper");
|
||||
|
||||
// Storage Specific Modules
|
||||
// MySQL
|
||||
const mysql = require("mysql2");
|
||||
const mysql = require("mysql");
|
||||
|
||||
const rssFeedsTable = process.env.DB_RSS_FEEDS_TABLE;
|
||||
const rssPostsTable = process.env.DB_RSS_POSTS_TABLE;
|
||||
@@ -481,10 +481,10 @@ exports.PostStorage = class PostStorage extends Storage {
|
||||
|
||||
savePost(_postObject, callback){
|
||||
const tempCreationDate = returnMysqlTime();
|
||||
log.DEBUG("Saving Post Object:", _postObject);
|
||||
if (!_postObject?.postId || !_postObject?.link) {
|
||||
return callback(new Error("Post object malformed, check the object before saving it", _postObject), undefined)
|
||||
}
|
||||
log.DEBUG("Saving Post:", _postObject);
|
||||
|
||||
if (_postObject.link.length > 250) _postObject.link = _postObject.link.substring(0, 250);
|
||||
|
||||
|
||||
40
Server/modules/radioRecordingScraper/recordings_spider.py
Normal file
40
Server/modules/radioRecordingScraper/recordings_spider.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import scrapy
|
||||
from scrapy.crawler import CrawlerProcess
|
||||
|
||||
class RecordingSpider(scrapy.Spider):
|
||||
name = "recording-scraper"
|
||||
start_urls = [
|
||||
'https://radio.vpn.cusano.net/sdr/transmissions',
|
||||
]
|
||||
|
||||
def parse(self, response):
|
||||
print("ASDASDD")
|
||||
print(response)
|
||||
for row in response.css("tr"):
|
||||
if row.css('td.py-1'):
|
||||
links = row.css('a')
|
||||
rows = row.css('td.py-1')
|
||||
print(row)
|
||||
yield {
|
||||
'device': rows[0],
|
||||
'date': rows[1],
|
||||
'duration': rows[2],
|
||||
"frequency": rows[3],
|
||||
"link": links[0].attrib["href"],
|
||||
}
|
||||
|
||||
next_page_url = response.css("a.page-link > a::attr(href)").extract_first()
|
||||
if next_page_url is not None:
|
||||
yield scrapy.Request(response.urljoin(next_page_url))
|
||||
|
||||
|
||||
process = CrawlerProcess(
|
||||
settings={
|
||||
"FEEDS": {
|
||||
"items.json": {"format": "json"},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
process.crawl(RecordingSpider)
|
||||
process.start() # the script will block here until the crawling is finished
|
||||
3
Server/modules/radioRecordingScraper/requirements.txt
Normal file
3
Server/modules/radioRecordingScraper/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
scrapy
|
||||
fake-useragent
|
||||
beautifulsoup4
|
||||
@@ -21,7 +21,7 @@
|
||||
"jsdoc": "^4.0.2",
|
||||
"jsonfile": "^6.1.0",
|
||||
"morgan": "^1.10.0",
|
||||
"mysql2": "^3.3.5",
|
||||
"mysql": "^2.18.1",
|
||||
"node-html-markdown": "^1.3.0",
|
||||
"node-html-parser": "^6.1.5",
|
||||
"openai": "^3.2.1",
|
||||
|
||||
46
Server/utilities/customSlashCommandBuilder.js
Normal file
46
Server/utilities/customSlashCommandBuilder.js
Normal file
@@ -0,0 +1,46 @@
|
||||
const { SlashCommandBuilder, SlashCommandStringOption } = require('discord.js');
|
||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||
const { BufferToJson } = require("../utilities/utils");
|
||||
const log = new DebugBuilder("server", "customSlashCommandBuilder");
|
||||
|
||||
const { getAllNodes, getAllNodesSync } = require("../utilities/mysqlHandler");
|
||||
|
||||
exports.customSlashCommandBuilder = class customSlashCommandBuilder extends SlashCommandBuilder {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async addAllSystemPresetOptions() {
|
||||
const nodeObjects = await new Promise((recordResolve, recordReject) => {
|
||||
getAllNodes((nodeRows) => {
|
||||
recordResolve(nodeRows);
|
||||
});
|
||||
});
|
||||
log.DEBUG("Node objects: ", nodeObjects);
|
||||
var presetsAvailable = [];
|
||||
for (const nodeObject of nodeObjects) {
|
||||
log.DEBUG("Node object: ", nodeObject);
|
||||
for (const presetName in nodeObject.nearbySystems) presetsAvailable.push(nodeObject.nearbySystems[presetName]);
|
||||
}
|
||||
|
||||
log.DEBUG("All Presets available: ", presetsAvailable);
|
||||
|
||||
// Remove duplicates
|
||||
presetsAvailable = [...new Set(presetsAvailable)];
|
||||
log.DEBUG("DeDuped Presets available: ", presetsAvailable);
|
||||
|
||||
this.addStringOption(option => option.setName("preset").setRequired(true).setDescription("The channels"));
|
||||
for (const preset of presetsAvailable){
|
||||
log.DEBUG("Preset: ", preset);
|
||||
this.options[0].addChoices({
|
||||
'name': String(preset),
|
||||
'value': String(preset)
|
||||
});
|
||||
}
|
||||
log.DEBUG("Preset Options: ", this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ const debug = require('debug');
|
||||
require('dotenv').config();
|
||||
// Modules
|
||||
const { writeFile } = require('fs');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const logLocation = process.env.LOG_LOCATION;
|
||||
|
||||
@@ -35,31 +34,31 @@ exports.DebugBuilder = class DebugBuilder {
|
||||
this.INFO = (...messageParts) => {
|
||||
const _info = debug(`${appName}:${fileName}:INFO`);
|
||||
_info(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:INFO\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:INFO\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.DEBUG = (...messageParts) => {
|
||||
const _debug = debug(`${appName}:${fileName}:DEBUG`);
|
||||
_debug(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:DEBUG\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:DEBUG\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.VERBOSE = (...messageParts) => {
|
||||
const _verbose = debug(`${appName}:${fileName}:VERBOSE`);
|
||||
_verbose(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:VERBOSE\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:VERBOSE\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.WARN = (...messageParts) => {
|
||||
const _warn = debug(`${appName}:${fileName}:WARNING`);
|
||||
_warn(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:WARNING\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:WARNING\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(messagePart)})}`, appName);
|
||||
}
|
||||
|
||||
this.ERROR = (...messageParts) => {
|
||||
const _error = debug(`${appName}:${fileName}:ERROR`);
|
||||
_error(messageParts);
|
||||
writeToLog(`${Date.now().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:ERROR\t-\t${messageParts.map((messagePart, index, array) => {return inspect(messagePart)})}`, appName);
|
||||
writeToLog(`${appName}:${fileName}:ERROR\t-\t${messageParts.map((messagePart, index, array) => {return JSON.stringify(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);
|
||||
|
||||
@@ -11,14 +11,14 @@ const path = require('node:path');
|
||||
const { DebugBuilder } = require("./debugBuilder");
|
||||
const log = new DebugBuilder("server", "deployCommands");
|
||||
|
||||
var commands = [];
|
||||
const commands = [];
|
||||
// Grab all the command files from the commands directory you created earlier
|
||||
const commandsPath = path.resolve(__dirname, '../commands');
|
||||
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||
|
||||
exports.deploy = (clientId, guildIDs) => {
|
||||
log.DEBUG("Deploying commands for: ", guildIDs);
|
||||
if (!Array.isArray(guildIDs)) guildIDs = [guildIDs];
|
||||
if (Array.isArray(guildIDs)) guildIDs = [guildIDs];
|
||||
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
|
||||
for (const file of commandFiles) {
|
||||
const command = require(`${path.resolve(commandsPath, file)}`);
|
||||
@@ -48,35 +48,3 @@ exports.deploy = (clientId, guildIDs) => {
|
||||
})()
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all commands for a given bot in a given guild
|
||||
*
|
||||
* @param {*} clientId The client ID of the bot to remove commands from
|
||||
* @param {*} guildId The ID of the guild to remove the bot commands from
|
||||
*/
|
||||
exports.removeAll = (clientId, guildId) => {
|
||||
if (!Array.isArray(guildId)) guildIDs = [guildId];
|
||||
log.DEBUG("Removing commands for: ", clientId, guildIDs);
|
||||
|
||||
commands = [];
|
||||
|
||||
const rest = new REST({ version: '10' }).setToken(token);
|
||||
for (const guildId of guildIDs){
|
||||
(async () => {
|
||||
try {
|
||||
log.DEBUG(`Started refreshing ${commands.length} application (/) commands for guild ID: ${guildId}.`);
|
||||
// The put method is used to fully refresh all commands in the guild with the current set
|
||||
const data = await rest.put(
|
||||
Routes.applicationGuildCommands(clientId, guildId),
|
||||
{ body: commands },
|
||||
);
|
||||
|
||||
log.DEBUG(`Successfully reloaded ${data.length} application (/) commands for guild ID: ${guildId}.`);
|
||||
} catch (error) {
|
||||
// And of course, make sure you catch and log any errors!
|
||||
log.ERROR("ERROR Deploying commands: ", error, "Body from error: ", commands);
|
||||
}
|
||||
})()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
require('dotenv').config();
|
||||
const mysql = require('mysql2');
|
||||
const mysql = require('mysql');
|
||||
const utils = require('./utils');
|
||||
const { nodeObject, clientObject, connectionObject } = require("./recordHelper");
|
||||
const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||
@@ -92,7 +92,7 @@ exports.getAllNodesSync = async () => {
|
||||
|
||||
console.log("Rows: ", rows);
|
||||
|
||||
return await returnNodeObjectFromRows(rows);
|
||||
return returnNodeObjectFromRows(rows);
|
||||
}
|
||||
|
||||
/** Get all nodes that have the online status set true (are online)
|
||||
@@ -110,7 +110,7 @@ exports.getOnlineNodes = (callback) => {
|
||||
* @param callback Callback function
|
||||
*/
|
||||
async function getNodeInfoFromId(nodeId, callback = undefined) {
|
||||
if (!nodeId || nodeId == '0' || nodeId == 0 ) throw new Error("No node ID given when trying to fetch node");
|
||||
if (!nodeId) throw new Error("No node ID given when trying to fetch node");
|
||||
log.DEBUG("Getting node from ID: ", nodeId);
|
||||
const sqlQuery = `SELECT * FROM ${nodesTable} WHERE id = ${nodeId}`
|
||||
|
||||
@@ -122,7 +122,7 @@ exports.getOnlineNodes = (callback) => {
|
||||
|
||||
// Call back the first (and theoretically only) row
|
||||
// Specify 0 so downstream functions don't have to worry about it
|
||||
return (callback) ? callback(await returnNodeObjectFromRow(sqlResponse[0])) : await returnNodeObjectFromRow(sqlResponse[0]);
|
||||
return (callback) ? callback(returnNodeObjectFromRow(sqlResponse[0])) : returnNodeObjectFromRow(sqlResponse[0]);
|
||||
}
|
||||
exports.getNodeInfoFromId = getNodeInfoFromId
|
||||
|
||||
@@ -136,9 +136,10 @@ exports.addNewNode = async (nodeObject, callback) => {
|
||||
ip = nodeObject.ip,
|
||||
port = nodeObject.port,
|
||||
location = nodeObject.location,
|
||||
nearbySystems = utils.JsonToBuffer(nodeObject.nearbySystems ?? {}),
|
||||
online = nodeObject.online
|
||||
const sqlQuery = `INSERT INTO ${nodesTable} (name, ip, port, location, nearbySystems, online) VALUES ('${name}', '${ip}', ${port}, '${location}', '${nearbySystems}', ${online})`;
|
||||
nearbySystems = utils.JsonToBuffer(nodeObject.nearbySystems),
|
||||
online = nodeObject.online,
|
||||
connected = 0;
|
||||
const sqlQuery = `INSERT INTO ${nodesTable} (name, ip, port, location, nearbySystems, online, connected) VALUES ('${name}', '${ip}', ${port}, '${location}', '${nearbySystems}', ${online}, ${connected})`;
|
||||
|
||||
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
||||
runSQL(sqlQuery, (rows) => {
|
||||
@@ -148,9 +149,7 @@ exports.addNewNode = async (nodeObject, callback) => {
|
||||
|
||||
// Call back the first (and theoretically only) row
|
||||
// Specify 0 so downstream functions don't have to worry about it
|
||||
const newNode = await this.getNodeInfoFromId(sqlResponse.insertId);
|
||||
log.DEBUG("Added new node: ", newNode)
|
||||
return (callback) ? callback(newNode) : newNode;
|
||||
return (callback) ? callback(returnNodeObjectFromRow(sqlResponse)) : returnNodeObjectFromRow(sqlResponse);
|
||||
}
|
||||
|
||||
/** Update the known info on a node
|
||||
@@ -207,7 +206,7 @@ exports.updateNodeInfo = async (nodeObject, callback = undefined) => {
|
||||
});
|
||||
|
||||
if (sqlResponse.affectedRows === 1) return (callback) ? callback(true) : true;
|
||||
else return (callback) ? callback(await returnNodeObjectFromRows(sqlResponse)) : await returnNodeObjectFromRows(sqlResponse);
|
||||
else return (callback) ? callback(returnNodeObjectFromRows(sqlResponse)) : returnNodeObjectFromRows(sqlResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -354,12 +353,12 @@ exports.getAllConnections = async (callback = undefined) => {
|
||||
|
||||
// Function to run and handle SQL errors
|
||||
function runSQL(sqlQuery, callback = undefined, error = (err) => {
|
||||
log.ERROR(err);
|
||||
console.log(err);
|
||||
throw err;
|
||||
}) {
|
||||
connection.query(sqlQuery, (err, rows) => {
|
||||
if (err) return error(err);
|
||||
log.VERBOSE('Response for query: ', sqlQuery, rows);
|
||||
//console.log('The rows are:', rows);
|
||||
return (callback) ? callback(rows) : rows
|
||||
})
|
||||
}
|
||||
|
||||
@@ -110,6 +110,8 @@ class nodeObject {
|
||||
* @param {*} param0._port The port that the client is listening on
|
||||
* @param {*} param0._location The physical location of the node
|
||||
* @param {*} param0._online True/False if the node is online or offline
|
||||
* @param {*} param0._connected True/False if the bot is connected to discord or not
|
||||
* @param {*} param0._connection The connection Object associated with the node, null if not checked, undefined if none exists
|
||||
* @param {*} param0._nearbySystems An object array of nearby systems
|
||||
*/
|
||||
constructor({ _id = null, _name = null, _ip = null, _port = null, _location = null, _nearbySystems = null, _online = null }) {
|
||||
|
||||
@@ -3,7 +3,6 @@ const { DebugBuilder } = require("../utilities/debugBuilder");
|
||||
const { clientObject } = require("./recordHelper");
|
||||
const { readFileSync } = require('fs');
|
||||
const log = new DebugBuilder("server", "utils");
|
||||
const logAC = new DebugBuilder("server", "command-autocorrect");
|
||||
const path = require('path');
|
||||
|
||||
// Convert a JSON object to a buffer for the DB
|
||||
@@ -118,19 +117,3 @@ exports.getClientObjectByClientID = (clientId) => {
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
||||
exports.filterAutocompleteValues = async (interaction, options) => {
|
||||
// Get the command used
|
||||
const command = interaction.command;
|
||||
|
||||
// Find values that start with what the user is entering
|
||||
const focusedValue = interaction.options.getFocused();
|
||||
const filtered = options.filter(preset => preset.startsWith(focusedValue));
|
||||
|
||||
// Give the query response to the user
|
||||
logAC.DEBUG("Focused Value: ", command, focusedValue, options, filtered);
|
||||
await interaction.respond(
|
||||
filtered.map(option => ({ name: option, value: option })),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user