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:
parent
43466b86fb
commit
b8f707e8f8
3 changed files with 171 additions and 2 deletions
21
db/migrations/v2_5_9_reactions.sql
Normal file
21
db/migrations/v2_5_9_reactions.sql
Normal 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);
|
|
@ -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
|
||||||
|
|
149
services/reactions_service.py
Normal file
149
services/reactions_service.py
Normal 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
|
Loading…
Reference in a new issue