From a70a5a39126de5895bf2ac7887a3100d2e4dfeb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Chwiedziuk?= Date: Mon, 19 Aug 2024 20:27:46 +0200 Subject: [PATCH 01/15] New --- .gitignore | 1 + config-example.ini | 3 ++ main.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 .gitignore create mode 100644 config-example.ini create mode 100644 main.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2fa7ce7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.ini diff --git a/config-example.ini b/config-example.ini new file mode 100644 index 0000000..01b0d4f --- /dev/null +++ b/config-example.ini @@ -0,0 +1,3 @@ +[ROK] +server_ID = 111 +kruh-XX = 6 diff --git a/main.py b/main.py new file mode 100644 index 0000000..4aae035 --- /dev/null +++ b/main.py @@ -0,0 +1,82 @@ +import discord +from discord.ext import commands +from configparser import ConfigParser + +# Bot token (replace with your own) +TOKEN = 'MTE1NDc0ODQ3MzE4MzMwNTc4OQ.Gz_Q7u.02sb2YNV_QQy7Bs19roXlB62mjoMKA6y8aubHU' +# Iterate over the sections in the config file + + +def get_server_IDs(): + config = ConfigParser() + config.read("config.ini") + server_IDs = [] + for section in config.sections(): + server_IDs.append(int(config[section]['server_ID'])) + return server_IDs + + +# Create an instance of the bot +intents = discord.Intents.default() +intents.members = True +bot = commands.Bot(command_prefix='!', intents=intents) + +# Study group roles and their corresponding IDs (you can customize this) +def get_study_groups(server_id): + config = ConfigParser() + config.read("config.ini") + + study_groups = {} + for section in config.sections(): + if int(config[section]['server_ID']) == server_id: + # Study group names are in style "kruh-XX", where XX is a two-digit number + # Iterate over all from top to bottom + for (key, value) in config.items(section): + if key.startswith('kruh-'): + study_groups[key] = int(value) + return study_groups + +@bot.event +async def on_ready(): + print(f'Logged in as {bot.user.name}') + + +@bot.command() +async def grant_role(ctx, study_group_name: str): + server_IDs = get_server_IDs() + author_id = ctx.author.id + + for guild_id in server_IDs: + guild = bot.get_guild(guild_id) + if guild is None: + continue + author = guild.get_member(author_id) + if author is None: + continue + study_groups = get_study_groups(guild_id) + if study_group_name in study_groups: + role_name = study_groups[study_group_name] + role = discord.utils.get(guild.roles, id=role_name) + + if role is not None: + await author.add_roles(role) + await ctx.send(f'{author.mention} has been granted the {study_group_name} role on server {guild.name}.') + return + await ctx.send('Something gone wrong. Please check your command and try again.') + return + + +@bot.event +async def on_message(message): + # Check if the message is a private message and not from the bot itself + if isinstance(message.channel, discord.DMChannel) and message.author != bot.user: + # Split the message content into words + words = message.content.split() + + # Check if the message starts with the bot's command prefix and has enough arguments + if len(words) >= 3 and words[0] == '!grant_role': + # Process the command + await bot.process_commands(message) + +# Run the bot +bot.run(TOKEN) From 7b2ec67cb66b57f9ccc3fad992829eea133562e9 Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Mon, 23 Sep 2024 18:32:00 +0200 Subject: [PATCH 02/15] Add Python requirements file --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c8e4765 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +discord==2.3.2 From 5c4729a284fad6c5edc4140cae3d673c886e5da2 Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Tue, 24 Sep 2024 15:12:33 +0200 Subject: [PATCH 03/15] chore: git ignore venv, vscode files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2fa7ce7..dfdead7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ config.ini +.venv +.vscode From 6d4f0d7e8d05589ee80598ba8894c697a0647273 Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Tue, 24 Sep 2024 15:13:52 +0200 Subject: [PATCH 04/15] rf: message sending --- main.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 4aae035..83b97a9 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,14 @@ from configparser import ConfigParser # Bot token (replace with your own) TOKEN = 'MTE1NDc0ODQ3MzE4MzMwNTc4OQ.Gz_Q7u.02sb2YNV_QQy7Bs19roXlB62mjoMKA6y8aubHU' -# Iterate over the sections in the config file + + +async def reply_error(ctx: commands.Context, message: str): + await reply(ctx, f'**Error:** {message}', True) + + +async def reply(ctx: commands.Context, message: str): + await ctx.send(message) def get_server_IDs(): @@ -60,9 +67,9 @@ async def grant_role(ctx, study_group_name: str): if role is not None: await author.add_roles(role) - await ctx.send(f'{author.mention} has been granted the {study_group_name} role on server {guild.name}.') + await reply(ctx, f'{author.mention} has been granted the {study_group_name} role on the [{guild.name}] server.') return - await ctx.send('Something gone wrong. Please check your command and try again.') + await reply_error(ctx, 'Something went wrong. Please check your command and try again.') return From ff5993997ab0cc68f698afbb45eaed9d3ec3fd8f Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Tue, 24 Sep 2024 16:08:30 +0200 Subject: [PATCH 05/15] rf: file structure, default config file --- main.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/main.py b/main.py index 83b97a9..0e68a89 100644 --- a/main.py +++ b/main.py @@ -2,8 +2,18 @@ import discord from discord.ext import commands from configparser import ConfigParser -# Bot token (replace with your own) -TOKEN = 'MTE1NDc0ODQ3MzE4MzMwNTc4OQ.Gz_Q7u.02sb2YNV_QQy7Bs19roXlB62mjoMKA6y8aubHU' +TOKEN = 'MTE1NDc0ODQ3MzE4MzMwNTc4OQ.Gz_Q7u.02sb2YNV_QQy7Bs19roXlB62mjoMKA6y8aubHU' # Bot token (replace with your own) +DEFAULT_CONFIG_FILE = 'config.ini' # Configuration file with server IDs and study group roles + + +# Create an instance of the bot +intents = discord.Intents.default() +intents.members = True + +config = ConfigParser() +config.read(DEFAULT_CONFIG_FILE) + +bot = commands.Bot(command_prefix='!', intents=intents) async def reply_error(ctx: commands.Context, message: str): @@ -16,22 +26,16 @@ async def reply(ctx: commands.Context, message: str): def get_server_IDs(): config = ConfigParser() - config.read("config.ini") + config.read(DEFAULT_CONFIG_FILE) server_IDs = [] for section in config.sections(): server_IDs.append(int(config[section]['server_ID'])) return server_IDs - -# Create an instance of the bot -intents = discord.Intents.default() -intents.members = True -bot = commands.Bot(command_prefix='!', intents=intents) - # Study group roles and their corresponding IDs (you can customize this) def get_study_groups(server_id): config = ConfigParser() - config.read("config.ini") + config.read(DEFAULT_CONFIG_FILE) study_groups = {} for section in config.sections(): From cdd68052caf8f53fde6e911cd02b5bd3bc05b12e Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Tue, 24 Sep 2024 16:24:54 +0200 Subject: [PATCH 06/15] perf: compute study groups from config only once --- main.py | 63 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/main.py b/main.py index 0e68a89..87a07ab 100644 --- a/main.py +++ b/main.py @@ -10,9 +10,6 @@ DEFAULT_CONFIG_FILE = 'config.ini' # Configuration file with server IDs and stud intents = discord.Intents.default() intents.members = True -config = ConfigParser() -config.read(DEFAULT_CONFIG_FILE) - bot = commands.Bot(command_prefix='!', intents=intents) @@ -24,28 +21,31 @@ async def reply(ctx: commands.Context, message: str): await ctx.send(message) -def get_server_IDs(): - config = ConfigParser() - config.read(DEFAULT_CONFIG_FILE) - server_IDs = [] - for section in config.sections(): - server_IDs.append(int(config[section]['server_ID'])) - return server_IDs +def init(config): + """ + Initialize the server IDs and study groups from the configuration file. + :param config: The configuration file. + :return: A tuple with server IDs and study groups. + """ + def get_section_server_id(section): + return int(config[section]["server_ID"]) -# Study group roles and their corresponding IDs (you can customize this) -def get_study_groups(server_id): - config = ConfigParser() - config.read(DEFAULT_CONFIG_FILE) + server_ids = {get_section_server_id(section) for section in config.sections() if "server_ID" in config[section]} + study_groups = {server_id: dict() for server_id in server_ids} - study_groups = {} for section in config.sections(): - if int(config[section]['server_ID']) == server_id: - # Study group names are in style "kruh-XX", where XX is a two-digit number - # Iterate over all from top to bottom - for (key, value) in config.items(section): - if key.startswith('kruh-'): - study_groups[key] = int(value) - return study_groups + server_id = get_section_server_id(section) + if server_id is None: + continue + + # Study group names are in style "kruh-XX", where XX is a two-digit number + # Iterate over all from top to bottom + for (key, value) in config.items(section): + if key.startswith('kruh-'): + study_groups[server_id][key] = int(value) + + return server_ids, study_groups + @bot.event async def on_ready(): @@ -54,25 +54,28 @@ async def on_ready(): @bot.command() async def grant_role(ctx, study_group_name: str): - server_IDs = get_server_IDs() author_id = ctx.author.id - for guild_id in server_IDs: + for guild_id in server_ids: guild = bot.get_guild(guild_id) + if guild is None: continue + author = guild.get_member(author_id) + if author is None: continue - study_groups = get_study_groups(guild_id) - if study_group_name in study_groups: - role_name = study_groups[study_group_name] + + if study_group_name in study_groups[guild_id]: + role_name = study_groups[guild_id][study_group_name] role = discord.utils.get(guild.roles, id=role_name) if role is not None: await author.add_roles(role) await reply(ctx, f'{author.mention} has been granted the {study_group_name} role on the [{guild.name}] server.') return + await reply_error(ctx, 'Something went wrong. Please check your command and try again.') return @@ -89,5 +92,11 @@ async def on_message(message): # Process the command await bot.process_commands(message) + +config = ConfigParser() +config.read(DEFAULT_CONFIG_FILE) + +server_ids, study_groups = init(config) + # Run the bot bot.run(TOKEN) From cf22845aa6f68c31166423cf1c97626fd8d14d49 Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Tue, 24 Sep 2024 16:44:14 +0200 Subject: [PATCH 07/15] feat: log --- main.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 87a07ab..e121f96 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,12 @@ +from configparser import ConfigParser +import logging + import discord from discord.ext import commands -from configparser import ConfigParser TOKEN = 'MTE1NDc0ODQ3MzE4MzMwNTc4OQ.Gz_Q7u.02sb2YNV_QQy7Bs19roXlB62mjoMKA6y8aubHU' # Bot token (replace with your own) DEFAULT_CONFIG_FILE = 'config.ini' # Configuration file with server IDs and study group roles +DEFAULT_LOG_FILE = 'kruhobot.log' # Log file for the bot # Create an instance of the bot @@ -12,6 +15,9 @@ intents.members = True bot = commands.Bot(command_prefix='!', intents=intents) +logging.basicConfig(filename=DEFAULT_LOG_FILE, level=logging.INFO) +logger = logging.getLogger("Kruhobot") + async def reply_error(ctx: commands.Context, message: str): await reply(ctx, f'**Error:** {message}', True) @@ -49,7 +55,7 @@ def init(config): @bot.event async def on_ready(): - print(f'Logged in as {bot.user.name}') + logger.info(f'Logged in as {bot.user.name}') @bot.command() @@ -74,9 +80,11 @@ async def grant_role(ctx, study_group_name: str): if role is not None: await author.add_roles(role) await reply(ctx, f'{author.mention} has been granted the {study_group_name} role on the [{guild.name}] server.') + logger.info(f'Granted role [{role_name}] to [{author_id}] in [{guild_id}] corresponding to the study group [{study_group_name}].') return await reply_error(ctx, 'Something went wrong. Please check your command and try again.') + logger.error(f'Failed to grant a role to [{author_id}] in [{guild_id}] corresponding to the study group [{study_group_name}].') return From b05c63d86a696b238d4593f183a2f09dda398659 Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 00:02:04 +0200 Subject: [PATCH 08/15] feat: add message_content intent --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index e121f96..c56ce1d 100644 --- a/main.py +++ b/main.py @@ -12,6 +12,7 @@ DEFAULT_LOG_FILE = 'kruhobot.log' # Log file for the bot # Create an instance of the bot intents = discord.Intents.default() intents.members = True +intents.message_content = True bot = commands.Bot(command_prefix='!', intents=intents) From 940cf1904310aa556276bf41d5cf6daa1fbc0aac Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 00:03:07 +0200 Subject: [PATCH 09/15] chore: git ignore logs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dfdead7..db589ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ config.ini .venv .vscode +*.log From b1e353a8902c8229deea76f33a2d00056626730d Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 00:24:59 +0200 Subject: [PATCH 10/15] feat: command checks --- main.py | 129 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 92 insertions(+), 37 deletions(-) diff --git a/main.py b/main.py index c56ce1d..b367321 100644 --- a/main.py +++ b/main.py @@ -7,7 +7,9 @@ from discord.ext import commands TOKEN = 'MTE1NDc0ODQ3MzE4MzMwNTc4OQ.Gz_Q7u.02sb2YNV_QQy7Bs19roXlB62mjoMKA6y8aubHU' # Bot token (replace with your own) DEFAULT_CONFIG_FILE = 'config.ini' # Configuration file with server IDs and study group roles DEFAULT_LOG_FILE = 'kruhobot.log' # Log file for the bot - +HELP_MESSAGE = """Usage: `!grant_role kruh-## UKCO` +- Replace `##` with your study group number +- Replace `UKCO` with your UKCO (8-digit personal number).""" # Create an instance of the bot intents = discord.Intents.default() @@ -19,39 +21,31 @@ bot = commands.Bot(command_prefix='!', intents=intents) logging.basicConfig(filename=DEFAULT_LOG_FILE, level=logging.INFO) logger = logging.getLogger("Kruhobot") - -async def reply_error(ctx: commands.Context, message: str): - await reply(ctx, f'**Error:** {message}', True) +config = ConfigParser() +config.read(DEFAULT_CONFIG_FILE) -async def reply(ctx: commands.Context, message: str): - await ctx.send(message) - - -def init(config): +async def reply_error(ctx, message: str): """ - Initialize the server IDs and study groups from the configuration file. - :param config: The configuration file. - :return: A tuple with server IDs and study groups. + Reply to the user with an error message. + :param ctx: The context of the command. + :param message: The error message. """ - def get_section_server_id(section): - return int(config[section]["server_ID"]) + await reply(ctx, f'**Error:** {message}') - server_ids = {get_section_server_id(section) for section in config.sections() if "server_ID" in config[section]} - study_groups = {server_id: dict() for server_id in server_ids} - for section in config.sections(): - server_id = get_section_server_id(section) - if server_id is None: - continue - - # Study group names are in style "kruh-XX", where XX is a two-digit number - # Iterate over all from top to bottom - for (key, value) in config.items(section): - if key.startswith('kruh-'): - study_groups[server_id][key] = int(value) - - return server_ids, study_groups +async def reply(ctx, message: str): + """ + Reply to the user. + :param ctx: The context of the command or the channel from the event handler. + :param message: The message to reply with. + """ + if isinstance(ctx, commands.Context): + await ctx.send(message) + elif isinstance(ctx, discord.abc.Messageable): + await ctx.send(message) + else: + logger.error(f'Failed to send the following message: "{message}"') @bot.event @@ -89,21 +83,82 @@ async def grant_role(ctx, study_group_name: str): return +def check_command(message): + # Split the message content into words + words = message.content.split() + + if len(words) == 0: + return False + + # Check if the message is a command + if not words[0].startswith('!'): + reply(message.channel, HELP_MESSAGE) + return False + + # Check if the command is recognized + if not words[0] == '!grant_role': + reply_error(message.channel, 'Unrecognized command.') + reply(message.channel, HELP_MESSAGE) + return False + + # Check if the number of arguments is correct + if not len(words) == 3: + reply_error(message.channel, 'Invalid number of arguments.') + reply(message.channel, HELP_MESSAGE) + return False + + # Check study group format + if not words[1].startswith('kruh-') or not words[1][5:].isdigit(): + reply_error(message.channel, 'Invalid study group format.') + reply(message.channel, HELP_MESSAGE) + return False + + if not words[2].isdigit() or not len(words[2]) == 8: + reply_error(message.channel, 'Invalid UKCO format.') + reply(message.channel, HELP_MESSAGE) + return False + + return True + + @bot.event async def on_message(message): # Check if the message is a private message and not from the bot itself - if isinstance(message.channel, discord.DMChannel) and message.author != bot.user: - # Split the message content into words - words = message.content.split() + if not isinstance(message.channel, discord.DMChannel) or message.author == bot.user: + return - # Check if the message starts with the bot's command prefix and has enough arguments - if len(words) >= 3 and words[0] == '!grant_role': - # Process the command - await bot.process_commands(message) + is_valid_command = check_command(message) + if not is_valid_command: + return + + await bot.process_commands(message) -config = ConfigParser() -config.read(DEFAULT_CONFIG_FILE) +def init(config): + """ + Initialize the server IDs and study groups from the configuration file. + :param config: The configuration file. + :return: A tuple with server IDs and study groups. + """ + def get_section_server_id(section): + return int(config[section]["server_ID"]) + + server_ids = {get_section_server_id(section) for section in config.sections() if "server_ID" in config[section]} + study_groups = {server_id: dict() for server_id in server_ids} + + for section in config.sections(): + server_id = get_section_server_id(section) + if server_id is None: + continue + + # Study group names are in style "kruh-XX", where XX is a two-digit number + # Iterate over all from top to bottom + for (key, value) in config.items(section): + if key.startswith('kruh-'): + study_groups[server_id][key] = int(value) + + return server_ids, study_groups + server_ids, study_groups = init(config) From a4cf15ce1d7a4911d68d3bbe261c7f91f812624a Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 00:32:55 +0200 Subject: [PATCH 11/15] rf: replies through common function --- main.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/main.py b/main.py index b367321..3180474 100644 --- a/main.py +++ b/main.py @@ -40,10 +40,7 @@ async def reply(ctx, message: str): :param ctx: The context of the command or the channel from the event handler. :param message: The message to reply with. """ - if isinstance(ctx, commands.Context): - await ctx.send(message) - elif isinstance(ctx, discord.abc.Messageable): - await ctx.send(message) + await ctx.send(message) else: logger.error(f'Failed to send the following message: "{message}"') From 16f26119aa31d927c2351b171c1fce75d88af7c8 Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 00:33:39 +0200 Subject: [PATCH 12/15] rf: command argument checks in command function --- main.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 3180474..720eaaf 100644 --- a/main.py +++ b/main.py @@ -52,7 +52,17 @@ async def on_ready(): @bot.command() async def grant_role(ctx, study_group_name: str): - author_id = ctx.author.id + # Check study group format + if not words[1].startswith('kruh-') or not words[1][5:].isdigit(): + reply_error(ctx, 'Invalid study group format.') + reply(ctx, HELP_MESSAGE) + return False + + # Check UKCO format + if not words[2].isdigit() or not len(words[2]) == 8: + reply_error(ctx, 'Invalid UKCO format.') + reply(ctx, HELP_MESSAGE) + return False for guild_id in server_ids: guild = bot.get_guild(guild_id) @@ -104,17 +114,6 @@ def check_command(message): reply(message.channel, HELP_MESSAGE) return False - # Check study group format - if not words[1].startswith('kruh-') or not words[1][5:].isdigit(): - reply_error(message.channel, 'Invalid study group format.') - reply(message.channel, HELP_MESSAGE) - return False - - if not words[2].isdigit() or not len(words[2]) == 8: - reply_error(message.channel, 'Invalid UKCO format.') - reply(message.channel, HELP_MESSAGE) - return False - return True From 4b3a3a99e0291eb227a8ce536c5dc78c7b834b3b Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 00:44:14 +0200 Subject: [PATCH 13/15] rf: grant_role command function --- main.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/main.py b/main.py index 720eaaf..34fc48e 100644 --- a/main.py +++ b/main.py @@ -51,7 +51,13 @@ async def on_ready(): @bot.command() -async def grant_role(ctx, study_group_name: str): +async def grant_role(ctx, study_group_name: str, ukco: int): + """ + Grant a role to the user based on the study group and UKCO. + :param ctx: The context of the command. + :param study_group_name: The name of the study group. + :param ukco: The UKCO of the user. + """ # Check study group format if not words[1].startswith('kruh-') or not words[1][5:].isdigit(): reply_error(ctx, 'Invalid study group format.') @@ -65,28 +71,28 @@ async def grant_role(ctx, study_group_name: str): return False for guild_id in server_ids: + if study_group_name not in study_groups[guild_id]: # Check if the study group is valid for the server + continue + guild = bot.get_guild(guild_id) - - if guild is None: + if guild is None: # Check if the guild exists continue - author = guild.get_member(author_id) - - if author is None: + role = discord.utils.get(guild.roles, id=study_groups[guild_id][study_group_name]) + if role is None: # Check if the role exists continue - if study_group_name in study_groups[guild_id]: - role_name = study_groups[guild_id][study_group_name] - role = discord.utils.get(guild.roles, id=role_name) + author = guild.get_member(ctx.author.id) + if author is None: # Check if the author is a member of the guild + continue - if role is not None: - await author.add_roles(role) - await reply(ctx, f'{author.mention} has been granted the {study_group_name} role on the [{guild.name}] server.') - logger.info(f'Granted role [{role_name}] to [{author_id}] in [{guild_id}] corresponding to the study group [{study_group_name}].') - return + await author.add_roles(role) + await reply(ctx, f'{author.mention} has been granted the {role.mention} role on the [{guild.name}] server.') + logger.info(f'Granted role [{role.mention}] to [{author.mention}] in [{guild.name}] corresponding to the study group [{study_group_name}].') + return await reply_error(ctx, 'Something went wrong. Please check your command and try again.') - logger.error(f'Failed to grant a role to [{author_id}] in [{guild_id}] corresponding to the study group [{study_group_name}].') + logger.error(f'Failed to grant a role to [{author.mention}] corresponding to the study group [{study_group_name}].') return From e3e9fd6f6e05fa020dedeacd2d572dd1a6700c0f Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 00:54:40 +0200 Subject: [PATCH 14/15] fix: refactor bugs --- main.py | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/main.py b/main.py index 34fc48e..87db849 100644 --- a/main.py +++ b/main.py @@ -41,8 +41,6 @@ async def reply(ctx, message: str): :param message: The message to reply with. """ await ctx.send(message) - else: - logger.error(f'Failed to send the following message: "{message}"') @bot.event @@ -59,16 +57,16 @@ async def grant_role(ctx, study_group_name: str, ukco: int): :param ukco: The UKCO of the user. """ # Check study group format - if not words[1].startswith('kruh-') or not words[1][5:].isdigit(): - reply_error(ctx, 'Invalid study group format.') - reply(ctx, HELP_MESSAGE) - return False + if not study_group_name.startswith('kruh-') or not study_group_name[5:].isdigit(): + await reply_error(ctx, 'Invalid study group format.') + await reply(ctx, HELP_MESSAGE) + return # Check UKCO format - if not words[2].isdigit() or not len(words[2]) == 8: - reply_error(ctx, 'Invalid UKCO format.') - reply(ctx, HELP_MESSAGE) - return False + if not (1000_0000 < ukco < 9999_9999): + await reply_error(ctx, 'Invalid UKCO format.') + await reply(ctx, HELP_MESSAGE) + return for guild_id in server_ids: if study_group_name not in study_groups[guild_id]: # Check if the study group is valid for the server @@ -87,8 +85,8 @@ async def grant_role(ctx, study_group_name: str, ukco: int): continue await author.add_roles(role) - await reply(ctx, f'{author.mention} has been granted the {role.mention} role on the [{guild.name}] server.') - logger.info(f'Granted role [{role.mention}] to [{author.mention}] in [{guild.name}] corresponding to the study group [{study_group_name}].') + await reply(ctx, f'{author.mention} has been granted the [{role.name}] role on the [{guild.name}] server.') + logger.info(f'Granted role [{role.name}] to [{author.mention}] in [{guild.name}] corresponding to the study group [{study_group_name}].') return await reply_error(ctx, 'Something went wrong. Please check your command and try again.') @@ -96,7 +94,7 @@ async def grant_role(ctx, study_group_name: str, ukco: int): return -def check_command(message): +async def check_command(message): # Split the message content into words words = message.content.split() @@ -105,19 +103,19 @@ def check_command(message): # Check if the message is a command if not words[0].startswith('!'): - reply(message.channel, HELP_MESSAGE) + await reply(message.channel, HELP_MESSAGE) return False # Check if the command is recognized if not words[0] == '!grant_role': - reply_error(message.channel, 'Unrecognized command.') - reply(message.channel, HELP_MESSAGE) + await reply_error(message.channel, 'Unrecognized command.') + await reply(message.channel, HELP_MESSAGE) return False # Check if the number of arguments is correct if not len(words) == 3: - reply_error(message.channel, 'Invalid number of arguments.') - reply(message.channel, HELP_MESSAGE) + await reply_error(message.channel, 'Invalid number of arguments.') + await reply(message.channel, HELP_MESSAGE) return False return True @@ -129,7 +127,7 @@ async def on_message(message): if not isinstance(message.channel, discord.DMChannel) or message.author == bot.user: return - is_valid_command = check_command(message) + is_valid_command = await check_command(message) if not is_valid_command: return From bd6f01989015774f509d8c1673369f3d1c98b5b8 Mon Sep 17 00:00:00 2001 From: Lukas Nedbalek Date: Sat, 28 Sep 2024 11:40:28 +0200 Subject: [PATCH 15/15] fix: grant_role ukco converter exception --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 87db849..b93a549 100644 --- a/main.py +++ b/main.py @@ -49,7 +49,7 @@ async def on_ready(): @bot.command() -async def grant_role(ctx, study_group_name: str, ukco: int): +async def grant_role(ctx, study_group_name: str, ukco: str): """ Grant a role to the user based on the study group and UKCO. :param ctx: The context of the command. @@ -63,7 +63,7 @@ async def grant_role(ctx, study_group_name: str, ukco: int): return # Check UKCO format - if not (1000_0000 < ukco < 9999_9999): + if not ukco.isdigit() or not len(ukco) == 8: await reply_error(ctx, 'Invalid UKCO format.') await reply(ctx, HELP_MESSAGE) return