Use an sqlite3 database for timer feature

There were some other small edits as well, mostly formatting or better
logging in certain functions
This commit is contained in:
SileNce5k 2023-05-27 22:16:43 +02:00
parent a098ab6616
commit d41b28ec91
No known key found for this signature in database
GPG key ID: 961132EB78C8915F
13 changed files with 2277 additions and 59 deletions

View file

@ -1,22 +1,24 @@
const createTimer = require('../../util/timer/createTimer'); const createTimer = require('../../util/timer/createTimer');
const deleteTimer = require('../../util/timer/deleteTimer'); const deleteTimer = require('../../util/timer/deleteTimer');
const parseTime = require('../../util/timer/parseTime'); const parseTime = require('../../util/timer/parseTime');
const fs = require('fs');
const showTimer = require('../../util/timer/showTimer'); const showTimer = require('../../util/timer/showTimer');
module.exports = { module.exports = {
name: "timer", name: "timer",
description: "Set a timer for a time in minutes.", description: "Set a timer for a time in minutes.",
moreHelp: ["Usage:" moreHelp: ["Usage:"
,"`<prefix>timer <time_in_minutes> <message_to_send>`" ,"`<prefix>timer [add|create] <time_in_minutes> <message_to_send>`"
,"`<prefix>timer <time>(d|h|m|s|t) <message_to_send>`" ,"`<prefix>timer <time>(d|h|m|s|t) <message_to_send>`"
,"`<prefix>timer <time_in_minutes> <message_to_send>`"
,"`<prefix>timer edit <timer_id> <new_time_in_minutes> <new_message_to_send>` (not implemented)"
,"`<prefix>timer [delete|remove] <timer_id>`"
,"`<prefix>timer show <timer_id>`"
,"Bot will mention you after the time has passed, with the custom message."], ,"Bot will mention you after the time has passed, with the custom message."],
execute({client, message, args}) { async execute({message, args}) {
let sendText = "This should never happen."; let sendText = "This should never happen.";
switch (args[0]) { switch (args[0]) {
case "add": case "add":
case "create": case "create":
sendText = createTimer(client, message, args, false); sendText = await createTimer(message, args, false);
break; break;
case "edit": case "edit":
sendText = "not implemented yet" sendText = "not implemented yet"
@ -24,14 +26,15 @@ module.exports = {
case "delete": case "delete":
case "remove": case "remove":
let timerID = args[1]; let timerID = args[1];
sendText = deleteTimer(client, message.author.id, timerID); sendText = await deleteTimer(message.author.id, timerID);
break; break;
case "show": case "show":
sendText = showTimer(client, message.author.id, args[1]); sendText = await showTimer(message.author.id, args[1]);
default: default:
sendText = "not sure what you mean" sendText = "not sure what you mean"
if(!isNaN(parseTime(args[0], Math.floor(new Date() / 1000)))) if(!isNaN(parseTime(args[0], Math.floor(new Date() / 1000))))
sendText = createTimer(client, message, args, true); sendText = await createTimer(message, args, true);
console.log("sendText: ", sendText)
break; break;
} }
message.channel.send(sendText); message.channel.send(sendText);

View file

@ -5,7 +5,7 @@ module.exports = {
let authorTimers = ""; let authorTimers = "";
client.timers.forEach(timer => { client.timers.forEach(timer => {
if(timer.user === message.author.id) if(timer.user === message.author.id)
authorTimers += `${timer.ID} : <t:${timer.reminderDate}:R> | ${timer.customMessage}\n`; authorTimers += `${timer.ID} : <t:${timer.reminderDate}:R>`;
}); });
let sendText = "" === authorTimers ? `You have no timers` : `Your timers are:\n${authorTimers}` let sendText = "" === authorTimers ? `You have no timers` : `Your timers are:\n${authorTimers}`
message.channel.send(sendText); message.channel.send(sendText);

2049
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@
"parse-ms": "^2.1.0", "parse-ms": "^2.1.0",
"prompt-sync": "^4.2.0", "prompt-sync": "^4.2.0",
"seedrandom": "^3.0.5", "seedrandom": "^3.0.5",
"sqlite3": "^5.1.6",
"valid-url": "^1.0.9" "valid-url": "^1.0.9"
}, },
"scripts": { "scripts": {

View file

@ -1,11 +1,23 @@
const fs = require('fs'); const fs = require('fs');
const createInitialConfig = require("./util/createInitialConfig") const createInitialConfig = require("./util/createInitialConfig")
const convertJSONToSQL = require('./util/timer/convertJSONToSQL');
if(!fs.existsSync("./data/config.json")) { if(!fs.existsSync("./data/config.json")) {
createInitialConfig(); createInitialConfig();
} }
if(!fs.existsSync("./data/timers.json")){ async function checkAndConvertJSONToSQL(){
fs.writeFileSync('./data/timers.json', "[]"); process.stdout.write("Checking if timers.json exists... ")
if(fs.existsSync("./data/timers.json")){
process.stdout.write(true + "\n")
await createDatabaseTables();
await convertJSONToSQL();
fs.renameSync('data/timers.json', 'data/timers.json.old');
console.log("Renamed timers.json to timers.json.old");
}else{
process.stdout.write(false + "\n")
} }
}
const createDatabaseTables = require('./server/createDatabaseTables');
checkAndConvertJSONToSQL();
const Discord = require('discord.js'); const Discord = require('discord.js');
const client = new Discord.Client({ intents: [Discord.Intents.FLAGS.GUILDS, Discord.Intents.FLAGS.GUILD_MESSAGES, Discord.Intents.FLAGS.GUILD_PRESENCES] }); const client = new Discord.Client({ intents: [Discord.Intents.FLAGS.GUILDS, Discord.Intents.FLAGS.GUILD_MESSAGES, Discord.Intents.FLAGS.GUILD_PRESENCES] });
const { const {
@ -23,12 +35,7 @@ client.settings = new Discord.Collection();
client.commands = new Discord.Collection(); client.commands = new Discord.Collection();
client.serverPrefixes = new Discord.Collection(); client.serverPrefixes = new Discord.Collection();
client.netmodules = new Discord.Collection(); client.netmodules = new Discord.Collection();
client.timers = require('./data/timers.json');
if(!fs.existsSync("./data/lastTimerID.txt")){
fs.writeFileSync('./data/lastTimerID.txt', "0");
}
client.lastTimerID = parseInt(fs.readFileSync('./data/lastTimerID.txt', 'utf8'));
client.settings.set("presenceType", presenceType); client.settings.set("presenceType", presenceType);
client.settings.set("presenceText", presenceText); client.settings.set("presenceText", presenceText);
@ -37,6 +44,7 @@ const reloadCommands = require("./util/reloadCommands.js");
const reloadNetModules = require('./util/reloadNetModules'); const reloadNetModules = require('./util/reloadNetModules');
const onMessage = require('./server/message'); const onMessage = require('./server/message');
const onReady = require('./server/ready'); const onReady = require('./server/ready');
reloadCommands(client) reloadCommands(client)
reloadNetModules(client) reloadNetModules(client)

View file

@ -0,0 +1,26 @@
const sqlite3 = require('sqlite3').verbose();
module.exports = async function () {
const db = new sqlite3.Database('data/database.db');
return new Promise ((resolve, reject)=>{
db.run(
`CREATE TABLE IF NOT EXISTS timers (
ID INTEGER PRIMARY KEY AUTOINCREMENT,
user TEXT,
reminderTime INTEGER,
channel TEXT,
customMessage TEXT,
hasPassed INTEGER)`,
(err) => {
if (err) {
console.error(`Error while creating table 'timers': ${err}`);
reject(err);
} else {
console.log("Table 'timers' created successfully.");
resolve();
}
db.close();
}
);
})
}

6
server/input.js Normal file
View file

@ -0,0 +1,6 @@
const prompt = require("prompt-sync")();
module.exports = function(client, owners, message){
let input;
}

View file

@ -3,7 +3,6 @@ const checkTimer = require('../util/timer/checkTimer');
const updatePresence = require('../util/updatePresence'); const updatePresence = require('../util/updatePresence');
module.exports = function(client, enableLoginMessage, loginChannel, loginMessage) { module.exports = function(client, enableLoginMessage, loginChannel, loginMessage) {
console.clear();
updatePresence(client) updatePresence(client)
console.log('Ready!'); console.log('Ready!');
if (enableLoginMessage === true) if (enableLoginMessage === true)

View file

@ -1,15 +1,37 @@
const sendTimerReminder = require('./sendTimerReminder') const sendTimerReminder = require('./sendTimerReminder')
const fs = require('fs') const fs = require('fs')
module.exports = function (client) { const sqlite3 = require('sqlite3').verbose();
module.exports = async function (client) {
const checkTimer = require('./checkTimer') const checkTimer = require('./checkTimer')
const db = new sqlite3.Database('data/database.db')
let currentUnixTime = Math.floor(new Date() / 1000);
await new Promise((resolve, reject) => {
db.get(
`SELECT * FROM timers WHERE reminderTime <= ? AND hasPassed = ?`,
[currentUnixTime, false],
function (error, timer) {
if (error) {
console.error(error);
reject(error);
} else {
if (timer !== undefined) {
db.run(`UPDATE timers SET hasPassed = ? WHERE ID = ?`, [true, timer.ID],
function (error) {
if (error) {
console.error(`Error while updating ${timer.ID} setPassed to true`, error);
reject(error);
} else {
console.log(`Updated ${timer.ID}, set hasPassed to true.`);
}
})
sendTimerReminder(client, timer);
}
for(let i = 0; i < client.timers.length; i++){ db.close();
if(parseInt(client.timers[i].reminderDate) <= Math.floor(new Date() / 1000)){ resolve();
sendTimerReminder(client, client.timers[i]);
client.timers.splice(i, 1);
i--
fs.writeFileSync('data/timers.json', JSON.stringify(client.timers, null, 4))
} }
} }
);
})
setTimeout(checkTimer, 1000, client); setTimeout(checkTimer, 1000, client);
} }

View file

@ -0,0 +1,33 @@
const fs = require('fs');
const sqlite3 = require('sqlite3').verbose();
module.exports = async function () {
const timers = require('../../data/timers.json')
const db = new sqlite3.Database('data/database.db');
return new Promise((resolve, reject) => {
for (let i = 0; i < timers.length; i++) {
let user = timers[i].user;
let reminderTime = timers[i].reminderDate;
let channel = timers[i].channel;
let customMessage = timers[i].customMessage;
let hasPassed = false;
db.run(`INSERT INTO timers (
user,
reminderTime,
channel,
customMessage,
hasPassed
) VALUES (?, ?, ?, ?, ?)`, [user, reminderTime, channel, customMessage, hasPassed], function (error) {
if (error) {
console.error(`Error while converting timers.json to SQL: ${error}`)
reject(error);
}
})
}
db.close();
console.log("Converted timers.json to SQL successfully.");
resolve();
})
}

View file

@ -1,7 +1,8 @@
const fs = require('fs'); const fs = require('fs');
const parseTime = require('./parseTime'); const parseTime = require('./parseTime');
const sqlite3 = require('sqlite3').verbose();
module.exports = function (client, message, args, compatibility) { module.exports = async function (message, args, compatibility) {
const databasePath = 'data/database.db'
if (args.length < 2) if (args.length < 2)
return message.channel.send("Please specify a time, and a message to send after the timer has finished"); return message.channel.send("Please specify a time, and a message to send after the timer has finished");
let currentUnixTime = Math.floor(new Date() / 1000); let currentUnixTime = Math.floor(new Date() / 1000);
@ -11,16 +12,52 @@ module.exports = function (client, message, args, compatibility) {
} }
let customMessage = compatibility ? args.slice(1).join(" ") : args.slice(2).join(" "); let customMessage = compatibility ? args.slice(1).join(" ") : args.slice(2).join(" ");
let reminderTime = currentUnixTime + timeInSeconds let reminderTime = currentUnixTime + timeInSeconds
let newTimerID = ++client.lastTimerID; let newTimerID;
const newTimer = { const db = new sqlite3.Database(databasePath)
"ID": newTimerID, let sendText = await new Promise((resolve, reject)=>{
"user": `${message.author.id}`, db.run(`INSERT INTO timers (
"reminderDate": reminderTime, user,
"channel": `${message.channel.id}`, reminderTime,
"customMessage": `${customMessage}` channel,
customMessage,
hasPassed
) VALUES (?, ?, ?, ?, ?)`,
[
message.author.id,
reminderTime,
message.channel.id,
customMessage,
false
], function (error) {
if (error) {
console.error(error)
let sendText = "Error while creating the timer. Check console.";
reject(sendText);
}else{
let lastRowID = this.lastID;
db.get(
`SELECT id FROM timers WHERE rowid = ?`,
lastRowID,
function (error, row) {
if (error) {
let sendText = "Error while getting the ID of the new timer. Check console.";
console.error(error);
reject(sendText);
} else {
newTimerID = row.ID;
let sendText = `A new timer with ID:${newTimerID} created.\nI will remind you <t:${reminderTime.toFixed(0)}:R> (<t:${reminderTime.toFixed(0)}:f>)`
console.log(`New timer with ID:${newTimerID} created.`);
resolve(sendText);
} }
fs.writeFileSync('data/lastTimerID.txt', newTimerID.toString()); }
client.timers.push(newTimer); );
fs.writeFileSync('data/timers.json', JSON.stringify(client.timers, null, 4)) }
return `A new timer with ID:${newTimerID} created.\nI will remind you <t:${reminderTime.toFixed(0)}:R> (<t:${reminderTime.toFixed(0)}:f>)`
});
})
console.log(sendText);
db.close();
return sendText;
} }

View file

@ -1,11 +1,32 @@
const fs = require('fs'); const sqlite3 = require('sqlite3').verbose();
module.exports = async function (authorID, timerID) {
module.exports = function (client, authorID, timerID) { const db = new sqlite3.Database('data/database.db')
let sendText = "";
let timerToDelete = client.timers.find(timer => timer.ID === parseInt(timerID) && timer.user === authorID); await new Promise((resolve, reject) => {
if (timerToDelete === undefined) db.all('SELECT * FROM timers WHERE id = ? AND user = ? AND hasPassed = ?', [parseInt(timerID), authorID, false], (err, rows) => {
return "Timer not found"; if (err) {
client.timers.splice(client.timers.indexOf(timerToDelete), 1); console.error(err);
fs.writeFileSync('data/timers.json', JSON.stringify(client.timers, null, 4)) return;
return `Timer with ID:${timerID} deleted.`; }
if (rows.length > 1) {
sendText = "More than one timer has this ID"
} else if (rows.length === 0) {
sendText = `A timer with the ID ${timerID} was not found.\n`
} else {
db.run('UPDATE timers SET hasPassed = ? WHERE ID = ? AND user = ?', [true, parseInt(timerID), authorID], function (err) {
if (err) {
console.error(err);
sendText = "Updating timers failed. Check console.";
}
else {
sendText = `Timer with ID:${timerID} deleted.`;
}
});
}
});
})
db.close();
return sendText;
} }

View file

@ -1,12 +1,25 @@
const fs = require('fs'); const sqlite3 = require('sqlite3').verbose();
module.exports = async function (authorID, timerID) {
module.exports = function (client, authorID, timerID) { const databasePath = `data/database.db`;
let timerToShow = client.timers.find(timer => timer.ID === parseInt(timerID)); const db = new sqlite3.Database(databasePath);
if (timerToShow === undefined) let sendText = "";
return "Timer not found"; await new Promise((resolve, reject) => {
if (timerToShow.user !== authorID){ db.get(`SELECT * FROM timers WHERE ID = ? AND user = ?`, [timerID, authorID],
return "You can only show info about your own timers."; function (error, timer){
if(error){
sendText = "An error occured while trying to read timer from database. Check console.";
console.error("Error while trying to read timer from database: ", error)
reject(error);
}else{
if(timer === undefined){
sendText = "Timer not found";
}else{
sendText = `${timer.ID} will remind you <t:${timer.reminderDate.toFixed(0)}:R> (<t:${timer.reminderDate.toFixed(0)}:f>)"`;
} }
return `${timerToShow.ID} will remind you <t:${timerToShow.reminderDate.toFixed(0)}:R> (<t:${timerToShow.reminderDate.toFixed(0)}:f>) with the message "${timerToShow.customMessage}"`; resolve();
}
})
})
db.close();
return sendText;
} }