1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 22:23:13 +00:00

Add reactions table and service

This commit is contained in:
wlinator 2024-07-10 21:03:20 +02:00
parent 43466b86fb
commit b8f707e8f8
3 changed files with 171 additions and 2 deletions

View file

@ -0,0 +1,21 @@
-- Create a table to store custom reactions
CREATE TABLE custom_reactions (
id SERIAL PRIMARY KEY, -- Unique identifier for each custom reaction
trigger TEXT NOT NULL, -- The text that triggers the custom reaction
response TEXT, -- The response text for the custom reaction (nullable for emoji reactions)
emoji TEXT, -- The emoji for the custom reaction (nullable for text responses)
is_emoji BOOLEAN DEFAULT FALSE, -- Indicates if the reaction is a discord emoji reaction
is_full_match BOOLEAN DEFAULT FALSE, -- Indicates if the trigger matches the full content of the message
is_global BOOLEAN DEFAULT TRUE, -- Indicates if the reaction is global or specific to a guild
guild_id BIGINT, -- The ID of the guild where the custom reaction is used (nullable for global reactions)
creator_id BIGINT NOT NULL, -- The ID of the user who created the custom reaction
usage_count INT DEFAULT 0, -- The number of times a custom reaction has been used
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the custom reaction was created
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the custom reaction was last updated
CONSTRAINT unique_trigger_guild UNIQUE (trigger, guild_id) -- Ensure that the combination of trigger, guild_id, and is_full_match is unique
);
-- Create indexes to speed up lookups
CREATE INDEX idx_custom_reactions_guild_id ON custom_reactions(guild_id);
CREATE INDEX idx_custom_reactions_creator_id ON custom_reactions(creator_id);
CREATE INDEX idx_custom_reactions_trigger ON custom_reactions(trigger);

View file

@ -2,8 +2,7 @@ import random
import asyncio import asyncio
from typing import List, Dict, Any from typing import List, Dict, Any
import discord from discord.ext.commands import Cog
from discord.ext.commands import Cog, Context, EmojiConverter
from discord import Message from discord import Message
from config.parser import JsonCache from config.parser import JsonCache

View file

@ -0,0 +1,149 @@
"""
TABLE custom_reactions:
id SERIAL PRIMARY KEY
trigger TEXT NOT NULL
response TEXT
emoji TEXT
is_emoji BOOLEAN DEFAULT FALSE
is_full_match BOOLEAN DEFAULT FALSE
is_global BOOLEAN DEFAULT TRUE
guild_id BIGINT
creator_id BIGINT NOT NULL
usage_count INT DEFAULT 0
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
CONSTRAINT unique_trigger_guild UNIQUE (trigger, guild_id)
"""
from typing import Optional, Dict, Any
from datetime import datetime
from db import database
class CustomReactionsService:
def __init__(self):
pass
async def find_trigger(
self, guild_id: int, message_content: str
) -> Optional[Dict[str, Any]]:
message_content = message_content.lower()
query = """
SELECT * FROM custom_reactions
WHERE (guild_id = ? OR is_global = TRUE) AND (
(is_full_match = TRUE AND trigger = ?) OR
(is_full_match = FALSE AND ? LIKE CONCAT('%', trigger, '%'))
)
ORDER BY guild_id = ? DESC, is_global ASC
LIMIT 1
"""
result = database.select_query_one(query, (guild_id, message_content, message_content, guild_id))
if result:
reaction = dict(result)
return {
"response": reaction.get("response"),
"type": "emoji" if reaction.get("is_emoji") else "text"
}
return None
async def create_custom_reaction(
self,
guild_id: int,
creator_id: int,
trigger: str,
response: Optional[str] = None,
emoji: Optional[str] = None,
is_emoji: bool = False,
is_full_match: bool = False,
is_global: bool = True,
) -> bool:
if await self.count_custom_reactions(guild_id) >= 100:
return False
query = """
INSERT INTO custom_reactions (trigger, response, emoji, is_emoji, is_full_match, is_global, guild_id, creator_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE trigger=trigger
"""
database.execute_query(
query,
(
trigger,
response,
emoji,
is_emoji,
is_full_match,
is_global,
guild_id,
creator_id,
),
)
return True
async def edit_custom_reaction(
self,
guild_id: int,
trigger: str,
new_response: Optional[str] = None,
new_emoji: Optional[str] = None,
is_emoji: Optional[bool] = None,
is_full_match: Optional[bool] = None,
is_global: Optional[bool] = None,
) -> bool:
query = """
UPDATE custom_reactions
SET response = COALESCE(?, response),
emoji = COALESCE(?, emoji),
is_emoji = COALESCE(?, is_emoji),
is_full_match = COALESCE(?, is_full_match),
is_global = COALESCE(?, is_global),
updated_at = ?
WHERE guild_id = ? AND trigger = ?
"""
database.execute_query(
query,
(
new_response,
new_emoji,
is_emoji,
is_full_match,
is_global,
datetime.utcnow(),
guild_id,
trigger,
),
)
return True
async def delete_custom_reaction(self, guild_id: int, trigger: str) -> bool:
query = """
DELETE FROM custom_reactions
WHERE guild_id = ? AND trigger = ?
"""
database.execute_query(query, (guild_id, trigger))
return True
async def count_custom_reactions(self, guild_id: int) -> int:
query = """
SELECT COUNT(*) FROM custom_reactions
WHERE guild_id = ?
"""
count = database.select_query_one(query, (guild_id,))
return count if count else 0
async def increment_reaction_usage(self, guild_id: int, trigger: str) -> bool:
query = """
UPDATE custom_reactions
SET usage_count = usage_count + 1,
updated_at = ?
WHERE guild_id = ? AND trigger = ?
"""
database.execute_query(
query,
(
datetime.utcnow(),
guild_id,
trigger,
),
)
return True