from data.database_classes.custom_commands import CustomCommand import discord from functions.database import utils def is_custom_command(message: discord.Message) -> CustomCommand: """ Check if a message triggers a custom command These use "?" as a prefix """ content = message.content # Message didn't call a custom command if not content.startswith("?"): return CustomCommand() # Can't be invoked by bots to prevent spam (@RPS) if message.author.bot: return CustomCommand() # Ignore capitals & spaces, strip off prefix content = content.lower().replace(" ", "")[1:] by_name = _find_by_name(content) # Command was found by its name if by_name: return CustomCommand(*by_name) # Check if a command exists with this alias instead return CustomCommand(*_find_by_alias(content), alias_used=content) def _find_by_name(message): """ Find a command by its name """ connection = utils.connect() cursor = connection.cursor() cursor.execute("SELECT * FROM custom_commands WHERE name = %s", (message,)) return cursor.fetchone() def _find_by_alias(message): """ Find a command by one of its aliases """ connection = utils.connect() cursor = connection.cursor() cursor.execute("SELECT command FROM custom_command_aliases WHERE alias = %s", (message,)) res = cursor.fetchone() # No command matched this alias if not res: return () cursor.execute("SELECT * FROM custom_commands WHERE id = %s", (res,)) return cursor.fetchone() def is_name_free(name) -> bool: """ Check if a name is already in use by a command Includes aliases """ connection = utils.connect() cursor = connection.cursor() cursor.execute("SELECT id from custom_commands WHERE name = %s", (name,)) if cursor.fetchone(): return False cursor.execute("SELECT id FROM custom_command_aliases WHERE alias = %s", (name,)) return cursor.fetchone() is None def _clean(inp: str): """ Strip markdown and other stuff out of a command name """ return "".join(filter(lambda x: x.isalnum(), inp)) def add_command(name: str, response: str): """ Add a new custom command """ name = _clean(name.lower()) if not is_name_free(name): return "Er is al een commando met deze naam." connection = utils.connect() cursor = connection.cursor() cursor.execute("INSERT INTO custom_commands(name, response) VALUES (%s, E%s)", (name, response,)) connection.commit() def add_alias(command: str, alias: str): """ Add an alias for a command Assumes the command exists """ command = _clean(command.lower()) alias = _clean(alias.lower()) # Base command doesn't exist if is_name_free(command): return "Er is geen commando met deze naam." # Alias already exists if not is_name_free(alias): return "Er is al een commando met deze naam." # Find the id of the base command command_id = CustomCommand(*_find_by_name(command)).id connection = utils.connect() cursor = connection.cursor() cursor.execute("INSERT INTO custom_command_aliases(command, alias) VALUES(%s, %s)", (command_id, alias,)) connection.commit() def get_all(): """ Return a list of all registered custom commands """ connection = utils.connect() cursor = connection.cursor() cursor.execute("SELECT * FROM custom_commands") commands = cursor.fetchall() ret = [] # Create a list of all entries for command in commands: dic = {"id": command[0], "name": command[1], "response": command[2]} # Find and add aliases cursor.execute("SELECT id, alias FROM custom_command_aliases WHERE command = %s", (command[0],)) aliases = cursor.fetchall() if aliases: dic["aliases"] = list(map(lambda x: {"id": x[0], "alias": x[1]}, aliases)) ret.append(dic) return ret def get_by_id(command_id: int): """ Return a command that matches a given id """ connection = utils.connect() cursor = connection.cursor() cursor.execute("SELECT * FROM custom_commands WHERE id = %s", (command_id,)) command = cursor.fetchone() # Nothing found if not command: return None dic = {"id": command[0], "name": command[1], "response": command[2]} cursor.execute("SELECT id, alias FROM custom_command_aliases WHERE command = %s", (command_id,)) aliases = cursor.fetchall() if aliases: dic["aliases"] = list(map(lambda x: {"id": x[0], "alias": x[1]}, aliases)) return dic