From 978f5e857d0a0d0fe54c9e316a459e19f61da553 Mon Sep 17 00:00:00 2001 From: SeaswimmerTheFsh Date: Sun, 20 Aug 2023 15:32:34 -0400 Subject: [PATCH] feat(issues): testing splitting the code into two separate files --- issues/issues.py | 194 ++-------------------------------------- issues/modals.py | 226 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+), 186 deletions(-) create mode 100644 issues/modals.py diff --git a/issues/issues.py b/issues/issues.py index deb992c..c602296 100644 --- a/issues/issues.py +++ b/issues/issues.py @@ -1,8 +1,6 @@ -import asyncio -import aiohttp import discord -from discord.interactions import Interaction from redbot.core import Config, app_commands, commands, checks +from .modals import BotBugModal, IssuesConfigurationModal, IssueResponseModal class Issues(commands.Cog): @@ -57,85 +55,19 @@ class Issues(commands.Cog): @discord.ui.button(label="Bot Bug", style=discord.ButtonStyle.danger, row=0) async def issue_button_bot_bug(self, interaction: discord.Interaction, button: discord.ui.Button): - await interaction.response.send_modal(Issues.BotBugModal(self.color, self.cog_instance, self.original_interaction)) + await interaction.response.send_modal(BotBugModal(self.color, self.cog_instance, self.original_interaction)) @discord.ui.button(label="Cog Bug", style=discord.ButtonStyle.danger, row=1) async def issue_button_cog_bug(self, interaction: discord.Interaction, button: discord.ui.Button): - await interaction.response.send_modal(Issues.BotBugModal(self.color, self.cog_instance, self.original_interaction)) + await interaction.response.send_modal(BotBugModal(self.color, self.cog_instance, self.original_interaction)) @discord.ui.button(label="Bot Suggestion", style=discord.ButtonStyle.blurple, row=0) async def issue_button_bot_suggestion(self, interaction: discord.Interaction, button: discord.ui.Button): - await interaction.response.send_modal(Issues.BotBugModal(self.color, self.cog_instance, self.original_interaction)) + await interaction.response.send_modal(BotBugModal(self.color, self.cog_instance, self.original_interaction)) @discord.ui.button(label="Cog Suggestion", style=discord.ButtonStyle.blurple, row=1) async def issue_button_cog_suggestion(self, interaction: discord.Interaction, button: discord.ui.Button): - await interaction.response.send_modal(Issues.BotBugModal(self.color, self.cog_instance, self.original_interaction)) - - class BotBugModal(discord.ui.Modal, title="Creating issue..."): - def __init__(self, color, cog_instance, original_interaction): - super().__init__() - self.color = color - self.cog_instance = cog_instance - self.original_interaction = original_interaction - - bug_description = discord.ui.TextInput( - label="Describe the bug", - placeholder="A clear and concise description of what the bug is.", - style=discord.TextStyle.paragraph, - max_length=2048 - ) - reproduction_steps = discord.ui.TextInput( - label="To Reproduce", - placeholder="What caused the bug?", - style=discord.TextStyle.paragraph, - required=True, - max_length=2048 - ) - expected_behavior = discord.ui.TextInput( - label="Expected Behavior", - placeholder="A clear and concise description of what you expected to happen.", - style=discord.TextStyle.paragraph, - required=True, - max_length=2048 - ) - additional_context = discord.ui.TextInput( - label="Additional Context", - placeholder="Add any other context about the problem here.", - style=discord.TextStyle.paragraph, - required=False, - max_length=2048 - ) - - async def on_submit(self, interaction: discord.Interaction): - embed = discord.Embed(title = "Issue Request", color = self.color) - fields = [self.bug_description, self.reproduction_steps, self.expected_behavior, self.additional_context] - for item in fields: - title = item.label - value = item.value - if value is not None: - if len(value) > 1024: - words = value.split() - split_value = [] - current_part = "" - for word in words: - if len(current_part) + len(word) + 1 <= 1024: - current_part += word + " " - else: - split_value.append(current_part.strip()) - current_part = word + " " - if current_part: - split_value.append(current_part.strip()) - for i, part in enumerate(split_value): - embed.add_field(name=title if i == 0 else "\u200b", value=part, inline=False) - else: - embed.add_field(name=title, value=value, inline=False) - if interaction.user.discriminator == '0': - username = interaction.user.name - else: - username = f"{interaction.user.name}#{interaction.user.discriminator}" - embed.set_footer(text=f"Submitted by {username} ({interaction.user.id})", icon_url=interaction.user.display_avatar.url) - embed.set_author(name="Bot Bug Report") - await self.cog_instance.submit_issue_request(interaction=interaction, original_interaction=self.original_interaction, embed=embed) + await interaction.response.send_modal(BotBugModal(self.color, self.cog_instance, self.original_interaction)) class IssueConfigurationButton(discord.ui.View): def __init__(self, config, ctx): @@ -145,53 +77,7 @@ class Issues(commands.Cog): @discord.ui.button(label="Change Configuration", style=discord.ButtonStyle.blurple, row=0) async def issue_configuration_button(self, interaction: discord.Interaction, button: discord.ui.Button): - await interaction.response.send_modal(Issues.IssuesConfigurationModal(self.config, self.ctx)) - - class IssuesConfigurationModal(discord.ui.Modal, title="Modifying configuration..."): - def __init__(self, config, ctx): - super().__init__() - self.config = config - self.ctx = ctx - - gitea_root_url = discord.ui.TextInput( - label="Gitea Root URL", - placeholder="https://try.gitea.io", - style=discord.TextStyle.short, - required=False, - max_length=200 - ) - gitea_repository_owner = discord.ui.TextInput( - label="Gitea Repository Owner", - placeholder="foo", - style=discord.TextStyle.short, - required=False, - max_length=200 - ) - gitea_repository = discord.ui.TextInput( - label="Gitea Repository Name", - placeholder="bar", - style=discord.TextStyle.short, - required=False, - max_length=200 - ) - gitea_token = discord.ui.TextInput( - label="Gitea User Access Token", - placeholder="Generate one from your user settings page.", - style=discord.TextStyle.short, - required=False, - max_length=200 - ) - - async def on_submit(self, interaction: discord.Interaction): - if self.gitea_token.value != "": - await self.config.gitea_token.set(self.gitea_token.value) - if self.gitea_root_url.value != "": - await self.config.gitea_root_url.set(self.gitea_root_url.value) - if self.gitea_repository_owner.value != "": - await self.config.gitea_repository_owner.set(self.gitea_repository_owner.value) - if self.gitea_repository.value != "": - await self.config.gitea_repository.set(self.gitea_repository.value) - await interaction.response.send_message(content="Configuration changed!") + await interaction.response.send_modal(IssuesConfigurationModal(self.config, self.ctx)) class IssueResponseButtons(discord.ui.View): def __init__(self, channel, message_id, user): @@ -202,72 +88,8 @@ class Issues(commands.Cog): @discord.ui.button(label="Approve", style=discord.ButtonStyle.green) async def issue_response_button_approve(self, interaction: discord.Interaction, button: discord.ui.Button): - await interaction.response.send_modal(Issues.IssueResponseModal(self.channel, self.message_id, self.user, True)) + await interaction.response.send_modal(IssueResponseModal(self.channel, self.message_id, self.user, True)) @discord.ui.button(label="Deny", style=discord.ButtonStyle.danger) async def issue_response_button_deny(self, interaction: discord.Interaction, button: discord.ui.Button): - await interaction.response.send_modal(Issues.IssueResponseModal(self.channel, self.message_id, self.user, False)) - - class IssueResponseModal(discord.ui.Modal, title="Sending response message..."): - def __init__(self, channel, message_id, user, approved): - super().__init__() - self.channel = channel - self.message_id = message_id - self.user = user - self.approved = approved - self.config = Config.get_conf(None, cog_name='Issues', identifier=4285273314713) - - response = discord.ui.TextInput( - label="Response", - placeholder="", - style=discord.TextStyle.paragraph, - required=False, - max_length=1024 - ) - - async def on_submit(self,interaction: discord.Interaction): - message: discord.Message = await self.channel.fetch_message(self.message_id) - embed = message.embeds[0] - field_values = [] - field_names = [] - if self.approved: - embed.color = 1226519 - embed.title = "Issue Request Approved" - status = "accepted" - else: - embed.color = 15671552 - embed.title = "Issue Request Denied" - status = "denied" - await interaction.response.send_message(content=f"Issue request {status}.") - if self.response.value is not None: - embed.add_field(name=f"Response from {interaction.user.name}", value=self.response.value, inline=False) - if self.approved: - for field in embed.fields: - field_names.append(f"**{field.name}**") - field_values.append(field.value) - if embed.author.name == "Bot Bug Report": - issue_title = f"[BOT BUG] Automatically generated issue" - elif embed.author.name == "Bot Suggestion": - issue_title = f"[BOT SUGGESTION] Automatically generated issue" - elif embed.author.name == "Cog Bug Report" or embed.author.name == "Cog Suggestion": - issue_title = f"[{field_values[0]}] Automatically generated issue" - headers = { - "Authorization": f"Bearer {await self.config.gitea_token()}", - "Accept": "application/json" - } - url = f"{await self.config.gitea_root_url()}/api/v1/repos/{await self.config.gitea_repository_owner()}/{await self.config.gitea_repository()}/issues" - issue_body = "\n".join([f"{name}\n{value}" for name, value in zip(field_names, field_values)]) - issue_data = { - "title": issue_title, - "body": issue_body - } - async def create_issue(): - async with aiohttp.ClientSession(headers=headers) as session: - async with session.post(url, json=issue_data) as response: - return await response.json(), response.status - response_json, status_code = await create_issue() - if status_code == 201: - await interaction.response.send_message(content=f"Issue request {status}.\n[Issue successfully created.]({response_json.get('html_url')})", ephemeral=True) - embed.url = response_json.get('html_url') - await message.edit(embed=embed, view=None) - await self.user.send(embed=embed) + await interaction.response.send_modal(IssueResponseModal(self.channel, self.message_id, self.user, False)) diff --git a/issues/modals.py b/issues/modals.py new file mode 100644 index 0000000..893e7c6 --- /dev/null +++ b/issues/modals.py @@ -0,0 +1,226 @@ +import aiohttp +import discord +from redbot.core import Config + +# Misc. functions + +def construct_embed(interaction: discord.Interaction, fields: list, color: str): + embed = discord.Embed(title="Issue Request", color=color) + for item in fields: + title = item.label + value = item.value + if value is not None: + if len(value) > 1024: + words = value.split() + split_value = [] + current_part = "" + for word in words: + if len(current_part) + len(word) + 1 <= 1024: + current_part += word + " " + else: + split_value.append(current_part.strip()) + current_part = word + " " + if current_part: + split_value.append(current_part.strip()) + for i, part in enumerate(split_value): + embed.add_field( + name=title if i == 0 else "\u200b", value=part, inline=False + ) + else: + embed.add_field(name=title, value=value, inline=False) + if interaction.user.discriminator == "0": + username = interaction.user.name + else: + username = f"{interaction.user.name}#{interaction.user.discriminator}" + embed.set_footer( + text=f"Submitted by {username} ({interaction.user.id})", + icon_url=interaction.user.display_avatar.url, + ) + return embed + +# Modals for the core '/issues' command. + +class BotBugModal(discord.ui.Modal, title="Creating issue..."): + def __init__(self, color, cog_instance, original_interaction): + super().__init__() + self.color = color + self.cog_instance = cog_instance + self.original_interaction = original_interaction + + bug_description = discord.ui.TextInput( + label="Describe the bug", + placeholder="A clear and concise description of what the bug is.", + style=discord.TextStyle.paragraph, + max_length=2048 + ) + reproduction_steps = discord.ui.TextInput( + label="To Reproduce", + placeholder="What caused the bug?", + style=discord.TextStyle.paragraph, + required=True, + max_length=2048 + ) + expected_behavior = discord.ui.TextInput( + label="Expected Behavior", + placeholder="A clear and concise description of what you expected to happen.", + style=discord.TextStyle.paragraph, + required=True, + max_length=2048 + ) + additional_context = discord.ui.TextInput( + label="Additional Context", + placeholder="Add any other context about the problem here.", + style=discord.TextStyle.paragraph, + required=False, + max_length=2048 + ) + + async def on_submit(self, interaction: discord.Interaction): + fields = [self.bug_description, self.reproduction_steps, self.expected_behavior, self.additional_context] + embed = construct_embed(interaction, fields, self.color) + embed.set_author(name="Bot Bug Report") + await self.cog_instance.submit_issue_request(interaction=interaction, original_interaction=self.original_interaction, embed=embed) + +# Response modal + +class IssueResponseModal(discord.ui.Modal, title="Sending response message..."): + def __init__(self, channel, message_id, user, approved): + super().__init__() + self.channel = channel + self.message_id = message_id + self.user = user + self.approved = approved + self.config = Config.get_conf(None, cog_name="Issues", identifier=4285273314713) + + issue_title_input = discord.ui.TextInput( + label="Title", + placeholder="Only use this if you're accepting the issue request.", + style=discord.TextStyle.short, + required=False, + max_length=200, + ) + response = discord.ui.TextInput( + label="Response", + placeholder="", + style=discord.TextStyle.paragraph, + required=False, + max_length=1024, + ) + + async def on_submit(self, interaction: discord.Interaction): + message: discord.Message = await self.channel.fetch_message(self.message_id) + embed = message.embeds[0] + field_values = [] + field_names = [] + + if self.approved: + embed.color = 1226519 + embed.title = "Issue Request Approved" + status = "accepted" + else: + embed.color = 15671552 + embed.title = "Issue Request Denied" + status = "denied" + await interaction.response.send_message(content=f"Issue request {status}.") + + if self.response.value is not None: + embed.add_field( + name=f"Response from {interaction.user.name}", + value=self.response.value, + inline=False, + ) + + if self.approved: + for field in embed.fields: + field_names.append(f"**{field.name}**") + field_values.append(field.value) + + if self.issue_title_input.value != "": + _issue_title = self.issue_title_input.value + else: + _issue_title = "Automatically generated issue" + + if embed.author.name == "Bot Bug Report": + issue_title = f"[BOT BUG] {_issue_title}" + elif embed.author.name == "Bot Suggestion": + issue_title = f"[BOT SUGGESTION] {_issue_title}" + elif embed.author.name == "Cog Bug Report" or embed.author.name == "Cog Suggestion": + issue_title = f"[{field_values[0]}] {_issue_title}" + + headers = { + "Authorization": f"Bearer {await self.config.gitea_token()}", + "Accept": "application/json", + } + + url = f"{await self.config.gitea_root_url()}/api/v1/repos/{await self.config.gitea_repository_owner()}/{await self.config.gitea_repository()}/issues" + + issue_body = "\n".join( + [f"{name}\n{value}" for name, value in zip(field_names, field_values)] + ) + + issue_data = {"title": issue_title, "body": issue_body} + + async def create_issue(): + async with aiohttp.ClientSession(headers=headers) as session: + async with session.post(url, json=issue_data) as response: + return await response.json(), response.status + + response_json, status_code = await create_issue() + if status_code == 201: + await interaction.response.send_message( + content=f"Issue request {status}.\n[Issue successfully created.]({response_json.get('html_url')})", + ephemeral=True, + ) + embed.url = response_json.get("html_url") + + await message.edit(embed=embed, view=None) + await self.user.send(embed=embed) + + +# Configuration modal + +class IssuesConfigurationModal(discord.ui.Modal, title="Modifying configuration..."): + def __init__(self, config, ctx): + super().__init__() + self.config = config + self.ctx = ctx + + gitea_root_url = discord.ui.TextInput( + label="Gitea Root URL", + placeholder="https://try.gitea.io", + style=discord.TextStyle.short, + required=False, + max_length=200 + ) + gitea_repository_owner = discord.ui.TextInput( + label="Gitea Repository Owner", + placeholder="foo", + style=discord.TextStyle.short, + required=False, + max_length=200 + ) + gitea_repository = discord.ui.TextInput( + label="Gitea Repository Name", + placeholder="bar", + style=discord.TextStyle.short, + required=False, + max_length=200 + ) + gitea_token = discord.ui.TextInput( + label="Gitea User Access Token", + placeholder="Generate one from your user settings page.", + style=discord.TextStyle.short, + required=False, + max_length=200 + ) + + async def on_submit(self, interaction: discord.Interaction): + if self.gitea_token.value != "": + await self.config.gitea_token.set(self.gitea_token.value) + if self.gitea_root_url.value != "": + await self.config.gitea_root_url.set(self.gitea_root_url.value) + if self.gitea_repository_owner.value != "": + await self.config.gitea_repository_owner.set(self.gitea_repository_owner.value) + if self.gitea_repository.value != "": + await self.config.gitea_repository.set(self.gitea_repository.value) + await interaction.response.send_message(content="Configuration changed!")