2023-08-20 15:32:34 -04:00
import aiohttp
import discord
from redbot . core import Config
2023-08-20 15:48:46 -04:00
#
2023-08-20 15:32:34 -04:00
# Misc. functions
2023-08-20 15:48:46 -04:00
#
2023-08-20 15:32:34 -04:00
2023-08-20 15:48:46 -04:00
def construct_embed ( interaction : discord . Interaction , fields : list [ discord . Embed . fields ] , color : str ) :
2023-08-20 15:32:34 -04:00
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
2023-08-20 15:48:46 -04:00
#
2023-08-20 15:32:34 -04:00
# Modals for the core '/issues' command.
2023-08-20 15:48:46 -04:00
#
2023-08-20 15:32:34 -04:00
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 ,
2023-08-20 15:48:46 -04:00
required = True ,
2023-08-20 15:32:34 -04:00
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 )
2023-08-20 15:48:46 -04:00
class CogBugModal ( 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
cog_name = discord . ui . TextInput (
label = " What cog is causing this error? " ,
placeholder = " If unsure, put \" GalaxyCogs \" . " ,
style = discord . TextStyle . short ,
required = True ,
max_length = 50
)
bug_description = discord . ui . TextInput (
label = " Describe the bug " ,
placeholder = " A clear and concise description of what the bug is. " ,
style = discord . TextStyle . paragraph ,
required = True ,
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 . cog_name , self . bug_description , self . reproduction_steps , self . expected_behavior , self . additional_context ]
embed = construct_embed ( interaction , fields , self . color )
embed . set_author ( name = " Cog Bug Report " )
await self . cog_instance . submit_issue_request ( interaction = interaction , original_interaction = self . original_interaction , embed = embed )
class BotSuggestionModal ( 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
suggestion_description = discord . ui . TextInput (
label = " Describe your suggestion. " ,
placeholder = " A clear and concise description of what your suggestion is. " ,
style = discord . TextStyle . paragraph ,
required = True ,
max_length = 2048
)
alternatives = discord . ui . TextInput (
label = " Describe alternatives you ' ve considered. " ,
placeholder = " A clear and concise description of any alternative solutions or features you ' ve cnosidered. " ,
style = discord . TextStyle . paragraph ,
required = True ,
max_length = 2048
)
additional_context = discord . ui . TextInput (
label = " Additional Context " ,
placeholder = " Add any other context about your suggestion here. " ,
style = discord . TextStyle . paragraph ,
required = False ,
max_length = 2048
)
async def on_submit ( self , interaction : discord . Interaction ) :
fields = [ self . suggestion_description , self . alternatives , self . additional_context ]
embed = construct_embed ( interaction , fields , self . color )
embed . set_author ( name = " Cog Suggestion " )
await self . cog_instance . submit_issue_request ( interaction = interaction , original_interaction = self . original_interaction , embed = embed )
class CogSuggestionModal ( 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
cog_name = discord . ui . TextInput (
label = " What cog is your suggestion for? " ,
placeholder = " If unsure, put \" GalaxyCogs \" . " ,
style = discord . TextStyle . short ,
required = True ,
max_length = 50
)
suggestion_description = discord . ui . TextInput (
label = " Describe your suggestion. " ,
placeholder = " A clear and concise description of what your suggestion is. " ,
style = discord . TextStyle . paragraph ,
required = True ,
max_length = 2048
)
alternatives = discord . ui . TextInput (
label = " Describe alternatives you ' ve considered. " ,
placeholder = " A clear and concise description of any alternative solutions or features you ' ve cnosidered. " ,
style = discord . TextStyle . paragraph ,
required = True ,
max_length = 2048
)
additional_context = discord . ui . TextInput (
label = " Additional Context " ,
placeholder = " Add any other context about your suggestion here. " ,
style = discord . TextStyle . paragraph ,
required = False ,
max_length = 2048
)
async def on_submit ( self , interaction : discord . Interaction ) :
fields = [ self . cog_name , self . suggestion_description , self . alternatives , self . additional_context ]
embed = construct_embed ( interaction , fields , self . color )
embed . set_author ( name = " Cog Suggestion " )
await self . cog_instance . submit_issue_request ( interaction = interaction , original_interaction = self . original_interaction , embed = embed )
#
2023-08-20 15:32:34 -04:00
# Response modal
2023-08-20 15:48:46 -04:00
#
2023-08-20 15:32:34 -04:00
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 "
2023-08-20 16:34:36 -04:00
await interaction . response . send_message ( content = f " Issue request { status } . " , ephemeral = True )
2023-08-20 15:32:34 -04:00
2023-08-20 16:22:27 -04:00
if self . response . value != " " :
2023-08-20 15:32:34 -04:00
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 } "
2023-08-20 16:19:34 -04:00
desired_labels = [ " bot " , " bug " ]
2023-08-20 15:32:34 -04:00
elif embed . author . name == " Bot Suggestion " :
issue_title = f " [BOT SUGGESTION] { _issue_title } "
2023-08-20 16:19:34 -04:00
desired_labels = [ " bot " , " enhancement " ]
elif embed . author . name == " Cog Bug Report " :
2023-08-20 15:32:34 -04:00
issue_title = f " [ { field_values [ 0 ] } ] { _issue_title } "
2023-08-20 16:19:34 -04:00
desired_labels = [ " cog " , " bug " ]
elif embed . author . name == " Cog Suggestion " :
issue_title = f " [ { field_values [ 0 ] } ] { _issue_title } "
desired_labels = [ " cog " , " enhancement " ]
2023-08-20 15:32:34 -04:00
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 ) ]
)
2023-09-24 17:16:32 -04:00
# async def fetch_labels():
# async with aiohttp.ClientSession(headers=headers) as session:
# async with session.post(url=f"{await self.config.gitea_root_url()}/api/v1/repos/{await self.config.gitea_repository_owner()}/{await self.config.gitea_repository()}/labels") as response:
# label_list = []
# for label in response.json():
# if label["name"] in desired_labels:
# label_list.append(label["id"])
# if label_list is None:
# print("Error! Labels are not properly configured on the target repository.")
# return await label_list
2023-08-20 16:19:34 -04:00
2023-08-20 16:32:52 -04:00
issue_labels = None
2023-08-20 16:19:34 -04:00
if issue_labels is None :
issue_data = { " title " : issue_title , " body " : issue_body }
else :
issue_data = { " title " : issue_title , " body " : issue_body , " labels " : issue_labels }
2023-08-20 15:32:34 -04:00
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 )
2023-08-20 15:48:46 -04:00
#
2023-08-20 15:32:34 -04:00
# Configuration modal
2023-08-20 15:48:46 -04:00
#
2023-08-20 15:32:34 -04:00
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! " )