From cb43dc33246b6526a959131547235e725fb8f9fe Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 01:56:05 -0600 Subject: [PATCH 01/16] fix: fixed double [] when using forcesync on allies --- src/func/Union.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/func/Union.py b/src/func/Union.py index 786791c..4a3861f 100644 --- a/src/func/Union.py +++ b/src/func/Union.py @@ -126,7 +126,7 @@ async def sync(self, ctx, name: str, tag: str = None, is_fs=False): # User is an ally elif guild_name in allies: if not can_tag: - new_nick += f" [{await get_gtag(guild_name)}]" + new_nick += f" {await get_gtag(guild_name)}" roles_to_remove.extend([bot.new_member_role, bot.member_role]) roles_to_add.extend([bot.guest, bot.ally]) From bbdac5d4faee46d658c545b5a079d7a9c955088d Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 01:56:57 -0600 Subject: [PATCH 02/16] fix: fixed ValueError in register --- src/func/Union.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/func/Union.py b/src/func/Union.py index 4a3861f..104c35b 100644 --- a/src/func/Union.py +++ b/src/func/Union.py @@ -5,9 +5,8 @@ from typing import Union import discord -import src.utils.ui_utils as uiutils - +import src.utils.ui_utils as uiutils from src.utils.consts import (active_req, allies, discord_not_linked_embed, guild_handle, neg_color, neutral_color, pos_color, registration_channel_id, staff_impersonation_embed, ticket_categories, @@ -185,7 +184,8 @@ async def register(self, ctx, name): discord.InputTextStyle.short, "Invited by:"] ] - await ctx.response.send_modal(modal=uiutils.ModalCreator(embed=embed, fields=fields, ign=ign, uuid=uuid, title="Player Reference", + await ctx.response.send_modal( + modal=uiutils.ModalCreator(embed=embed, fields=fields, ign=ign, uuid=uuid, title="Player Reference", function=validate_reference)) await ctx.author.add_roles(bot.member_role, reason="Registration - Member") guest_ticket = None @@ -212,6 +212,7 @@ async def register(self, ctx, name): category=discord.utils.get(ctx.guild.categories, name=ticket_categories["registrees"])) guest_ticket = ticket + class Join_Misc_Buttons(discord.ui.Button): def __init__(self, button: list): """ @@ -232,8 +233,6 @@ async def callback(self, interaction: discord.Interaction): f"{interaction.user.mention} kindly leave your current guild so that" f" we can can invite you to Miscellaneous.") - - elif interaction.custom_id == "No": await ticket.purge(limit=100) await interaction.user.remove_roles(bot.processing, reason="Registration - Guest") @@ -264,7 +263,7 @@ async def callback(self, interaction: discord.Interaction): await ctx.author.remove_roles(bot.new_member_role, reason="Register") await ctx.author.edit(nick=ign) - return embed, guest_ticket if guild_name != guild_handle else None, None + return (embed, guest_ticket) if guild_name != guild_handle else (None, None) async def add(self, ctx): if ctx.channel.category.name not in ticket_categories.values(): From 0bf6c526bad0b9284fe7ca957b49b29c282bf6a7 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 01:57:15 -0600 Subject: [PATCH 03/16] fix: rolecheck updates ally guild tags correctly --- src/func/General.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/func/General.py b/src/func/General.py index fcd52c1..37cb28c 100644 --- a/src/func/General.py +++ b/src/func/General.py @@ -150,7 +150,7 @@ async def sem_task(task): last_value = guild_division[0] # Set nick - if not discord_member.nick or gtag not in discord_member.nick: + if not discord_member.nick or f" [{gtag}]" not in discord_member.nick: await discord_member.edit(nick=username + f' [{gtag}]') # Edit roles From c83f6d8980989c29d2faedac4518392d57758094 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:02:16 -0600 Subject: [PATCH 04/16] feat: created a new function that handles the closing of dnkl tickets --- src/utils/discord_utils.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index d98983a..8e7da76 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -1,3 +1,4 @@ +import asyncio from __main__ import bot from datetime import datetime, timedelta from io import BytesIO @@ -11,9 +12,12 @@ from src.utils.consts import (config, dnkl_req, gvg_requirements, log_channel_id, neg_color, neutral_color, staff_application_questions, ticket_categories, - unknown_ign_embed, guild_handle, positive_responses, dnkl_creation_embed, member_req) + unknown_ign_embed, guild_handle, positive_responses, dnkl_creation_embed, dnkl_channel_id, + missing_permissions_embed) +from src.utils.db_utils import select_one, insert_new_dnkl, update_dnkl, delete_dnkl from src.utils.minecraft_utils import get_player_gexp -from src.utils.request_utils import get_hypixel_player, get_mojang_profile, get_player_guild, get_guild_level, get_guild_by_name +from src.utils.request_utils import get_hypixel_player, get_mojang_profile, get_player_guild, get_guild_level + async def name_grabber(author: discord.Member) -> str: if not author.nick: @@ -39,11 +43,27 @@ async def is_linked_discord(player_data: dict, user: discord.User) -> bool: return (discord == str(user)[:-2]) or (discord == (str(user.id) + "#0000") or (discord == str(user))) - async def get_ticket_creator(channel: discord.TextChannel): return bot.guild.get_member(int(channel.topic.split("|")[0])) +async def close_ticket(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, + embed: discord.Embed, interaction: discord.Interaction): + if author != interaction.user: + await channel.send(embed=missing_permissions_embed) + return None + + embed = discord.Embed(title="This ticket will be deleted in 20 seconds!", color=neg_color) + + # Send deletion warning and gather transcript + await interaction.response.send_message(embed=embed) + transcript = await chat_exporter.export(channel, limit=None) + if transcript: + transcript = discord.File(BytesIO(transcript.encode()), + filename=f"transcript-{channel.name}.html") + await bot.get_channel(log_channel_id).send( + f"DNKL Request was denied and channel was deleted by {author}") + await bot.get_channel(log_channel_id).send(file=transcript) async def create_ticket(user: discord.Member, ticket_name: str, category_name: str = ticket_categories["generic"]): # Create ticket ticket: discord.TextChannel = await bot.guild.create_text_channel(ticket_name, @@ -119,7 +139,8 @@ async def callback(self, interaction: discord.Interaction): ] embed = discord.Embed(title="Player Report", color=neutral_color) await interaction.response.send_modal( - modal=uiutils.ModalCreator(embed=embed, fields=fields, ign=ign, uuid=uuid, title="Player Report")) + modal=uiutils.ModalCreator(embed=embed, fields=fields, ign=ign, uuid=uuid, + title="Player Report")) if option == "Query/Problem": await ticket.edit(name=f"general-{ign}", topic=f"{interaction.user.id}|", From a8c8f460f4694c5af1a832a53b99087705f43ed9 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:02:51 -0600 Subject: [PATCH 05/16] feat: created a new function that handles the errors in dnkl tickets --- src/utils/discord_utils.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index 8e7da76..c2c8ecb 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -64,6 +64,22 @@ async def close_ticket(channel: discord.TextChannel, author: discord.User, ign: await bot.get_channel(log_channel_id).send( f"DNKL Request was denied and channel was deleted by {author}") await bot.get_channel(log_channel_id).send(file=transcript) + + # Sleep and delete channel + await asyncio.sleep(20) + await discord.TextChannel.delete(channel) + + +async def dnkl_error(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, + interaction: discord.Interaction): + if bot.staff not in interaction.user.roles: + await channel.send(embed=missing_permissions_embed) + return None + + await interaction.response.send_message(embed=discord.Embed( + title="Your application has been accepted, however there was an error!", + description="Please await staff assistance!", + color=neutral_color)) async def create_ticket(user: discord.Member, ticket_name: str, category_name: str = ticket_categories["generic"]): # Create ticket ticket: discord.TextChannel = await bot.guild.create_text_channel(ticket_name, From e9117b6dfdfdcc64cef52228fa3c5258136cd011 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:03:56 -0600 Subject: [PATCH 06/16] feat: created a new function that handles the denial of dnkl tickets --- src/utils/discord_utils.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index c2c8ecb..a426b42 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -80,6 +80,33 @@ async def dnkl_error(channel: discord.TextChannel, author: discord.User, ign: st title="Your application has been accepted, however there was an error!", description="Please await staff assistance!", color=neutral_color)) + + +async def dnkl_deny(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, + interaction: discord.Interaction, self_denial: bool = False): + if bot.staff not in interaction.user.roles and not self_denial: + await channel.send(embed=missing_permissions_embed) + return None + + if not self_denial: + await interaction.response.send_message("**This user's do-not-kick-list application has been denied!.**\n" + "If you didn't mean to hit deny, you can add them using `/dnkl_add`.", + ephemeral=True) + + embed = discord.Embed(title="Your do-not-kick-list application has been denied!", + description=f"You do not meet the DNKL requirements of {format(dnkl_req, ',d')} weekly guild experience.", + color=neg_color) + embed.set_footer( + text="If don't you think you can meet the requirements, you may rejoin the guild once your inactivity period has ended.") + + closeView = discord.ui.View(timeout=None) # View for staff members to approve/deny the DNKL + button = ("Close This Ticket", "close_ticket", discord.enums.ButtonStyle.red) + closeView.add_item( + uiutils.Button_Creator(channel=channel, author=author, ign=ign, uuid=uuid, button=button, + function=close_ticket)) + await channel.send(embed=embed, view=closeView) + await delete_dnkl(ign) + async def create_ticket(user: discord.Member, ticket_name: str, category_name: str = ticket_categories["generic"]): # Create ticket ticket: discord.TextChannel = await bot.guild.create_text_channel(ticket_name, @@ -474,7 +501,6 @@ async def get_ticket_properties(channel: discord.TextChannel): return topic.split('|') - @tasks.loop(count=1) async def after_cache_ready(): # Set owner id(s) and guild @@ -503,7 +529,6 @@ async def after_cache_ready(): from src.utils.discord_utils import name_grabber bot.staff_names = [(await get_mojang_profile(await name_grabber(member)))[0] for member in bot.staff.members] - from src.utils.loop_utils import check_giveaways, send_gexp_lb, update_invites check_giveaways.start() send_gexp_lb.start() From c45dc669f7a0048083ee44ce374291f7b4beca30 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:04:07 -0600 Subject: [PATCH 07/16] feat: created a new function that handles the approval of dnkl tickets --- src/utils/discord_utils.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index a426b42..9e2ec64 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -107,6 +107,37 @@ async def dnkl_deny(channel: discord.TextChannel, author: discord.User, ign: str await channel.send(embed=embed, view=closeView) await delete_dnkl(ign) + +async def dnkl_approve(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, + interaction: discord.Interaction): + if bot.staff not in interaction.user.roles: + await channel.send(embed=missing_permissions_embed) + return None + + msg = await bot.get_channel(dnkl_channel_id).send(embed=embed) + + # Check if user is already on DNKL + current_message = await select_one("SELECT message_id FROM dnkl WHERE uuid = (?)", + (uuid,)) + # User is not currently on DNKL + if not current_message: + await insert_new_dnkl(msg.id, uuid, ign) + return await interaction.response.send_message("**This user has been added to the do-not-kick-list!**") + + # User is already on DNKl + # Try to delete current message + try: + current_message = await bot.get_channel(dnkl_channel_id).fetch_message( + current_message) + await current_message.delete() + except Exception: + pass + + await update_dnkl(msg.id, uuid) + await interaction.response.send_message( + "**Since this user was already on the do-not-kick-list, their entry has been updated.**") + + async def create_ticket(user: discord.Member, ticket_name: str, category_name: str = ticket_categories["generic"]): # Create ticket ticket: discord.TextChannel = await bot.guild.create_text_channel(ticket_name, From 459ae57f33a598c27eef06df7e996b3f7786a3e5 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:04:42 -0600 Subject: [PATCH 08/16] feat: updated button callback functions by including them with the button's initialization --- src/utils/discord_utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index 9e2ec64..841c809 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -519,7 +519,11 @@ async def create_transcript(channel: discord.TextChannel, limit: int = None): async def dnkl_application(ign: str, uuid: str, channel: discord.TextChannel, author: discord.User, weekly_gexp: int): YearView = discord.ui.View() - YearView.add_item(uiutils.StartYearSelect(channel=channel, ign=ign, uuid=uuid, weekly_gexp=weekly_gexp)) # Year Selection Dropdown + buttons = (("Approve", "DNKL_Approve", discord.enums.ButtonStyle.green, dnkl_approve), + ("Deny", "DNKL_Deny", discord.enums.ButtonStyle.red, dnkl_deny), + ("Error", "DNKL_Error", discord.enums.ButtonStyle.gray, dnkl_error)) + YearView.add_item(uiutils.StartYearSelect(channel=channel, ign=ign, uuid=uuid, + weekly_gexp=weekly_gexp, buttons=buttons)) # Year Selection Dropdown embed = discord.Embed(title=f"In which year will {ign}'s inactivity begin?", color=neutral_color) await channel.send(embed=embed, view=YearView) From 6e82aae73319eb58f721014227436f3201fd0765 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:06:02 -0600 Subject: [PATCH 09/16] feat: added support for button callback functions --- src/utils/ui_utils.py | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/utils/ui_utils.py b/src/utils/ui_utils.py index 72a91bc..6e627a1 100644 --- a/src/utils/ui_utils.py +++ b/src/utils/ui_utils.py @@ -1,26 +1,22 @@ -import asyncio +import calendar from __main__ import bot from datetime import datetime, timedelta -from io import BytesIO -import calendar -import chat_exporter import discord import discord.ui as ui -from src.utils.consts import (dnkl_channel_id, dnkl_req, - missing_permissions_embed, - neg_color, neutral_color, log_channel_id) -from src.utils.db_utils import insert_new_dnkl, select_one, update_dnkl, delete_dnkl +from src.utils.consts import (neg_color, neutral_color) class StartYearSelect(ui.Select): - def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, weekly_gexp: int): + def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, weekly_gexp: int, buttons: tuple): super().__init__(placeholder="Year") self.channel = channel self.ign = ign self.uuid = uuid self.weekly_gexp = weekly_gexp + self.buttons = buttons + self.add_option(label=str(datetime.now().year)) if datetime.now().month == 11: self.add_option(label=str(datetime.now().year + 1)) @@ -32,7 +28,8 @@ async def callback(self, interaction: discord.Interaction): start_year = list(interaction.data.values())[0][0] MonthView = discord.ui.View() MonthView.add_item(StartMonthSelect(channel=self.channel, ign=self.ign, uuid=self.uuid, - year=start_year, weekly_gexp=self.weekly_gexp)) # Month Selection Dropdown + year=start_year, weekly_gexp=self.weekly_gexp, + buttons=self.buttons)) # Month Selection Dropdown embed = discord.Embed(title=f"In which month of {start_year} will {self.ign}'s inactivity begin?", color=neutral_color).set_footer(text=f"Start Date - ?/?/{start_year}") await interaction.response.send_message(embed=embed, view=MonthView) @@ -40,13 +37,14 @@ async def callback(self, interaction: discord.Interaction): class StartMonthSelect(ui.Select, object): - def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, year: int, weekly_gexp: int): + def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, year: int, weekly_gexp: int, buttons: tuple): super().__init__(placeholder="Month") self.channel = channel self.year = year self.ign = ign self.uuid = uuid self.weekly_gexp = weekly_gexp + self.buttons = buttons for x in range(datetime.now().month, datetime.now().month + 2): if x > 12: @@ -57,10 +55,12 @@ def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, year: int, async def callback(self, interaction: discord.Interaction): # Set option var and delete Select so it cannot be used twice start_month = list(interaction.data.values())[0][0] - DayView = discord.ui.View() + DayView = discord.ui.View() DayView.add_item(StartDaySelect(channel=self.channel, ign=self.ign, uuid=self.uuid, month=start_month, - year=self.year, weekly_gexp=self.weekly_gexp)) # Day Selection Dropdown + year=self.year, weekly_gexp=self.weekly_gexp, + buttons=self.buttons)) # Day Selection Dropdown + embed = discord.Embed(title=f"What is the closest day to the start of {self.ign}'s inactivity?", color=neutral_color).set_footer(text=f"Start Date - ?/{start_month}/{self.year}") await interaction.response.send_message(embed=embed, view=DayView) @@ -68,7 +68,8 @@ async def callback(self, interaction: discord.Interaction): class StartDaySelect(ui.Select): - def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, month: str, year: int, weekly_gexp: int): + def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, month: str, year: int, weekly_gexp: int, + buttons: tuple): super().__init__(placeholder="Day") self.channel = channel self.ign = ign @@ -76,6 +77,7 @@ def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, month: str self.month = month self.year = year self.weekly_gexp = weekly_gexp + self.buttons = buttons monthNumber = datetime.strptime(self.month, "%B").month if datetime.now().month == monthNumber: @@ -97,7 +99,8 @@ async def callback(self, interaction: discord.Interaction): LengthView = discord.ui.View() LengthView.add_item( InactivityLenSelect(author=interaction.user, channel=self.channel, ign=self.ign, uuid=self.uuid, - day=start_day, month=self.month, year=self.year, weekly_gexp=self.weekly_gexp)) + day=start_day, month=self.month, year=self.year, weekly_gexp=self.weekly_gexp, + buttons=self.buttons)) embed = discord.Embed(title=f"How long will {self.ign} be inactive?", color=neutral_color).set_footer( text=f"Start Date - {start_day}/{self.month}/{self.year}") @@ -107,7 +110,7 @@ async def callback(self, interaction: discord.Interaction): class InactivityLenSelect(ui.Select): def __init__(self, author: discord.User, channel: discord.TextChannel, ign: str, uuid: str, day: int, month: str, - year: int, weekly_gexp: int): + year: int, weekly_gexp: int, buttons: tuple): super().__init__(placeholder="Length") self.author = author self.channel = channel @@ -117,6 +120,8 @@ def __init__(self, author: discord.User, channel: discord.TextChannel, ign: str, self.year = year self.day = day self.weekly_gexp = weekly_gexp + self.buttons = buttons + self.deny = buttons[1][3] self.add_option(label=f"1 Week", value=str(1)) for x in range(2, 4): @@ -142,7 +147,8 @@ async def callback(self, interaction: discord.Interaction): month=self.month, year=self.year, length=length, - weekly_gexp=self.weekly_gexp)) + weekly_gexp=self.weekly_gexp, + buttons=self.buttons)) embed = discord.Embed(title=f"What is the reason behind {self.ign}'s inactivity?", color=neutral_color) @@ -154,7 +160,7 @@ async def callback(self, interaction: discord.Interaction): class InactivityReasonSelect(ui.Select): def __init__(self, author: discord.User, channel: discord.TextChannel, ign: str, uuid: str, day: int, month: str, - year: int, length: int, weekly_gexp: int): + year: int, length: int, weekly_gexp: int, buttons: tuple): super().__init__(placeholder="Reason") self.author = author self.channel = channel @@ -165,6 +171,7 @@ def __init__(self, author: discord.User, channel: discord.TextChannel, ign: str, self.day = day self.length = length self.weekly_gexp = weekly_gexp + self.buttons = buttons reasons = ["Exams", "Medical Issues", "Vacation", "Computer Problems", "Other"] for reason in reasons: From 47dcad19fc348bd213a091a23e062676a0be2c46 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:06:59 -0600 Subject: [PATCH 10/16] refactor: Improved the readability and optimized code --- src/utils/ui_utils.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/utils/ui_utils.py b/src/utils/ui_utils.py index 6e627a1..b6127a3 100644 --- a/src/utils/ui_utils.py +++ b/src/utils/ui_utils.py @@ -79,19 +79,14 @@ def __init__(self, channel: discord.TextChannel, ign: str, uuid: str, month: str self.weekly_gexp = weekly_gexp self.buttons = buttons - monthNumber = datetime.strptime(self.month, "%B").month - if datetime.now().month == monthNumber: - step = 2 - if datetime.now().day - (calendar.monthrange(int(self.year), monthNumber)[ - 1] + 1) < 20: # Adding a check to change step value if the number of days is less - step = 1 - for x in range(datetime.now().day, calendar.monthrange(int(self.year), monthNumber)[1] + 1, - step): # A range from current day to last day of month; step 2 - self.add_option(label=str(x)) - else: - for x in range(1, calendar.monthrange(int(self.year), monthNumber)[1] + 1, - 2): # A range from 1 to last day of month; step 2 - self.add_option(label=str(x)) + month_number = datetime.strptime(self.month, "%B").month + start_date = datetime.now().day if datetime.now().month == month_number else 1 + end_date = calendar.monthrange(int(self.year), month_number)[1] + 1 + number_of_days = end_date - start_date + step = 1 if number_of_days < 26 else 2 + + for day in range(start_date, end_date, step): + self.add_option(label=str(day)) # Override default callback async def callback(self, interaction: discord.Interaction): From 4dee60e0323d077139dca37ac704c4138c3c824d Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:07:32 -0600 Subject: [PATCH 11/16] feat: added self close functionality to >3 weeks dnkl --- src/utils/ui_utils.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/utils/ui_utils.py b/src/utils/ui_utils.py index b6127a3..ef10db9 100644 --- a/src/utils/ui_utils.py +++ b/src/utils/ui_utils.py @@ -126,11 +126,17 @@ def __init__(self, author: discord.User, channel: discord.TextChannel, ign: str, async def callback(self, interaction: discord.Interaction): length = list(interaction.data.values())[0][0] if length == "?": - embed = discord.Embed(title=f"We do not accept do-not-kick-list applications for more than 3 weeks!", - description="If you think you won't be able to meet the guild requirements during your inactivity period," - " you can leave the guild and notify staff once you're back. We'll invite you back!", + embed = discord.Embed(title=f"We do not accept do-not-kick-list applications that are longer than 3 weeks!", + description="If you think you will be unable to meet the guild requirements during your inactivity period," + " you can leave the guild and notify staff once you're back. We'll gladly invite you back!", color=neg_color) - await interaction.response.send_message(embed=embed) + await self.deny(channel=self.channel, author=self.author, ign=self.ign, uuid=self.uuid, embed=embed, + interaction=interaction, self_denial=True) + + await interaction.response.send_message("**If you missclicked, kindly create a new ticket!**\n" + "You will be punished if you lie and abuse the DNKL system.", + ephemeral=True) + self.view.stop() return reason_view = discord.ui.View() From 50ae4221af183f47ae379647b66456588130a348 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:09:00 -0600 Subject: [PATCH 12/16] feat: replaced the DNKL_Buttons class with a generalized Button_Creator class --- src/utils/ui_utils.py | 97 +++++-------------------------------------- 1 file changed, 10 insertions(+), 87 deletions(-) diff --git a/src/utils/ui_utils.py b/src/utils/ui_utils.py index ef10db9..218d7aa 100644 --- a/src/utils/ui_utils.py +++ b/src/utils/ui_utils.py @@ -225,106 +225,30 @@ async def callback(self, interaction: discord.Interaction): self.view.stop() -class Dnkl_Buttons(discord.ui.Button): +class Button_Creator(discord.ui.Button): def __init__(self, channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, button: list, - embed: discord.Embed): - """ - 3 buttons for 3 dnkl actions. `custom_id` is needed for persistent views. - """ + embed: discord.Embed = None, function=None): + # button = ["LABEL", "CUSTOM_ID", STYLE] self.embed = embed self.channel = channel self.ign = ign self.uuid = uuid self.author = author - super().__init__(label=button[0], custom_id=button[1], style=button[2]) - - async def callback(self, interaction: discord.Interaction): - if bot.staff not in interaction.user.roles: - await self.channel.send(embed=missing_permissions_embed) - return - # if bot.staff not in interaction.user.roles and ticket.id != interaction.channel_id: return - elif interaction.custom_id == "DNKL_Approve": - msg = await bot.get_channel(dnkl_channel_id).send(embed=self.embed) - - # Check if user is already on DNKL - current_message = await select_one("SELECT message_id FROM dnkl WHERE uuid = (?)", - (self.uuid,)) - # User is not currently on DNKL - if not current_message: - await insert_new_dnkl(msg.id, self.uuid, self.ign) - return await interaction.response.send_message("**This user has been added to the do-not-kick-list!**") - - # User is already on DNKl - # Try to delete current message - try: - current_message = await bot.get_channel(dnkl_channel_id).fetch_message( - current_message) - await current_message.delete() - except Exception: - pass - - await update_dnkl(msg.id, self.uuid) - await interaction.response.send_message( - "**Since this user was already on the do-not-kick-list, their entry has been updated.**") - elif interaction.custom_id == "DNKL_Deny": - await interaction.response.send_message("**This user's do-not-kick-list application has been denied!.**\n" - "If you didn't mean to hit deny, you can add them using `/dnkl_add`.", - ephemeral=True) - - denial_embed = discord.Embed(title="Your do-not-kick-list application has been denied!", - description=f"You do not meet the DNKL requirements of {format(dnkl_req, ',d')} weekly guild experience.", - color=neg_color) - denial_embed.set_footer( - text="If don't you think you can meet the requirements, you may rejoin the guild once your inactivity period has ended.") - closeView = discord.ui.View(timeout=None) # View for staff members to approve/deny the DNKL - button = ("Close This Ticket", discord.enums.ButtonStyle.red) - closeView.add_item( - CloseDNKLTicket(channel=self.channel, author=self.author, ign=self.ign, uuid=self.uuid, button=button)) - await self.channel.send(embed=denial_embed, view=closeView) - await delete_dnkl(self.ign) - - elif interaction.custom_id == "DNKL_Error": - await interaction.response.send_message(embed=discord.Embed( - title="Your application has been accepted, however there was an error!", - description="Please await staff assistance!", - color=neutral_color)) - self.view.stop() - - -class CloseDNKLTicket(discord.ui.Button): - def __init__(self, channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, button: list): - self.channel = channel - self.ign = ign - self.uuid = uuid - self.author = author + self.function = function - super().__init__(label=button[0], style=button[1]) + super().__init__(label=button[0], custom_id=button[1], style=button[2]) async def callback(self, interaction: discord.Interaction): - if self.author != interaction.user: - await self.channel.send(embed=missing_permissions_embed) + meets_req = await self.function(channel=self.channel, author=self.author, ign=self.ign, uuid=self.uuid, + embed=self.embed, + interaction=interaction) + if not meets_req: return - - embed = discord.Embed(title="This ticket will be deleted in 20 seconds!", color=neg_color) - - # Send deletion warning and gather transcript - await interaction.response.send_message(embed=embed) - transcript = await chat_exporter.export(self.channel, limit=None) - if transcript: - transcript = discord.File(BytesIO(transcript.encode()), filename=f"transcript-{self.channel.name}.html") - await bot.get_channel(log_channel_id).send( - f"DNKL Request was denied and channel was deleted by {self.author}") - await bot.get_channel(log_channel_id).send(file=transcript) - - # Sleep and delete channel - await asyncio.sleep(20) - await discord.TextChannel.delete(self.channel) - self.view.stop() class ModalCreator(discord.ui.Modal): - def __init__(self, embed: discord.Embed, fields: list, title: str, ign: str, uuid: str,function = None) -> None: + def __init__(self, embed: discord.Embed, fields: list, title: str, ign: str, uuid: str, function=None) -> None: # fields = ["LABEL", "PLACEHOLDER", STYLE] super().__init__(title=title) self.embed = embed @@ -349,4 +273,3 @@ async def callback(self, interaction: discord.Interaction): count += 1 await interaction.response.send_message(embeds=[self.embed]) - From f9aa08a594d20bd59a9af5decb96a75cd840bc1c Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:09:16 -0600 Subject: [PATCH 13/16] feat: added support for the generalized class --- src/utils/ui_utils.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/utils/ui_utils.py b/src/utils/ui_utils.py index 218d7aa..4f337e2 100644 --- a/src/utils/ui_utils.py +++ b/src/utils/ui_utils.py @@ -210,15 +210,13 @@ async def callback(self, interaction: discord.Interaction): staff_approval_embed.set_footer(text="Other Elaboration: \n" + other_reason) DNKLView = discord.ui.View(timeout=None) # View for staff members to approve/deny the DNKL - buttons = [["Approve", "DNKL_Approve", discord.enums.ButtonStyle.green], - ["Deny", "DNKL_Deny", discord.enums.ButtonStyle.red], - ["Error", "DNKL_Error", discord.enums.ButtonStyle.gray]] + # Loop through the list of roles and add a new button to the view for each role. - for button in buttons: + for button in self.buttons: # Get the role from the guild by ID. DNKLView.add_item( - Dnkl_Buttons(channel=self.channel, author=self.author, ign=self.ign, uuid=self.uuid, button=button, - embed=final_embed)) + Button_Creator(channel=self.channel, author=self.author, ign=self.ign, uuid=self.uuid, button=button, + embed=final_embed, function=button[3])) await self.channel.send("**Staff**, what do you wish to do with this application?", embed=staff_approval_embed, view=DNKLView) From 5ad5749b6a90d831cd558f9c3c2083394244ad08 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:44:36 -0600 Subject: [PATCH 14/16] feat: new function that deals with gvg approvals --- src/utils/discord_utils.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index 841c809..2c38fc0 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -70,6 +70,20 @@ async def close_ticket(channel: discord.TextChannel, author: discord.User, ign: await discord.TextChannel.delete(channel) +async def gvg_approve(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, + interaction: discord.Interaction): + if bot.staff not in interaction.user.roles: + await channel.send(embed=missing_permissions_embed) + return None + + await interaction.response.send_message(embed=discord.Embed( + title="Your application has been accepted!", + description="Please await staff assistance for more information!", + color=neutral_color)) + member = await bot.guild.fetch_member(author.id) + await member.add_roles(bot.gvg) + + return True async def dnkl_error(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, interaction: discord.Interaction): if bot.staff not in interaction.user.roles: From ad726119740acdaedfd002ba882f2ca0187a0685 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:44:47 -0600 Subject: [PATCH 15/16] feat: new function that deals with gvg denials --- src/utils/discord_utils.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index 2c38fc0..c141de2 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -84,6 +84,22 @@ async def gvg_approve(channel: discord.TextChannel, author: discord.User, ign: s await member.add_roles(bot.gvg) return True + + +async def gvg_deny(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, + interaction: discord.Interaction): + if bot.staff not in interaction.user.roles: + await channel.send(embed=missing_permissions_embed) + return None + + await interaction.response.send_message(embed=discord.Embed( + title="Your application has been denied!", + description="Please await staff assistance for more information!", + color=neg_color)) + + return True + + async def dnkl_error(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, interaction: discord.Interaction): if bot.staff not in interaction.user.roles: From 2a98f272c46db387c6abdf2df9f273e43a59be99 Mon Sep 17 00:00:00 2001 From: Amogh Date: Sun, 5 Nov 2023 02:45:34 -0600 Subject: [PATCH 16/16] fix: added return values to dnkl functions --- src/utils/discord_utils.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/utils/discord_utils.py b/src/utils/discord_utils.py index c141de2..5d5dd25 100644 --- a/src/utils/discord_utils.py +++ b/src/utils/discord_utils.py @@ -110,6 +110,7 @@ async def dnkl_error(channel: discord.TextChannel, author: discord.User, ign: st title="Your application has been accepted, however there was an error!", description="Please await staff assistance!", color=neutral_color)) + return True async def dnkl_deny(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, @@ -137,6 +138,8 @@ async def dnkl_deny(channel: discord.TextChannel, author: discord.User, ign: str await channel.send(embed=embed, view=closeView) await delete_dnkl(ign) + return True + async def dnkl_approve(channel: discord.TextChannel, author: discord.User, ign: str, uuid: str, embed: discord.Embed, interaction: discord.Interaction): @@ -167,6 +170,8 @@ async def dnkl_approve(channel: discord.TextChannel, author: discord.User, ign: await interaction.response.send_message( "**Since this user was already on the do-not-kick-list, their entry has been updated.**") + return True + async def create_ticket(user: discord.Member, ticket_name: str, category_name: str = ticket_categories["generic"]): # Create ticket @@ -245,7 +250,6 @@ async def callback(self, interaction: discord.Interaction): await interaction.response.send_modal( modal=uiutils.ModalCreator(embed=embed, fields=fields, ign=ign, uuid=uuid, title="Player Report")) - if option == "Query/Problem": await ticket.edit(name=f"general-{ign}", topic=f"{interaction.user.id}|", category=discord.utils.get(interaction.guild.categories, @@ -339,9 +343,9 @@ async def callback(self, interaction: discord.Interaction): name=ticket_categories["generic"])) # Fetch player data - player_data = await get_hypixel_player(ign) + player_data = await get_hypixel_player(uuid=uuid) if not player_data: - return await ticket.send(unknown_ign_embed) + return await ticket.send(embed=unknown_ign_embed) player_data = player_data["stats"] # Set vars for each stat @@ -411,13 +415,14 @@ async def callback(self, interaction: discord.Interaction): # Send embed and end loop GvGView = discord.ui.View(timeout=None) # View for staff members to approve/deny the DNKL - buttons = [["Accept", "GvG_Application_Positive", discord.enums.ButtonStyle.green], - ["Deny", "GvG_Application_Negative", discord.enums.ButtonStyle.red]] + buttons = (("Accept", "GvG_Application_Positive", discord.enums.ButtonStyle.green, gvg_approve), + ("Deny", "GvG_Application_Negative", discord.enums.ButtonStyle.red, gvg_deny)) # Loop through the list of roles and add a new button to the view for each role. for button in buttons: # Get the role from the guild by ID. GvGView.add_item( - uiutils.Button_Creator(channel=ticket, ign=ign, button=button, member=user, uuid=uuid)) + uiutils.Button_Creator(channel=ticket, ign=ign, button=button, author=user, uuid=uuid, + function=button[3])) await ticket.send("Staff, what do you wish to do with this application?", embed=embed, view=GvGView)