From 83d39d0002fd198a9c8a0cfc0342c67fd901332d Mon Sep 17 00:00:00 2001 From: imcompiling Date: Sat, 7 Sep 2024 15:00:16 -0400 Subject: [PATCH 1/5] Add an approval process for event submissions. --- DakinySettings.py | 1 + cogs/commands/record.py | 113 +++++++++++++++++++++++++++++++-------- cogs/commands/request.py | 2 +- pyproject.toml | 1 + 4 files changed, 95 insertions(+), 22 deletions(-) diff --git a/DakinySettings.py b/DakinySettings.py index c726ffa..aee5abc 100644 --- a/DakinySettings.py +++ b/DakinySettings.py @@ -40,6 +40,7 @@ class EventSettings: host_points: int participate_points: int + verify: bool weekly_limit: int diff --git a/cogs/commands/record.py b/cogs/commands/record.py index eb7b877..0f79066 100644 --- a/cogs/commands/record.py +++ b/cogs/commands/record.py @@ -1,5 +1,7 @@ """Contained commands and views for record commands.""" +from typing import List + import nextcord from discord import TextInputStyle from nextcord.ext import commands @@ -180,33 +182,74 @@ class EventView(nextcord.ui.View): Removes view and embed from recording message. Sends point information to database. """ - discord_users = self.event_participants.values.members # noqa: PD011 not a pandas object - if discord_users: - discord_users_list: list[str] = [str(user.id) for user in discord_users if user.id is not self.host_id] - record_event_points( - discord_users_list, - settings.event_settings.participate_points, - is_member=True, + if settings.event_settings.verify: + verification_channel: nextcord.TextChannel = interaction.guild.get_channel(settings.channel_ids.admin) + verification_view = EventVerification( + self.event_participants.values.members, interaction.message.embeds[0].fields[1].value, self.host_id + ) + await verification_channel.send( + content="Event record request.", embed=interaction.message.embeds[1], view=verification_view + ) + submission_response = "Event has been submitted to admins for approval." + else: + self.process_event( + self.event_participants.values.members, + interaction.message.embeds[0].fields[1].value, + self.host_id, ) - non_discord_users = interaction.message.embeds[0].fields[1].value - if non_discord_users: - non_discord_users_list: list[str] = non_discord_users.split("\n") - record_event_points( - non_discord_users_list, - settings.event_settings.participate_points, - is_member=False, - ) - - record_event_points([self.host_id], settings.event_settings.host_points, is_member=True) - - event_channel: nextcord.TextChannel = interaction.guild.get_channel(settings.channel_ids.event_post) - await event_channel.send(embed=interaction.message.embeds[0]) - await interaction.response.edit_message(content="Event has been submitted.", view=None, embed=None) + event_channel: nextcord.TextChannel = interaction.guild.get_channel(settings.channel_ids.event_post) + await event_channel.send(embed=interaction.message.embeds[0]) + submission_response = "Event has been submitted." + await interaction.response.edit_message(content=submission_response, view=None, embed=None) self.stop() +class EventVerification(nextcord.ui.View): + """Class contains code to approve/deny event submissions.""" + + def __init__( + self, + discord_users: list[nextcord.Member], + non_discord_users: str, + host_id: int, + ): + super().__init__(timeout=None, auto_defer=True) + self.discord_users: list[nextcord.Member] = discord_users + self.non_discord_users: str = non_discord_users + self.host_id: int = host_id + + @nextcord.ui.button(label="Approve", style=nextcord.ButtonStyle.green) + async def approve(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None: # noqa: ARG002 + """ + Approve button for an event submission. + + Calls the process event function. Records who approved the event. + Removes the view from the interaction message. + + Args: + button (nextcord.ui.Button): Unused. + interaction (nextcord.Interaction): The interaction of the user clicking the button. + """ + process_event(self.discord_users, self.non_discord_users, self.host_id) + + content = f"\nApproved by <@{interaction.user.id}>." + await interaction.response.edit_message(content=content, view=None) + + @nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red) + async def deny(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None: # noqa: ARG002 + """ + Deny button for an event submission. Just removes the view and logs who denied the request. + + Args: + button (nextcord.ui.Button): Unused. + interaction (nextcord.Interaction): The interaction of the user clicking the button. + """ + content = f"\nDenied by <@{interaction.user.id}>." + await interaction.response.edit_message(content=content, view=None) + + class ParticipantModal(nextcord.ui.Modal): """ This modal contains all the text edits for an event. @@ -281,3 +324,31 @@ class ParticipantSelect(nextcord.ui.UserSelect): participants: str = "\n".join([f"<@{participant.id}>" for participant in self.values.members]) embed.set_field_at(0, name="Participants", value=participants) await interaction.response.edit_message(embed=embed) + + +def process_event(discord_users: list[nextcord.Member], non_discord_users: str, host_id: int) -> None: + """ + Processes all points to give to participants and host for an event. + + Args: + discord_users (list[nextcord.Member]): List of discord members that participated in event. + non_discord_users (str): Newline separated list of non discord members that participated in event. + host_id (int): Discord ID of host. + """ + if discord_users: + discord_users_list: list[str] = [str(user.id) for user in discord_users if user.id is not host_id] + record_event_points( + discord_users_list, + settings.event_settings.participate_points, + is_member=True, + ) + + if non_discord_users: + non_discord_users_list: list[str] = non_discord_users.split("\n") + record_event_points( + non_discord_users_list, + settings.event_settings.participate_points, + is_member=False, + ) + + record_event_points([host_id], settings.event_settings.host_points, is_member=True) diff --git a/cogs/commands/request.py b/cogs/commands/request.py index aa5ebf1..9004c8c 100644 --- a/cogs/commands/request.py +++ b/cogs/commands/request.py @@ -109,7 +109,7 @@ class UsernameRequest(nextcord.ui.View): await interaction.followup.edit_message(interaction.message.id, content=content, view=None) else: await interaction.response.edit_message( - content="An error occured while changing the user's nickname.", + content="An error occurred while changing the user's nickname.", view=None, ) diff --git a/pyproject.toml b/pyproject.toml index 4e74b55..94b1c0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,7 @@ ignore = [ "E117", "ISC001", "ISC002", + "PD011", # doesn't like me using '.values' on embeds.... "Q000", "Q001", "Q002", From 79706fbe348e1654fa6b7651df23d56575cc0b88 Mon Sep 17 00:00:00 2001 From: imcompiling Date: Sat, 7 Sep 2024 15:05:34 -0400 Subject: [PATCH 2/5] Fix bad array index. Send event to event channel when approved. --- cogs/commands/record.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cogs/commands/record.py b/cogs/commands/record.py index 0f79066..50c58a2 100644 --- a/cogs/commands/record.py +++ b/cogs/commands/record.py @@ -188,7 +188,7 @@ class EventView(nextcord.ui.View): self.event_participants.values.members, interaction.message.embeds[0].fields[1].value, self.host_id ) await verification_channel.send( - content="Event record request.", embed=interaction.message.embeds[1], view=verification_view + content="Event record request.", embed=interaction.message.embeds[0], view=verification_view ) submission_response = "Event has been submitted to admins for approval." else: @@ -233,6 +233,8 @@ class EventVerification(nextcord.ui.View): interaction (nextcord.Interaction): The interaction of the user clicking the button. """ process_event(self.discord_users, self.non_discord_users, self.host_id) + event_channel: nextcord.TextChannel = interaction.guild.get_channel(settings.channel_ids.event_post) + await event_channel.send(embed=interaction.message.embeds[0]) content = f"\nApproved by <@{interaction.user.id}>." await interaction.response.edit_message(content=content, view=None) From 38ef2f4cb8f674c8dbfb68c03b7dec1b725f36bc Mon Sep 17 00:00:00 2001 From: imcompiling Date: Sat, 7 Sep 2024 15:07:59 -0400 Subject: [PATCH 3/5] process_event isn't part of the class anymore. --- cogs/commands/record.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/commands/record.py b/cogs/commands/record.py index 50c58a2..23480e2 100644 --- a/cogs/commands/record.py +++ b/cogs/commands/record.py @@ -192,7 +192,7 @@ class EventView(nextcord.ui.View): ) submission_response = "Event has been submitted to admins for approval." else: - self.process_event( + process_event( self.event_participants.values.members, interaction.message.embeds[0].fields[1].value, self.host_id, From 87b21782ce533535f378674aee83bc1c0ae14f98 Mon Sep 17 00:00:00 2001 From: imcompiling Date: Sat, 7 Sep 2024 15:08:53 -0400 Subject: [PATCH 4/5] Remove unneeded import. --- cogs/commands/record.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cogs/commands/record.py b/cogs/commands/record.py index 23480e2..487d9f0 100644 --- a/cogs/commands/record.py +++ b/cogs/commands/record.py @@ -1,7 +1,5 @@ """Contained commands and views for record commands.""" -from typing import List - import nextcord from discord import TextInputStyle from nextcord.ext import commands From 512802def76386cf2844ab15adadc4f4d63d8c3d Mon Sep 17 00:00:00 2001 From: imcompiling Date: Sat, 7 Sep 2024 15:14:50 -0400 Subject: [PATCH 5/5] Add ability to configure event verification. --- cogs/commands/settings.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/cogs/commands/settings.py b/cogs/commands/settings.py index 3880bb5..73aafe3 100644 --- a/cogs/commands/settings.py +++ b/cogs/commands/settings.py @@ -160,7 +160,7 @@ class SettingsCog(commands.Cog, name="Settings Commands"): Args: interaction (nextcord.Interaction): Discord interaction of command. - points (nextcord.TextChannel): Number of points to set. + points (int): Number of points to set. """ settings.event_settings.host_points = points settings.save() @@ -181,12 +181,32 @@ class SettingsCog(commands.Cog, name="Settings Commands"): Args: interaction (nextcord.Interaction): Discord interaction of command. - points (nextcord.TextChannel): Number of points to set. + points (int): Number of points to set. """ settings.event_settings.participate_points = points settings.save() await interaction.response.send_message(f"Event Participation Points set to {points}.", ephemeral=True) + @event_settings.subcommand(description="Sets Event Participation Points value.") + async def verify( + self, + interaction: nextcord.Interaction, + do_verification: bool = nextcord.SlashOption( # noqa: FBT001 + required=True, + description="Whether an event should be verified or not.", + ), + ) -> None: + """ + Sets DakinySettings event_settings.verify to the given number of points. + + Args: + interaction (nextcord.Interaction): Discord interaction of command. + do_verification (bool): If the bot should verify events. + """ + settings.event_settings.verify = do_verification + settings.save() + await interaction.response.send_message(f"Event verification set to {do_verification}.", ephemeral=True) + @event_settings.subcommand(description="Sets Event Weekly Limit value.") async def weekly_limit( self, @@ -200,7 +220,7 @@ class SettingsCog(commands.Cog, name="Settings Commands"): Args: interaction (nextcord.Interaction): Discord interaction of command. - points (nextcord.TextChannel): Number of points to set. + points (int): Number of points to set. """ settings.event_settings.weekly_limit = points settings.save()