From 33b2b71a2c5e2f774749f2b118a33b067c645500 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Thu, 17 Nov 2022 00:44:52 +0100 Subject: [PATCH 01/30] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b9038ed..2953111 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ docker-compose up -d To see the bot logs when running with docker in detached mode (`-d`), use the [docker logs for the container](https://docs.docker.com/engine/reference/commandline/logs/). ## 💠 Bot usage +> TODO add `/server info` and `/user *` with other parameters to docs ### ULB servers From 46f709e12885b5d8bb38b3d7a3d6f41841b31ee6 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Sat, 26 Nov 2022 16:37:25 +0100 Subject: [PATCH 02/30] add memory limit to the container --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 782d599..801d484 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,3 +12,5 @@ services: volumes: - ./:/usr/src/ulbdiscordbot restart: always # or unless-stopped + mem_limit: 1g # memory limit for the container + # cpus: 0.5 # cpu limit for the container From d27108659aebeac3e3fed7d2576c8058b733ae25 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 13:14:21 +0100 Subject: [PATCH 03/30] add missing information about admin command --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b9038ed..903c15f 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,10 @@ Edit info of a user. Delete a user. +* `/server info` + +Get information about a guild (ULB role, number of registered members, ...) + * `/update` This forces a total update of the database and of all the servers. Since the bot already does this automatically at startup and after each reconnection, the only normal usecase for this would be if you manually add an entry (server or user) to the google sheet instead of using the `/user add` command above, we don't recommend manually editing the google sheet. From 3acc68b87dba4b9d42f4237b077402c0e3306ef3 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 13:15:45 +0100 Subject: [PATCH 04/30] change disnake version from 2.6 to 2.7 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cc8bb6d..743d71e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ cfgv==3.3.1 cfscrape==2.1.1 charset-normalizer==2.1.1 classify-imports==4.2.0 -disnake==2.6.0 +disnake==2.7.0 distlib==0.3.6 filelock==3.8.0 frozenlist==1.3.0 From 6c08c4b7f7b4b4600db2d9059a176dc5fec46a00 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 13:23:00 +0100 Subject: [PATCH 05/30] removed frozenlist since it had compiler issu with python 3.11 --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 743d71e..04cec82 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,6 @@ classify-imports==4.2.0 disnake==2.7.0 distlib==0.3.6 filelock==3.8.0 -frozenlist==1.3.0 google-auth==2.11.1 google-auth-oauthlib==0.5.3 gspread==5.5.0 From 80e1829e05d6e2055d0425a3549834af418376ca Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 13:26:25 +0100 Subject: [PATCH 06/30] added the feedback command information --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 903c15f..62fd378 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,10 @@ To see the bot logs when running with docker in detached mode (`-d`), use the [d Once the ULB role is set, when a new user joins the server, either they are already registered (from another of your servers) in which case they will get the `@ULB` role and get renamed, or they are not registered yet and will receive a DM message with the instructions to register themselves using the `/ulb` command. +* `/feedback` + +Send a feedback directly from discord. + ### Admin server * `/user add` From 2f6254794efd5a0869e92b2d74cfaf4f6580eea6 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 13:27:39 +0100 Subject: [PATCH 07/30] Revert "add missing information about admin command" This reverts commit d27108659aebeac3e3fed7d2576c8058b733ae25. --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 62fd378..2e41dc0 100644 --- a/README.md +++ b/README.md @@ -228,10 +228,6 @@ Edit info of a user. Delete a user. -* `/server info` - -Get information about a guild (ULB role, number of registered members, ...) - * `/update` This forces a total update of the database and of all the servers. Since the bot already does this automatically at startup and after each reconnection, the only normal usecase for this would be if you manually add an entry (server or user) to the google sheet instead of using the `/user add` command above, we don't recommend manually editing the google sheet. From f835bface09e03a4fc4a048c50d12a208e19f45f Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 13:27:46 +0100 Subject: [PATCH 08/30] Revert "added the feedback command information" This reverts commit 80e1829e05d6e2055d0425a3549834af418376ca. --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 2e41dc0..b9038ed 100644 --- a/README.md +++ b/README.md @@ -206,10 +206,6 @@ To see the bot logs when running with docker in detached mode (`-d`), use the [d Once the ULB role is set, when a new user joins the server, either they are already registered (from another of your servers) in which case they will get the `@ULB` role and get renamed, or they are not registered yet and will receive a DM message with the instructions to register themselves using the `/ulb` command. -* `/feedback` - -Send a feedback directly from discord. - ### Admin server * `/user add` From c4ebc10616fa52189816d9e0b5f24a038de268c0 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 13:28:52 +0100 Subject: [PATCH 09/30] added missing information about discord commands --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2953111..62fd378 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,6 @@ docker-compose up -d To see the bot logs when running with docker in detached mode (`-d`), use the [docker logs for the container](https://docs.docker.com/engine/reference/commandline/logs/). ## 💠 Bot usage -> TODO add `/server info` and `/user *` with other parameters to docs ### ULB servers @@ -207,6 +206,10 @@ To see the bot logs when running with docker in detached mode (`-d`), use the [d Once the ULB role is set, when a new user joins the server, either they are already registered (from another of your servers) in which case they will get the `@ULB` role and get renamed, or they are not registered yet and will receive a DM message with the instructions to register themselves using the `/ulb` command. +* `/feedback` + +Send a feedback directly from discord. + ### Admin server * `/user add` @@ -225,6 +228,10 @@ Edit info of a user. Delete a user. +* `/server info` + +Get information about a guild (ULB role, number of registered members, ...) + * `/update` This forces a total update of the database and of all the servers. Since the bot already does this automatically at startup and after each reconnection, the only normal usecase for this would be if you manually add an entry (server or user) to the google sheet instead of using the `/user add` command above, we don't recommend manually editing the google sheet. From 1767f248808fbdebd0ae9cd074ad52de4dc01cae Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 14:02:05 +0100 Subject: [PATCH 10/30] added member count and percent --- cogs/Ulb.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cogs/Ulb.py b/cogs/Ulb.py index a1a6b53..05a9e1c 100644 --- a/cogs/Ulb.py +++ b/cogs/Ulb.py @@ -162,9 +162,12 @@ async def info(self, inter: disnake.ApplicationCommandInteraction): ) return + n_registered = len(guilddata.role.members) + percent = int(n_registered / inter.guild.member_count * 100) + embed = disnake.Embed( title="Info du serveur", - description=f"ULB role : {guilddata.role.mention}\nRenommer les membres : **{'oui' if guilddata.rename else 'non'}**", + description=f"ULB role : {guilddata.role.mention}\nNombre de membre vérifié : **{n_registered}** *({percent}%)*\nRenommer les membres : **{'oui' if guilddata.rename else 'non'}**", color=disnake.Color.green(), ) From 5de4cc30425161e0b464f09869a9e45cd90895cd Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 14:02:33 +0100 Subject: [PATCH 11/30] added member count to server info and /stats command --- cogs/Admin.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cogs/Admin.py b/cogs/Admin.py index b6564b7..10990fc 100644 --- a/cogs/Admin.py +++ b/cogs/Admin.py @@ -401,12 +401,32 @@ async def server_info( number_registered_user = len( [1 for _, member in enumerate(guild.members) if member in Database.ulb_users.keys()] ) + + n_registered = len(Database.ulb_guilds.get(guild).role.members) + percent = int(n_registered / guild.member_count * 100) + guild_data = Database.ulb_guilds.get(guild) await inter.edit_original_response( embed=disnake.Embed( title="Info du server", - description=f"**Nom :** {guild.name}\n**ID :** `{guild.id}`\n**Role :** @{guild_data.role.name}\n**Role ID :** `{guild_data.role.id}`\n**Rename :** `{'Oui' if guild_data.rename else 'Non'}`\n**Nombre de membre vérifié :** `{number_registered_user}`", - color=disnake.Color.green(), + description=f"**Nom :** {guild.name}\n**ID :** `{guild.id}`\n**Role :** @{guild_data.role.name}\n**Role ID :** `{guild_data.role.id}`\n**Rename :** `{'Oui' if guild_data.rename else 'Non'}`\n**Nombre de membre vérifié :** `{n_registered} ({percent}%)`", + color=disnake.Color.blue(), + ) + ) + + @commands.slash_command( + name="stats", + default_member_permissions=disnake.Permissions.all(), + description="Voir les statistiques d'utilisation du bot.", + ) + async def stats(self, inter: disnake.ApplicationCommandInteraction): + await inter.response.defer(ephemeral=True) + + await inter.edit_original_response( + embed=disnake.Embed( + title="Statistique du bot", + description=f"**Servers configurés : **`{len(Database.ulb_guilds)}`\n**Membres vérifiés : **`{len(Database.ulb_users)}`", + color=disnake.Colour.blue(), ) ) From 3c7ae176b05dbebf1c259015a2bab0bf195ec714 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Thu, 16 Feb 2023 14:02:54 +0100 Subject: [PATCH 12/30] added /stats admin command info --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 62fd378..03c40cd 100644 --- a/README.md +++ b/README.md @@ -232,6 +232,10 @@ Delete a user. Get information about a guild (ULB role, number of registered members, ...) +* `/stats` + +Get statistics about the bot usage (nombre of configured servers, number of registered users, ...) + * `/update` This forces a total update of the database and of all the servers. Since the bot already does this automatically at startup and after each reconnection, the only normal usecase for this would be if you manually add an entry (server or user) to the google sheet instead of using the `/user add` command above, we don't recommend manually editing the google sheet. From a02321439f56953d9caa1b04d209c34f152d4084 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Fri, 17 Feb 2023 12:26:10 +0100 Subject: [PATCH 13/30] change disnake to 2.8 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 04cec82..a54c01a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ cfgv==3.3.1 cfscrape==2.1.1 charset-normalizer==2.1.1 classify-imports==4.2.0 -disnake==2.7.0 +disnake==2.8.* distlib==0.3.6 filelock==3.8.0 google-auth==2.11.1 From a03683db26457359a2bdac3a3c07fa32a370dc72 Mon Sep 17 00:00:00 2001 From: oscarvsp Date: Tue, 5 Dec 2023 12:25:15 +0100 Subject: [PATCH 14/30] change black type to python3 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 72a22a0..b7cee0d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: hooks: - id: black language: python - types: [python] + types: [python3] args: ["--line-length=120"] - repo: https://github.com/PyCQA/autoflake From 14e34132c6706a9356b176e7e2537e2fe7f58967 Mon Sep 17 00:00:00 2001 From: oscarvsp Date: Tue, 5 Dec 2023 12:26:17 +0100 Subject: [PATCH 15/30] added way to send error log message without cmd context --- bot/bot.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/bot/bot.py b/bot/bot.py index a308b33..0bd8bb0 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -96,11 +96,24 @@ def load_commands(self) -> None: ) self.cog_not_loaded.append(extension) - async def send_error_log(self, interaction: ApplicationCommandInteraction, error: Exception): + async def send_error_log(self, tb: str): + + n = len(tb) // 4050 + + #Logs need to be diveded into multiple embed due to size limitation + # TODO Check if we can use a list of embeds and one message + # TODO Make it dynamic base on the message size from the lib (check library version, maybe need to upgrade) + for i in range(n): + await self.log_channel.send(embed=disnake.Embed(description=f"```python\n{tb[4050*i:4050*(i+1)]}```")) + await self.log_channel.send(embed=disnake.Embed(description=f"```python\n{tb[4050*n:]}```")) + + async def send_cmd_error_log(self, interaction: ApplicationCommandInteraction, error: Exception): tb = self.tracebackEx(error) logging.error( f"{error} raised on command /{interaction.application_command.name} from {interaction.guild.name+'#'+interaction.channel.name if interaction.guild else 'DM'} by {interaction.author.name}.\n{tb}" ) + + #Send error msg to the user await interaction.send( content=self.owner.mention, embed=disnake.Embed( @@ -110,6 +123,8 @@ async def send_error_log(self, interaction: ApplicationCommandInteraction, error ), delete_after=10, ) + + #Send logs to admins await self.log_channel.send( embed=disnake.Embed(title=f":x: __** ERROR**__ :x:", description=f"```{error}```").add_field( name=f"Raised on command :", @@ -117,10 +132,7 @@ async def send_error_log(self, interaction: ApplicationCommandInteraction, error + (f" and target\n``'{interaction.target}``'." if interaction.target else "."), ) ) - n = len(tb) // 4050 - for i in range(n): - await self.log_channel.send(embed=disnake.Embed(description=f"```python\n{tb[4050*i:4050*(i+1)]}```")) - await self.log_channel.send(embed=disnake.Embed(description=f"```python\n{tb[4050*n:]}```")) + await self.send_error_log(tb) async def on_slash_command(self, interaction: disnake.ApplicationCommandInteraction) -> None: logging.trace( @@ -138,13 +150,13 @@ async def on_message_command(self, interaction: disnake.MessageCommandInteractio ) async def on_slash_command_error(self, interaction: ApplicationCommandInteraction, error: Exception) -> None: - await self.send_error_log(interaction, error) + await self.send_cmd_error_log(interaction, error) async def on_user_command_error(self, interaction: disnake.UserCommandInteraction, error: Exception) -> None: - await self.send_error_log(interaction, error) + await self.send_cmd_error_log(interaction, error) async def on_message_command_error(self, interaction: disnake.MessageCommandInteraction, error: Exception) -> None: - await self.send_error_log(interaction, error) + await self.send_cmd_error_log(interaction, error) async def on_slash_command_completion(self, interaction: disnake.ApplicationCommandInteraction) -> None: logging.trace( From a9928597e3671bbe880e8b929bb212d7da90dac7 Mon Sep 17 00:00:00 2001 From: oscarvsp Date: Tue, 5 Dec 2023 12:27:27 +0100 Subject: [PATCH 16/30] added check and error msg for database loading --- classes/database.py | 56 ++++++++++++++++++++++++--------------------- cogs/Admin.py | 35 +++++++--------------------- cogs/Ulb.py | 14 +++++------- 3 files changed, 44 insertions(+), 61 deletions(-) diff --git a/classes/database.py b/classes/database.py index 61d0c39..9313d65 100644 --- a/classes/database.py +++ b/classes/database.py @@ -94,7 +94,7 @@ def loaded(cls) -> bool: return cls._loaded @classmethod - def load(cls, bot: Bot) -> None: + async def load(cls, bot: Bot) -> bool: """Load the data from the google sheet. Returns @@ -104,31 +104,35 @@ def load(cls, bot: Bot) -> None: - Guild: `Dict[disnake.Guild, disnake.Role]` - Users: `Dict[disnake.User, UlbUser]]` """ - # First time this is call, we need to load the credentials and the sheet - if not cls._sheet: - cred_dict = {} - cred_dict["type"] = os.getenv("GS_TYPE") - cred_dict["project_id"] = os.getenv("GS_PROJECT_ID") - cred_dict["auth_uri"] = os.getenv("GS_AUTHOR_URI") - cred_dict["token_uri"] = os.getenv("GS_TOKEN_URI") - cred_dict["auth_provider_x509_cert_url"] = os.getenv("GS_AUTH_PROV") - cred_dict["client_x509_cert_url"] = os.getenv("GS_CLIENT_CERT_URL") - cred_dict["private_key"] = os.getenv("GS_PRIVATE_KEY").replace( - "\\n", "\n" - ) # Python add a '\' before any '\n' when loading a str - cred_dict["private_key_id"] = os.getenv("GS_PRIVATE_KEY_ID") - cred_dict["client_email"] = os.getenv("GS_CLIENT_EMAIL") - cred_dict["client_id"] = int(os.getenv("GS_CLIENT_ID")) - creds = ServiceAccountCredentials.from_json_keyfile_dict(cred_dict, cls._scope) - cls._client = gspread.authorize(creds) - logging.info("[Database] Google sheet credentials loaded.") - - # Open google sheet - cls._sheet = cls._client.open_by_url(os.getenv("GOOGLE_SHEET_URL")) - cls._users_ws = cls._sheet.worksheet("users") - cls._guilds_ws = cls._sheet.worksheet("guilds") - - logging.info("[Database] Spreadsheed loaded") + try: + # First time this is call, we need to load the credentials and the sheet + if not cls._sheet: + cred_dict = {} + cred_dict["type"] = os.getenv("GS_TYPE") + cred_dict["project_id"] = os.getenv("GS_PROJECT_ID") + cred_dict["auth_uri"] = os.getenv("GS_AUTHOR_URI") + cred_dict["token_uri"] = os.getenv("GS_TOKEN_URI") + cred_dict["auth_provider_x509_cert_url"] = os.getenv("GS_AUTH_PROV") + cred_dict["client_x509_cert_url"] = os.getenv("GS_CLIENT_CERT_URL") + cred_dict["private_key"] = os.getenv("GS_PRIVATE_KEY").replace( + "\\n", "\n" + ) # Python add a '\' before any '\n' when loading a str + cred_dict["private_key_id"] = os.getenv("GS_PRIVATE_KEY_ID") + cred_dict["client_email"] = os.getenv("GS_CLIENT_EMAIL") + cred_dict["client_id"] = int(os.getenv("GS_CLIENT_ID")) + creds = ServiceAccountCredentials.from_json_keyfile_dict(cred_dict, cls._scope) + cls._client = gspread.authorize(creds) + logging.info("[Database] Google sheet credentials loaded.") + + # Open google sheet + cls._sheet = cls._client.open_by_url(os.getenv("GOOGLE_SHEET_URL")) + cls._users_ws = cls._sheet.worksheet("users") + cls._guilds_ws = cls._sheet.worksheet("guilds") + + logging.info("[Database] Spreadsheed loaded") + except (ValueError, gspread.exceptions.SpreadsheetNotFound, gspread.exceptions.WorksheetNotFound) as err: + await bot.send_error_log(bot.tracebackEx(err)) + return logging.info("[Database] Loading data...") diff --git a/cogs/Admin.py b/cogs/Admin.py index 10990fc..3ca1882 100644 --- a/cogs/Admin.py +++ b/cogs/Admin.py @@ -28,11 +28,12 @@ def __init__(self, bot: Bot): ) async def update(self, inter: disnake.ApplicationCommandInteraction): await inter.response.defer(ephemeral=True) - Database.load(self.bot) - await utils.update_all_guilds() - await inter.edit_original_response( - embed=disnake.Embed(description="All servers updated !", color=disnake.Color.green()) - ) + await Database.load(self.bot) + if (Database.loaded): + await utils.update_all_guilds() + await inter.edit_original_response( + embed=disnake.Embed(description="All servers updated !", color=disnake.Color.green()) + ) @commands.slash_command( name="yearly-update", @@ -401,32 +402,12 @@ async def server_info( number_registered_user = len( [1 for _, member in enumerate(guild.members) if member in Database.ulb_users.keys()] ) - - n_registered = len(Database.ulb_guilds.get(guild).role.members) - percent = int(n_registered / guild.member_count * 100) - guild_data = Database.ulb_guilds.get(guild) await inter.edit_original_response( embed=disnake.Embed( title="Info du server", - description=f"**Nom :** {guild.name}\n**ID :** `{guild.id}`\n**Role :** @{guild_data.role.name}\n**Role ID :** `{guild_data.role.id}`\n**Rename :** `{'Oui' if guild_data.rename else 'Non'}`\n**Nombre de membre vérifié :** `{n_registered} ({percent}%)`", - color=disnake.Color.blue(), - ) - ) - - @commands.slash_command( - name="stats", - default_member_permissions=disnake.Permissions.all(), - description="Voir les statistiques d'utilisation du bot.", - ) - async def stats(self, inter: disnake.ApplicationCommandInteraction): - await inter.response.defer(ephemeral=True) - - await inter.edit_original_response( - embed=disnake.Embed( - title="Statistique du bot", - description=f"**Servers configurés : **`{len(Database.ulb_guilds)}`\n**Membres vérifiés : **`{len(Database.ulb_users)}`", - color=disnake.Colour.blue(), + description=f"**Nom :** {guild.name}\n**ID :** `{guild.id}`\n**Role :** @{guild_data.role.name}\n**Role ID :** `{guild_data.role.id}`\n**Rename :** `{'Oui' if guild_data.rename else 'Non'}`\n**Nombre de membre vérifié :** `{number_registered_user}`", + color=disnake.Color.green(), ) ) diff --git a/cogs/Ulb.py b/cogs/Ulb.py index 05a9e1c..7e42f46 100644 --- a/cogs/Ulb.py +++ b/cogs/Ulb.py @@ -19,10 +19,11 @@ def __init__(self, bot: Bot): @commands.Cog.listener("on_ready") async def on_ready(self): - Database.load(self.bot) - Registration.setup(self) - logging.info("[Cog:Ulb] Ready !") - await utils.update_all_guilds() + await Database.load(self.bot) + if (Database.loaded): + Registration.setup(self) + logging.info("[Cog:Ulb] Ready !") + await utils.update_all_guilds() async def wait_setup(self, inter: disnake.ApplicationCommandInteraction) -> None: """Async sleep until GoogleSheet is loaded and RegistrationForm is set""" @@ -162,12 +163,9 @@ async def info(self, inter: disnake.ApplicationCommandInteraction): ) return - n_registered = len(guilddata.role.members) - percent = int(n_registered / inter.guild.member_count * 100) - embed = disnake.Embed( title="Info du serveur", - description=f"ULB role : {guilddata.role.mention}\nNombre de membre vérifié : **{n_registered}** *({percent}%)*\nRenommer les membres : **{'oui' if guilddata.rename else 'non'}**", + description=f"ULB role : {guilddata.role.mention}\nRenommer les membres : **{'oui' if guilddata.rename else 'non'}**", color=disnake.Color.green(), ) From 68f26799ea4ee39b63dc66832aadd37e9100c663 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:29:51 +0000 Subject: [PATCH 17/30] Bump aiohttp from 3.8.3 to 3.9.0 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.3 to 3.9.0. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.3...v3.9.0) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8daee22..feadc55 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.8.3 +aiohttp==3.9.0 aiosignal==1.2.0 async-timeout==4.0.2 asyncpg==0.26.0 From e0cf852cb09c90752fc832c387102f37de1feb99 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:31:35 +0100 Subject: [PATCH 18/30] update python image to 3.11.6-alpine- Update Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a14845d..2496153 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ #FROM python:3 -FROM python:3.8.6-alpine +FROM python:3.11.6-alpine # use python:3.11.0rc2-slim for less vulnerabilities ? (from `docker scan`) # use python:3.8.6 for no pip dependencies build errors ? # use python:alpine for reduced size From 230cb857cdb33f6b6908a9a9a1bdb75b591382e8 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:55:08 +0100 Subject: [PATCH 19/30] bump asyncpg, frozenlist, multidict, yarl to latest- Update requirements.txt --- requirements.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8daee22..ae40001 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ aiohttp==3.8.3 aiosignal==1.2.0 async-timeout==4.0.2 -asyncpg==0.26.0 +#asyncpg==0.26.0 +asyncpg==0.29.0 attrs==22.1.0 autopep8==1.7.0 cachetools==5.2.0 @@ -13,7 +14,8 @@ classify-imports==4.2.0 disnake==2.6.0 distlib==0.3.6 filelock==3.8.0 -frozenlist==1.3.0 +#frozenlist==1.3.1 +frozenlist==1.4.0 google-auth==2.11.1 google-auth-oauthlib==0.5.3 gspread==5.5.0 @@ -21,7 +23,8 @@ httplib2==0.20.4 identify==2.5.5 idna==3.4 lor-deckcodes==5.0.0 -multidict==6.0.2 +#multidict==6.0.2 +multidict==6.0.4 mypy==0.971 mypy-extensions==0.4.3 nodeenv==1.7.0 @@ -48,4 +51,5 @@ tomli==2.0.1 typing_extensions==4.3.0 urllib3==1.26.12 virtualenv==20.16.3 -yarl==1.8.1 +#yarl==1.8.1 +yarl==1.9.3 From 985a96350b5bb10ae81bf1d6f94f71c02b2a1226 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:58:36 +0100 Subject: [PATCH 20/30] bump async-timeout to latest - Update requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ae40001..548180d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ aiohttp==3.8.3 aiosignal==1.2.0 -async-timeout==4.0.2 +#async-timeout==4.0.2 +async-timeout==4.0.3 #asyncpg==0.26.0 asyncpg==0.29.0 attrs==22.1.0 From 1f5eed93feede0dd93e8c58b512ff17a207d91cb Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:32:10 +0100 Subject: [PATCH 21/30] fix: filter names to remove unwanted characters only keep ASCII letters and spaces --- classes/registration.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/classes/registration.py b/classes/registration.py index a39ed85..fd72732 100644 --- a/classes/registration.py +++ b/classes/registration.py @@ -9,6 +9,7 @@ from typing import Dict from typing import List from typing import Tuple +from string import ascii_letters import disnake from disnake.ext import commands @@ -519,7 +520,10 @@ async def _register_user_step(self, inter: disnake.ModalInteraction) -> None: The modal interaction that triggered the step """ # Extract name and store the user - name = " ".join([name.title() for name in self.email.split("@")[0].split(".")]) + allowed_chars = set(ascii_letters + " ") # or set('abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ') + unfiltered_name = " ".join([name.title() for name in self.email.split("@")[0].split(".")]) + name = "".join(filter(allowed_chars.__contains__, unfiltered_name)) # remove all characters that aren't ASCII letters or a space + logging.trace(f"[RegistrationForm] [User:{self.target.id}] Extracted name from email= {name}") Database.set_user(self.target, name, self.email) await self._stop() From b70170533f1bd86f6f4f11c98ab6ef0b1f58ffd6 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:02:59 +0100 Subject: [PATCH 22/30] rename user choice during update_all_guilds during an update_all_guilds command, only updates the user's name if both the guild has rename enabled AND the admin set force rename to true at the command --- classes/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/utils.py b/classes/utils.py index 517554b..d2c03f0 100644 --- a/classes/utils.py +++ b/classes/utils.py @@ -141,7 +141,7 @@ async def update_guild(guild: disnake.Guild, *, role: disnake.Role = None, renam await update_member(member, role=role, rename=rename) -async def update_all_guilds() -> None: +async def update_all_guilds(force_rename: bool = False) -> None: """Update all guilds. This create tasks to do it. @@ -149,7 +149,7 @@ async def update_all_guilds() -> None: logging.info("[Utils] Checking all guilds...") await asyncio.gather( *[ - update_guild(guild, role=guild_data.role, rename=guild_data.rename) + update_guild(guild, role=guild_data.role, rename=force_rename if guild_data.rename else guild_data.rename) # force rename users only if both the guild has rename enabled and the admin set the update to force rename true for guild, guild_data in Database.ulb_guilds.items() ] ) From 89bcf1b093193931c6683154ac967c46c2efabfd Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:08:09 +0100 Subject: [PATCH 23/30] add option for admin to choose to force rename during `/update` to all servers --- cogs/Admin.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cogs/Admin.py b/cogs/Admin.py index b6564b7..3a4f7e2 100644 --- a/cogs/Admin.py +++ b/cogs/Admin.py @@ -26,12 +26,21 @@ def __init__(self, bot: Bot): default_member_permissions=disnake.Permissions.all(), dm_permission=False, ) - async def update(self, inter: disnake.ApplicationCommandInteraction): + async def update( + self, + inter: disnake.ApplicationCommandInteraction, + rename: str = commands.Param( + description="Forcer un rename à tous les utilisateur.rice.s avec l'update ? (Seulment dans les serveurs ayant le rename d'activé)", + default="Non", + choices=["Non", "Oui"], + ), + ): + force_rename = rename == "Oui" # Convert from str to bool await inter.response.defer(ephemeral=True) Database.load(self.bot) - await utils.update_all_guilds() + await utils.update_all_guilds(force_rename) await inter.edit_original_response( - embed=disnake.Embed(description="All servers updated !", color=disnake.Color.green()) + embed=disnake.Embed(description=f"All servers updated !{" Members renamed." if force_rename else ""}", color=disnake.Color.green()) ) @commands.slash_command( From fa88dd7d254f92e147fb686070728fbc6b560b56 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:08:40 +0200 Subject: [PATCH 24/30] resolve merge conflict into bepolytech/dev --- cogs/Admin.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cogs/Admin.py b/cogs/Admin.py index 3a4f7e2..6b6bc90 100644 --- a/cogs/Admin.py +++ b/cogs/Admin.py @@ -37,11 +37,12 @@ async def update( ): force_rename = rename == "Oui" # Convert from str to bool await inter.response.defer(ephemeral=True) - Database.load(self.bot) - await utils.update_all_guilds(force_rename) - await inter.edit_original_response( - embed=disnake.Embed(description=f"All servers updated !{" Members renamed." if force_rename else ""}", color=disnake.Color.green()) - ) + await Database.load(self.bot) + if (Database.loaded): + await utils.update_all_guilds(force_rename) + await inter.edit_original_response( + embed=disnake.Embed(description=f"All servers updated !{" Members renamed." if force_rename else ""}", color=disnake.Color.green()) + ) @commands.slash_command( name="yearly-update", From 3481cc105c0e25671279575db2d5eb7bfce07eaf Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:22:52 +0200 Subject: [PATCH 25/30] fix typos --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 03c40cd..8140c31 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,7 @@ Once the ULB role is set, when a new user joins the server, either they are alre * `/feedback` -Send a feedback directly from discord. +Send feedback directly from discord. ### Admin server @@ -234,7 +234,7 @@ Get information about a guild (ULB role, number of registered members, ...) * `/stats` -Get statistics about the bot usage (nombre of configured servers, number of registered users, ...) +Get statistics about the bot usage (number of configured servers, number of registered users, ...) * `/update` From 5a60293e3092bcc06d2edec1b3d2f93f13bd0e7c Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:24:20 +0200 Subject: [PATCH 26/30] fix typo --- cogs/Admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/Admin.py b/cogs/Admin.py index 6b6bc90..d44cae2 100644 --- a/cogs/Admin.py +++ b/cogs/Admin.py @@ -30,7 +30,7 @@ async def update( self, inter: disnake.ApplicationCommandInteraction, rename: str = commands.Param( - description="Forcer un rename à tous les utilisateur.rice.s avec l'update ? (Seulment dans les serveurs ayant le rename d'activé)", + description="Forcer un rename à tous les utilisateur.rice.s avec l'update ? (Seulement dans les serveurs ayant le rename d'activé)", default="Non", choices=["Non", "Oui"], ), From 97cb6b9a744391d6c16149a7a4446af1b9e0bc21 Mon Sep 17 00:00:00 2001 From: ticccco <23436953+LucasPlacentino@users.noreply.github.com> Date: Wed, 17 Apr 2024 10:25:55 +0200 Subject: [PATCH 27/30] Update README.md add info to `/update` command docs (force rename or not) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8140c31..913d85a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This is a small discord bot written in python using the [disnake library](https://github.com/DisnakeDev/disnake) to make a registration system for ULB discord servers. -The bot checks that a user is a ULB student by verifying their ULB email adress using a one-time generated token sent to their email adress. It then gives them the role and adds their Discord user ID and ULB email adress to a database. The user will is then automatically verified on every server that the bot is running. The bot also has a rename functionality (optional, per server), names are extracted from the email adress. +**_[Version 1]_**: The bot checks that a user is a ULB student by verifying their ULB email adress using a one-time generated token sent to their email adress. It then gives them the role and adds their Discord user ID and ULB email adress to a database. The user will is then automatically verified on every server that the bot is running. The bot also has a rename functionality (optional, per server), names are extracted from the email adress. # ➕ Add the bot to your server @@ -196,11 +196,11 @@ To see the bot logs when running with docker in detached mode (`-d`), use the [d * `/setup` -(Admin permission needed) When adding the bot to a new server, you need to set the @ULB role with the command `/setup`. This command also allows you to choose if you want to force the registered member to get renamed with their real name or not (yes by default). +**[Admin permission needed]** When adding the bot to a new server, you need to set the @ULB role with the command `/setup`. This command also allows you to choose if you want to force the registered member to get renamed with their real name or not (yes by default). * `/info` -(Admin permission needed) Get current server information (@ULB role, if rename is enabled, and checks for permission conflicts). +**[Admin permission needed]** Get current server information (@ULB role, if rename is enabled, and checks for permission conflicts). * `/ulb` @@ -238,7 +238,7 @@ Get statistics about the bot usage (number of configured servers, number of regi * `/update` -This forces a total update of the database and of all the servers. Since the bot already does this automatically at startup and after each reconnection, the only normal usecase for this would be if you manually add an entry (server or user) to the google sheet instead of using the `/user add` command above, we don't recommend manually editing the google sheet. +This forces a total update of the database and of all the servers. Since the bot already does this automatically at startup and after each reconnection, the only normal usecase for this would be if you manually add an entry (server or user) to the google sheet instead of using the `/user add` command above, we don't recommend manually editing the google sheet. It also includes an option (`/update Non`) to not rename users (on servers where it is enabled) when running this command (default: do **not** force rename on force update). ## 👤 Author From 70f7a275a17ee91ff84c7c80edcdb75615068dc2 Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Fri, 26 Apr 2024 09:22:01 +0200 Subject: [PATCH 28/30] Better auto complete match by lowering the text --- cogs/Admin.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cogs/Admin.py b/cogs/Admin.py index d44cae2..4a725af 100644 --- a/cogs/Admin.py +++ b/cogs/Admin.py @@ -41,7 +41,7 @@ async def update( if (Database.loaded): await utils.update_all_guilds(force_rename) await inter.edit_original_response( - embed=disnake.Embed(description=f"All servers updated !{" Members renamed." if force_rename else ""}", color=disnake.Color.green()) + embed=disnake.Embed(description=f"All servers updated !{' Members renamed.' if force_rename else ''}", color=disnake.Color.green()) ) @commands.slash_command( @@ -431,7 +431,7 @@ async def user_id_autocomplete(self, inter: disnake.ApplicationCommandInteractio @user_delete.autocomplete("name") async def name_autocomplete(self, inter: disnake.ApplicationCommandInteraction, user_input: str): return [ - str(userdata.name) for userdata in Database.ulb_users.values() if str(userdata.name).startswith(user_input) + str(userdata.name) for userdata in Database.ulb_users.values() if str(userdata.name.lower()).startswith(user_input.lower()) ] @user_set.autocomplete("username") @@ -439,7 +439,7 @@ async def user_set_autocomplete(self, inter: disnake.ApplicationCommandInteracti return [ f"{user.name}#{user.discriminator}" for user in self.bot.users - if str(user.name).startswith(user_input) and user not in Database.ulb_users.keys() + if str(user.name.lower()).startswith(user_input.lower()) and user not in Database.ulb_users.keys() ] @user_edit.autocomplete("username") @@ -449,7 +449,7 @@ async def username_autocomplete(self, inter: disnake.ApplicationCommandInteracti return [ f"{user.name}#{user.discriminator}" for user in Database.ulb_users.keys() - if str(user.name).startswith(user_input) + if str(user.name.lower()).startswith(user_input.lower()) ] @user_edit.autocomplete("email") @@ -458,7 +458,7 @@ async def email_autocomplete(self, inter: disnake.ApplicationCommandInteraction, return [ str(userdata.email) for userdata in Database.ulb_users.values() - if str(userdata.email).startswith(user_input) and userdata.email != "N/A" + if str(userdata.email.lower()).startswith(user_input.lower()) and userdata.email != "N/A" ] @server_info.autocomplete("id") @@ -470,7 +470,7 @@ async def email_autocomplete(self, inter: disnake.ApplicationCommandInteraction, return [ f"{server.name}#{server.id}" for server in Database.ulb_guilds.keys() - if str(server.name).startswith(user_input) + if str(server.name.lower()).startswith(user_input.lower()) ] From 08af6f3897583113ca0c785d5dc6c97b11f79dfc Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Fri, 26 Apr 2024 09:39:03 +0200 Subject: [PATCH 29/30] Better exception handler and logs --- classes/utils.py | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/classes/utils.py b/classes/utils.py index d2c03f0..509d3c5 100644 --- a/classes/utils.py +++ b/classes/utils.py @@ -79,6 +79,17 @@ async def update_member(member: disnake.Member, *, name: str = None, role: disna if rename == None: rename = Database.ulb_guilds.get(member.guild).rename + if role not in member.roles: + try: + await member.add_roles(role) + logging.info(f"[Utils:update_member] [User:{member.id}] [Guild:{member.guild.id}] Add role={role.id}") + except HTTPException as ex: + logging.error( + f'[Utils:update_member] [User:{member.id}] [Guild:{member.guild.id}] Not able to add ulb role "{role.name}:{role.id}" to ulb user "{member.name}:{member.id}": {ex}' + ) + else: + logging.trace(f"[Utils:update_member] [User:{member.id}] [Guild:{member.guild.id}] role={role.id} already set") + if rename: if name == None: name = Database.ulb_users.get(member).name @@ -90,14 +101,11 @@ async def update_member(member: disnake.Member, *, name: str = None, role: disna logging.warning( f'[Utils:update_user] [User:{member.id}] [Guild:{member.guild.id}] Not able to edit user "{member.name}:{member.id}" nick to "{name}": {ex}' ) - if role not in member.roles: - try: - await member.add_roles(role) - logging.info(f"[Utils:update_user] [User:{member.id}] [Guild:{member.guild.id}] Set role={role.id}") - except HTTPException as ex: - logging.error( - f'[Utils:update_user] [User:{member.id}] [Guild:{member.guild.id}] Not able to add ulb role "{role.name}:{role.id}" to ulb user "{member.name}:{member.id}": {ex}' - ) + else: + logging.trace(f"[Utils:update_user] [User:{member.id}] [Guild:{member.guild.id}] name={name} already set") + else: + logging.trace(f"[Utils:update_member] [User:{member.id}] [Guild:{member.guild.id}] Skip renaming") + async def update_user(user: disnake.User, *, name: str = None): @@ -110,13 +118,19 @@ async def update_user(user: disnake.User, *, name: str = None): name : `Optional[str]` The name to use instead of fetching the database. """ + logging.trace(f"[Utils:update_user] [User:{user.id}] Start") if name == None: name = Database.ulb_users.get(user).name for guild, guild_data in Database.ulb_guilds.items(): member = guild.get_member(user.id) if member: - await update_member(member, name=name, role=guild_data.role, rename=guild_data.rename) - + try: + await update_member(member, name=name, role=guild_data.role, rename=guild_data.rename) + except RoleNotInGuildError: + logging.warning( + f"[Utils:update_user] [User:{user.id}] [Guild:{guild.id}] The role registered ulb role @{guild_data.role.name} is not found" + ) + logging.trace(f"[Utils:update_user] [User:{user.id}] End") async def update_guild(guild: disnake.Guild, *, role: disnake.Role = None, rename: bool = None) -> None: """Update a given guilds. @@ -132,13 +146,21 @@ async def update_guild(guild: disnake.Guild, *, role: disnake.Role = None, renam rename : `Optional[bool]` Does the guild force rename or not """ + loggind.trace(f"[Utils:update_guild] [Guild:{guild.id}] Start") if role == None: role = Database.ulb_guilds.get(guild).role if rename == None: rename = Database.ulb_guilds.get(guild).rename for member in guild.members: if member in Database.ulb_users.keys(): - await update_member(member, role=role, rename=rename) + try: + await update_member(member, role=role, rename=rename) + except RoleNotInGuildError: + logging.warning( + f"[Utils:update_guild] [Guild:{guild.id}] The role registered ulb role @{role.name} is not found" + ) + break + loggind.trace(f"[Utils:update_guild] [Guild:{guild.id}] End") async def update_all_guilds(force_rename: bool = False) -> None: From 4e52af6caff6b35847a27cfaaf96e4d32691220f Mon Sep 17 00:00:00 2001 From: OscarVsp Date: Fri, 26 Apr 2024 09:46:03 +0200 Subject: [PATCH 30/30] better logs --- classes/database.py | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/classes/database.py b/classes/database.py index 9313d65..b423807 100644 --- a/classes/database.py +++ b/classes/database.py @@ -129,12 +129,12 @@ async def load(cls, bot: Bot) -> bool: cls._users_ws = cls._sheet.worksheet("users") cls._guilds_ws = cls._sheet.worksheet("guilds") - logging.info("[Database] Spreadsheed loaded") + logging.info("[Database:load] Spreadsheed loaded") except (ValueError, gspread.exceptions.SpreadsheetNotFound, gspread.exceptions.WorksheetNotFound) as err: await bot.send_error_log(bot.tracebackEx(err)) return - logging.info("[Database] Loading data...") + logging.info("[Database:load] Loading data...") # Load guilds cls.ulb_guilds = {} @@ -146,28 +146,30 @@ async def load(cls, bot: Bot) -> bool: if role: cls.ulb_guilds.setdefault(guild, UlbGuild(role, rename)) logging.trace( - f"[Database] Role {role.name}:{role.id} loaded from guild {guild.name}:{guild.id} with {rename=}" + f"[Database:load] Role {role.name}:{role.id} loaded from guild {guild.name}:{guild.id} with {rename=}" ) else: logging.warning( - f"[Database] Not able to find role from id={guild_data.get('role_id', int)} in guild {guild.name}:{guild.id}." + f"[Database:load] Not able to find role from id={guild_data.get('role_id', int)} in guild {guild.name}:{guild.id}." ) else: - logging.warning(f"[GoogleSheet] Not able to find guild from id={guild_data.get('guild_id', int)}.") - logging.info(f"[Database] Found {len(cls.ulb_guilds)} guilds.") + logging.warning(f"[Database:load] Not able to find guild from id={guild_data.get('guild_id', int)}.") + logging.info(f"[Database:load] Found {len(cls.ulb_guilds)} guilds.") # Load users cls.ulb_users = {} + not_found_counter = 0 for user_data in cls._users_ws.get_all_records(): user = bot.get_user(user_data.get("user_id", int)) if user: cls.ulb_users.setdefault(user, UlbUser(user_data.get("name", str), user_data.get("email", str))) logging.trace( - f"[Database] User {user.name}:{user.id} loaded with name={user_data.get('name')} and email={user_data.get('email')}" + f"[Database:load] User {user.name}:{user.id} loaded with name={user_data.get('name')} and email={user_data.get('email')}" ) else: + not_found_counter += 1 logging.warning(f"[Database] Not able to find user from id={user_data.get('user_id',int)}.") - logging.info(f"[Database] Found {len(cls.ulb_users)} users.") + logging.info(f"[Database:load] {len(cls.ulb_users)} users found, {not_found_counter} not found.") cls._loaded = True @@ -187,15 +189,15 @@ async def _set_user_task(cls, user_id: int, name: str, email: str): user_cell: gspread.cell.Cell = cls._users_ws.find(str(user_id), in_column=1) await asyncio.sleep(0.1) if user_cell: - logging.debug(f"[Database] {user_id=} found") + logging.trace(f"[Database:_set_user_task] {user_id=} found") cls._users_ws.update_cell(user_cell.row, 2, name) await asyncio.sleep(0.1) cls._users_ws.update_cell(user_cell.row, 3, email) - logging.info(f"[Database] {user_id=} updated with {name=} and {email=}") + logging.info(f"[Database:_set_user_task] {user_id=} updated with {name=} and {email=}") else: - logging.debug(f"[Database] {user_id=} not found") + logging.trace(f"[Database:_set_user_task] {user_id=} not found") cls._users_ws.append_row(values=[str(user_id), name, email]) - logging.info(f"[Database] {user_id=} added with {name=} and {email=}") + logging.info(f"[Database:_set_user_task] {user_id=} added with {name=} and {email=}") @classmethod def set_user(cls, user: disnake.User, name: str, email: str): @@ -228,10 +230,10 @@ async def _delete_user_task(cls, user_id: int): """ user_cell: gspread.cell.Cell = cls._users_ws.find(str(user_id), in_column=1) await asyncio.sleep(0.1) - logging.trace(f"[Database] {user_id=} found") + logging.trace(f"[Database:_delete_user_task] {user_id=} found") cls._users_ws.delete_row(user_cell.row) await asyncio.sleep(0.1) - logging.info(f"[Database] {user_id=} deleted.") + logging.info(f"[Database:_delete_user_task] {user_id=} deleted.") @classmethod def delete_user(cls, user: disnake.User): @@ -265,14 +267,14 @@ async def _set_guild_task(cls, guild_id: int, role_id: int, rename: bool): guild_cell: gspread.cell.Cell = cls._guilds_ws.find(str(guild_id), in_column=1) await asyncio.sleep(0.1) if guild_cell: - logging.debug(f"[Database] {guild_id=} found.") + logging.trace(f"[Database:_set_guild_task] {guild_id=} found.") cls._guilds_ws.update_cell(guild_cell.row, 2, str(role_id)) cls._guilds_ws.update_cell(guild_cell.row, 3, rename) - logging.info(f"[Database] {guild_id=} update with {role_id=} and {rename=}.") + logging.info(f"[Database:_set_guild_task] {guild_id=} update with {role_id=} and {rename=}.") else: - logging.debug(f"[Database] {guild_id=} not found.") + logging.trace(f"[Database:_set_guild_task] {guild_id=} not found.") cls._guilds_ws.append_row(values=[str(guild_id), str(role_id), rename]) - logging.info(f"[Database] {guild_id=} added with {role_id=} and {rename=}.") + logging.info(f"[Database:_set_guild_task] {guild_id=} added with {role_id=} and {rename=}.") @classmethod def set_guild(cls, guild: disnake.Guild, role: disnake.Role, rename: bool): @@ -303,10 +305,10 @@ async def _delete_guild_task(cls, guild_id: int): """ guild_cell: gspread.cell.Cell = cls._guilds_ws.find(str(guild_id), in_column=1) await asyncio.sleep(0.1) - logging.trace(f"[Database] {guild_id=} found") + logging.trace(f"[Database:_delete_guild_task] {guild_id=} found") cls._guilds_ws.delete_row(guild_cell.row) await asyncio.sleep(0.1) - logging.info(f"[Database] {guild_id=} deleted.") + logging.info(f"[Database:_delete_guild_task] {guild_id=} deleted.") @classmethod def delete_guild(cls, guild: disnake.Guild):