Skip to content

Commit

Permalink
chore: Use mysql to store ccmd data
Browse files Browse the repository at this point in the history
  • Loading branch information
Seniru committed May 17, 2023
1 parent e4da29f commit ef1e25c
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 154 deletions.
34 changes: 0 additions & 34 deletions database/CustomCommands.sql
Original file line number Diff line number Diff line change
@@ -1,42 +1,8 @@
-- MySQL dump 10.13 Distrib 8.0.33, for Linux (x86_64)
--
-- Host: sql9.freesqldatabase.com Database: sql9617855
-- ------------------------------------------------------
-- Server version 5.5.62-0ubuntu0.14.04.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `CustomCommands`
--

DROP TABLE IF EXISTS `CustomCommands`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE IF NOT EXISTS `CustomCommands` (
`name` varchar(15) NOT NULL,
`runner` varchar(20) NOT NULL,
`source` varchar(40) NOT NULL,
`author` bigint(20),
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `CustomCommands`
--

LOCK TABLES `CustomCommands` WRITE;
/*!40000 ALTER TABLE `CustomCommands` DISABLE KEYS */;
INSERT INTO `CustomCommands` VALUES ('8ball','cpython-3.8.9','https://pastebin.com/raw/ExMLuAgv','544776631672242176'),('coinflip','cpython-3.8.9','https://pastebin.com/raw/f8v5EGQF','544776631672242176'),('death','cpython-3.8.9','https://pastebin.com/raw/nLtRfDhs','544776631672242176'),('dice','cpython-3.8.9','https://pastebin.com/raw/LmxRAKE1','544776631672242176'),('dog','cpython-3.8.9','https://pastebin.com/raw/bijXTmat','544776631672242176'),('embed','cpython-3.8.9','https://pastebin.com/raw/AbPX16PA','522972601488900097'),('frog','cpython-3.8.9','https://pastebin.com/raw/bwpCSAvi','544776631672242176'),('graph','cpython-3.8.9','https://pastebin.com/raw/YH0YyPAk','522972601488900097'),('howto','cpython-3.8.9','https://pastebin.com/raw/amMuvd1B','522972601488900097'),('no','cpython-3.8.9','https://pastebin.com/raw/tvprgEqC','522972601488900097'),('order','cpython-3.8.9','https://pastebin.com/raw/B38n572h','544776631672242176'),('percentage','cpython-3.8.9','https://pastebin.com/raw/QghKi731','544776631672242176'),('raw','cpython-3.8.9','https://pastebin.com/raw/Mqq8TkXT','522972601488900097'),('ricardo','cpython-3.8.9','https://pastebin.com/raw/3LRJ8Q6A','522972601488900097'),('tex','cpython-3.8.9','https://pastebin.com/raw/hE2W5YKs','522972601488900097'),('worldclock','cpython-3.8.9','https://pastebin.com/raw/yBueDaSJ','522972601488900097'),('yes','cpython-3.8.9','https://pastebin.com/raw/UguBK6yg','544776631672242176');
/*!40000 ALTER TABLE `CustomCommands` ENABLE KEYS */;
UNLOCK TABLES;
4 changes: 1 addition & 3 deletions database/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ FROM mysql:5.7
WORKDIR /database

ADD *.sql /docker-entrypoint-initdb.d/
ADD /run-til-midnight.sh /
RUN chmod +x /run-til-midnight.sh

EXPOSE 3306
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["/run-til-midnight.sh", "mysqld"]
CMD ["mysqld"]
6 changes: 3 additions & 3 deletions database/ModData.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CREATE TABLE IF NOT EXISTS `Warnings` (
`member` bigint(20) NOT NULL
`reason` varchar(100) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
`member` bigint(20) NOT NULL,
`reason` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
10 changes: 4 additions & 6 deletions database/Qotd.sql
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
CREATE TABLE IF NOT EXISTS `QOTD` (
`id` int NOT NULL,
`question` VARCHAR(200) NOT NULL
`question` VARCHAR(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `QOTData` (
`kind` CHAR(5) NOT NULL,
`kind` CHAR(6) NOT NULL,
`value` VARCHAR(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `QOTData`
VALUES('latest', '$current_time')
ON DUPLICATE KEY IGNORE;
VALUES('latest', '$current_time');

INSERT INTO `QOTData`
VALUES('index', '0')
ON DUPLICATE KEY IGNORE;
VALUES('index', '0');
8 changes: 0 additions & 8 deletions database/run-til-midnight.sh

This file was deleted.

6 changes: 1 addition & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ services:
restart: always
ports:
- 3306:3306
environment:
MYSQL_DATABASE: db
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: root
env_file: ./.env
volumes:
- my-db:/var/lib/mysql

Expand Down
2 changes: 1 addition & 1 deletion script.bash
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

sh /wait-for-it.sh "db:3306" --timeout=60
bash /wait-for-it.sh "db:3306" --timeout=60

function run() {
python -u src/main.py || run
Expand Down
64 changes: 39 additions & 25 deletions src/bots/Discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import discord
import requests
import utils
import aiomysql
from data import data

from bots.cmd_handler import commands
Expand Down Expand Up @@ -45,8 +46,13 @@ async def on_ready(self):
self.mod_data = await self.data_channel.fetch_message(data["data"]["mod"])
self.mod_data = json.loads(self.mod_data.content[7:-3])

self.slash = {}#slash.Manager(self)
#DiscordComponents(self)
self.db = await aiomysql.create_pool(
host='db',
port=int(os.getenv("MYSQL_PORT")),
user=os.getenv("MYSQL_USER"),
password=os.getenv("MYSQL_PASSWORD"),
db=os.getenv("MYSQL_DATABASE")
)

await self.start_period_tasks()

Expand All @@ -73,36 +79,44 @@ async def on_message(self, message):
await cmd["f"](args[1:], message, self)
else:


async with self.db.acquire() as conn:
cur = await conn.cursor(aiomysql.DictCursor)
await cur.execute("SELECT * FROM CustomCommands \
WHERE name LIKE %s;",
[ args[0] ]
)

ccmd = self.ccmds[args[0]]
code = requests.get(ccmd["source"]).content.decode("utf-8")
ccmd = await cur.fetchone()
if not ccmd:
return

code = requests.get(ccmd["source"]).content.decode("utf-8")

stdin = content[len(args[0]) + 1:]
stdin = content[len(args[0]) + 1:]

res = requests.post(WANDBOX_ENDPOINT + "/compile.json",
data = json.dumps({ "compiler": ccmd["runner"], "code": code, "stdin": "{}\n{}".format(message.author.id, f"'{stdin}'" if stdin else "''") }),
headers = { "content-Type": "application/json" }
)
res = requests.post(WANDBOX_ENDPOINT + "/compile.json",
data = json.dumps({ "compiler": ccmd["runner"], "code": code, "stdin": "{}\n{}".format(message.author.id, f"'{stdin}'" if stdin else "''") }),
headers = { "content-Type": "application/json" }
)

if res.status_code != 200:
return await message.reply(":x: | We encountered an internal error. Please try again soon!")
if res.status_code != 200:
return await message.reply(":x: | We encountered an internal error. Please try again soon!")

res = json.loads(res.content.decode("utf-8"))
res = json.loads(res.content.decode("utf-8"))

if res["status"] != "0":
return await message.reply(embed = discord.Embed.from_dict({
"title": ":x: Error in the command",
"description": "Contact the author of this command to fix it\n\n**Error log**:\n ```\n{}```".format((res["program_error"] or "")),
"color": 0xcc0000
if res["status"] != "0":
return await message.reply(embed = discord.Embed.from_dict({
"title": ":x: Error in the command",
"description": "Contact the author of this command to fix it\n\n**Error log**:\n ```\n{}```".format((res["program_error"] or "")),
"color": 0xcc0000

}))
}))

res = json.loads(res["program_output"])
if not res:
return await message.reply(":x: | An error occured while running the command. Please ask the author of this command to fix the output format.")
res = json.loads(res["program_output"])
if not res:
return await message.reply(":x: | An error occured while running the command. Please ask the author of this command to fix the output format.")

await message.reply(embed = discord.Embed.from_dict(res))
await message.reply(embed = discord.Embed.from_dict(res))

elif self.user.id in message.raw_mentions:
fact = requests.get("https://uselessfacts.jsph.pl/random.md?language=en", headers = { "User-Agent": "Seniru" }).json()
Expand Down Expand Up @@ -198,7 +212,7 @@ async def on_error(self, evt, *args, **kwargs):
if str(r) == "Cannot send a packet to a closed Connection.":
return await commands["restart"]["f"]([], None, self)

await self.get_channel(data["channels"]["staff"]).send(f"`[ERR][DISCORD@evt_{evt}]` ```py\n{traceback.format_exc()}```")
await self.get_channel(data["channels"]["logs"]).send(f"`[ERR][DISCORD@evt_{evt}]` ```py\n{traceback.format_exc()}```")

async def send_verification_key(self, member):
key = utils.generate_random_key(member.id)
Expand Down Expand Up @@ -243,7 +257,7 @@ async def start_period_tasks(self):
await commands[task[0]]["f"](task[1], None, self)
except Exception as e:
import traceback
await self.main_guild.get_channel(data["channels"]["staff"]).send(
await self.main_guild.get_channel(data["channels"]["logs"]).send(
"**`[DAILY TASK FAILURE|{0}]`** \n```py\n{1}```"
.format(task[0].upper(), traceback.format_exc()))
await last_daily_data.edit(content=str(now.timestamp()))
Expand Down
110 changes: 74 additions & 36 deletions src/bots/commands/ccmds.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import aiomysql
import utils

from discord import Embed
Expand All @@ -6,30 +7,40 @@
async def cmds(args, msg, client):
"""Lists all the custom commands
"""
await msg.reply(embed = Embed.from_dict({
"title": "Available custom commands",
"description": "• " + "\n• ".join(client.ccmds.keys()),
"color": 0x2987ba
}))
async with client.db.acquire() as conn:
cur = await conn.cursor()
await cur.execute("SELECT name FROM CustomCommands;")
r = await cur.fetchall()
await msg.reply(embed = Embed.from_dict({
"title": "Available custom commands",
"description": "• " + "\n• ".join(map(lambda c: c[0], r)),
"color": 0x2987ba
}))

async def cmd(args, msg, client):
"""Displays information about a custom command
Args:
command (string): The command
"""
cmd_name = utils.get(args, 0, "")
cmd = client.ccmds.get(cmd_name)
if not cmd:
return await msg.reply(":x: | Cannot find that command")
await msg.reply(embed = Embed.from_dict({
"title": "Custom command info",
"fields": [
{ "name": "Author", "value": "<@!{}>".format(cmd["author"]) },
{ "name": "Source", "value": "[{source}]({source})".format(source = cmd["source"])}
],
"color": 0x2987ba
}))
async with client.db.acquire() as conn:
cur = await conn.cursor(aiomysql.DictCursor)
cmd_name = utils.get(args, 0, "")
await cur.execute(
"SELECT * FROM CustomCommands \
WHERE name LIKE %s;"
, [cmd_name])
cmd = await cur.fetchone()
if not cmd:
return await msg.reply(":x: | Cannot find that command")
await msg.reply(embed = Embed.from_dict({
"title": "Custom command info",
"fields": [
{ "name": "Author", "value": "<@!{}>".format(cmd["author"]) },
{ "name": "Source", "value": "[{source}]({source})".format(source = cmd["source"])}
],
"color": 0x2987ba
}))

async def ccmd(args, msg, client):
"""Creates a new custom command
Expand All @@ -44,12 +55,19 @@ async def ccmd(args, msg, client):
name, compiler, source = args[0], args[1], args[2]
if len(name) > 10:
return await msg.reply(":x: Command name should be less than or equal to 10 characters")
if client.ccmds.get(name):
return await msg.reply("Command **{}** already exists! Please use `> ecmd` to overwrite it!".format(name))

client.ccmds[name] = { "runner": compiler, "source": source, "author": str(msg.author.id) } # stringified id for backward compatibility
await client.update_ccmds()
await msg.reply(":white_check_mark: | Created the command")
async with client.db.acquire() as conn:
cur = await conn.cursor(aiomysql.DictCursor)
try:
await cur.execute(
"INSERT INTO CustomCommands \
VALUES (%s, %s, %s, %s);",
[name, compiler, source, msg.author.id]
)
await conn.commit()
await msg.reply(":white_check_mark: | Created the command")
except Exception as e:
if e.args[0] == 1062:
await msg.reply("Command **{}** already exists! Please use `> ecmd` to overwrite it!".format(name))


async def dcmd(args, msg, client):
Expand All @@ -59,13 +77,23 @@ async def dcmd(args, msg, client):
command (string): Command name
"""
cmd_name = utils.get(args, 0, "")
cmd = client.ccmds.get(cmd_name)
admin_role = client.main_guild.get_role(data["roles"]["admin"])
if not (cmd and (cmd["author"] == str(msg.author.id) or (admin_role in msg.author.roles))):
return await msg.reply(":x: You are not the author of the specified command or the command doesn't exist!")
client.ccmds.pop(cmd_name)
await client.update_ccmds()
await msg.reply(":white_check_mark: | Deleted the command")

async with client.db.acquire() as conn:
cur = await conn.cursor(aiomysql.DictCursor)
await cur.execute("SELECT * FROM CustomCommands \
WHERE name LIKE %s;",
[ cmd_name ]
)
cmd = await cur.fetchone()
if not (cmd and (cmd["author"] == str(msg.author.id) or (admin_role in msg.author.roles))):
return await msg.reply(":x: You are not the author of the specified command or the command doesn't exist!")
await cur.execute("DELETE FROM CustomCommands \
WHERE name LIKE %s;",
[ cmd_name ]
)
await conn.commit()
await msg.reply(":white_check_mark: | Deleted the command")

async def ecmd(args, msg, client):
"""Edits a custom command
Expand All @@ -78,13 +106,23 @@ async def ecmd(args, msg, client):
if len(args) < 3:
return await msg.reply(":x: Failed to edit the command. Please supply all the arguments\nFormat: `> ecmd <name> <compiler> <source>`")
name, compiler, source = args[0], args[1], args[2]
cmd = client.ccmds.get(name)

admin_role = client.main_guild.get_role(data["roles"]["admin"])
if not (cmd and (cmd["author"] == str(msg.author.id) or (admin_role in msg.author.roles))):
return await msg.reply(":x: You are not the author of the specified command or the command doesn't exist!")

async with client.db.acquire() as conn:
cur = await conn.cursor(aiomysql.DictCursor)
await cur.execute("SELECT * FROM CustomCommands \
WHERE name LIKE %s;",
[ name ]
)
cmd = await cur.fetchone()
if not (cmd and (cmd["author"] == msg.author.id or (admin_role in msg.author.roles))):
return await msg.reply(":x: You are not the author of the specified command or the command doesn't exist!")

await cur.execute("UPDATE CustomCommands \
SET runner=%s, source=%s \
WHERE name LIKE %s",
[ compiler, source, name ]
)

client.ccmds[name] = { "runner": compiler, "source": source, "author": str(msg.author.id) } # stringified id for backward compatibility
await client.update_ccmds()
await msg.reply(":white_check_mark: | Editted the command")
await conn.commit()
await msg.reply(":white_check_mark: | Editted the command")
3 changes: 2 additions & 1 deletion src/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"bday": 592742600058994688,
"admin": 592341953547337739,
"stats": 575328568008114176,
"staff": 905746669725962270
"staff": 905746669725962270,
"logs": 760004760048107530
},
"roles": {
"admin": 655909026101723147,
Expand Down
Loading

0 comments on commit ef1e25c

Please sign in to comment.