From a5b7872d3f032085db9f710445180b4c04c5b6f3 Mon Sep 17 00:00:00 2001 From: diamante0018 Date: Wed, 5 Mar 2025 21:44:50 +0100 Subject: [PATCH] feat: DB for patterns --- Dockerfile | 14 +++++++---- aw.py | 4 ++++ bot/commands.py | 19 +++++++++++++++ bot/config.py | 46 ++++++++++++++++++++++++++++++++---- database/__init__.py | 55 ++++++++++++++++++++++++++++++++++++++++++++ database/schema.sql | 5 ++++ patterns.json | 4 ++++ 7 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 database/__init__.py create mode 100644 database/schema.sql diff --git a/Dockerfile b/Dockerfile index dbbb597..0f03441 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,17 @@ FROM python:alpine WORKDIR /aw-bot -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt -COPY bot /aw-bot/bot -COPY aw.py . -COPY patterns.json . +COPY bot /aw-bot/bot +COPY database /aw-bot/database +COPY aw.py . +COPY patterns.json . ENV BOT_TOKEN="" +# Where the database will be stored +ENV BOT_DATA_DIR = "" + CMD ["python", "aw.py"] diff --git a/aw.py b/aw.py index 88882cb..8f16ea1 100644 --- a/aw.py +++ b/aw.py @@ -3,6 +3,8 @@ import os import discord from discord.ext import commands +from database import initialize_db + GUILD_ID = 1110531063161299074 BOT_LOG = 1112049391482703873 GENERAL_CHANNEL = 1110531063744303138 @@ -11,6 +13,8 @@ OFFTOPIC_CHANNEL = 1112048063448617142 intents = discord.Intents.all() bot = commands.Bot(command_prefix="!", intents=intents) +initialize_db() + @bot.event async def on_ready(): diff --git a/bot/commands.py b/bot/commands.py index 2c7a016..02764a1 100644 --- a/bot/commands.py +++ b/bot/commands.py @@ -3,6 +3,9 @@ from typing import Literal import discord from discord import app_commands +from database import add_pattern + +from bot.config import update_patterns from bot.utils import compile_stats, fetch_game_stats, perform_search GUILD_ID = 1110531063161299074 @@ -25,6 +28,22 @@ async def setup(bot): bot.tree.on_error = on_tree_error + @bot.tree.command( + name="add_pattern", + description="Add a new message pattern to the database.", + guild=discord.Object(id=GUILD_ID), + ) + @app_commands.checks.has_permissions(administrator=True) + async def add_pattern_cmd( + interaction: discord.Interaction, regex: str, response: str + ): + """Slash command to add a new message pattern to the database.""" + add_pattern(regex, response) + update_patterns(regex, response) + await interaction.response.send_message( + f"Pattern added!\n**Regex:** `{regex}`\n**Response:** `{response}`" + ) + @bot.tree.command( name="search", description="Search for servers by hostname or IP.", diff --git a/bot/config.py b/bot/config.py index 1287375..f1ea1e2 100644 --- a/bot/config.py +++ b/bot/config.py @@ -1,7 +1,43 @@ import json +import os +from database import get_patterns, add_pattern -try: - with open("patterns.json", "r") as f: - message_patterns = json.load(f) -except FileNotFoundError: - message_patterns = [] # Fallback to an empty list if the file doesn't exist +PATTERNS_FILE = "patterns.json" + +BOT_DATA_DIR = os.getenv("BOT_DATA_DIR", "/bot-data") +MIGRATION_FLAG = os.path.join(BOT_DATA_DIR, "migration_done.flag") + + +def migrate_patterns(): + """Migrate patterns.json to the database if not already done.""" + if os.path.exists(MIGRATION_FLAG): + print("Not performing migration: already done") + return + + if not os.path.exists(PATTERNS_FILE): + return + + try: + with open(PATTERNS_FILE, "r") as f: + patterns = json.load(f) + except (json.JSONDecodeError, FileNotFoundError): + patterns = [] + + for pattern in patterns: + add_pattern(pattern["regex"], pattern["response"]) + + with open(MIGRATION_FLAG, "w") as f: + f.write("done") + + print("Migration completed: patterns.json -> Database") + + +migrate_patterns() + +message_patterns = get_patterns() + + +def update_patterns(regex: str, response: str): + """update patterns in memory.""" + message_patterns.append({"regex": regex, "response": response}) + print(f"Pattern added in memory: {regex}") diff --git a/database/__init__.py b/database/__init__.py new file mode 100644 index 0000000..2474443 --- /dev/null +++ b/database/__init__.py @@ -0,0 +1,55 @@ +import sqlite3 +import os + +DB_DIR = os.getenv("BOT_DATA_DIR", "/bot-data") +DB_PATH = os.path.join(DB_DIR, "database.db") + +os.makedirs(DB_DIR, exist_ok=True) + + +def initialize_db(): + """Creates the database tables if they don't exist.""" + print(f"Opening database: {DB_PATH}") + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + + with open(os.path.join(os.path.dirname(__file__), "schema.sql"), "r") as f: + cursor.executescript(f.read()) + + conn.commit() + conn.close() + + +def add_pattern(regex: str, response: str): + """Adds a new pattern to the database.""" + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + + cursor.execute( + "INSERT INTO message_patterns (regex, response) VALUES (?, ?)", + (regex, response), + ) + conn.commit() + conn.close() + + +def get_patterns(): + """Fetches all regex-response pairs from the database.""" + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + + cursor.execute("SELECT regex, response FROM message_patterns") + patterns = cursor.fetchall() + conn.close() + + return [{"regex": row[0], "response": row[1]} for row in patterns] + + +def remove_pattern(pattern_id: int): + """Removes a pattern by ID.""" + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + + cursor.execute("DELETE FROM message_patterns WHERE id = ?", (pattern_id,)) + conn.commit() + conn.close() diff --git a/database/schema.sql b/database/schema.sql new file mode 100644 index 0000000..ea1c1d1 --- /dev/null +++ b/database/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS message_patterns ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + regex TEXT NOT NULL, + response TEXT NOT NULL +) diff --git a/patterns.json b/patterns.json index 004df14..ded0bfe 100644 --- a/patterns.json +++ b/patterns.json @@ -330,5 +330,9 @@ { "regex": "andrew tate", "response": "https://cdn.discordapp.com/attachments/1112049391482703873/1346497706964815952/GlEMX4TWQAAUqlc.jpg" + }, + { + "regex": "suicide", + "response": "https://cdn.discordapp.com/attachments/1160511084143312959/1346587278499119234/Snapinst.app_video_AQPJue2aNWd3IuxSsCqEwyFbm7FweOLHfRPFQIfk4U7J9krpIydfGSTdmXqa04ozGljyxNCVBjqu-cHgEAw1LMX4ImX1Zr849d7cUc4.mp4" } ] \ No newline at end of file