2023-09-01 19:37:50 -04:00
import discord
2023-09-01 22:02:15 -04:00
from discord import ui
2023-09-01 19:37:50 -04:00
from redbot . core import Config , checks , commands
class Forums ( commands . Cog ) :
""" Custom cog intended for use on the Galaxy discord server.
Developed by SeaswimmerTheFsh . """
def __init__ ( self , bot ) :
self . bot = bot
self . config = Config . get_conf ( self , identifier = 2352711325 )
self . config . register_guild (
2023-09-07 18:30:57 -04:00
request_roles = [ ] ,
2023-09-08 13:56:44 -04:00
forum_channel = None ,
forum_tag = None
2023-09-01 19:37:50 -04:00
)
2023-09-01 19:42:11 -04:00
@commands.command ( )
2023-09-08 13:56:44 -04:00
@commands.guild_only ( )
2023-09-07 19:50:51 -04:00
async def resolved ( self , ctx : commands . Context , * , reason : str = None ) :
2023-09-01 19:37:50 -04:00
""" Marks a thread as resolved. """
2023-09-08 13:56:44 -04:00
channel_id = await self . config . guild ( ctx . guild ) . forum_channel ( )
tag = await self . config . guild ( ctx . guild ) . forum_tag ( )
request_role_ids = await self . config . guild ( ctx . guild ) . request_roles ( )
if channel_id is None or tag is None or request_role_ids is None :
await ctx . reply ( f " Configuration not set properly! Please set configuration options with ` { ctx . prefix } resolvedset`. " )
return
if isinstance ( ctx . channel , discord . Thread ) and ctx . channel . parent_id == channel_id :
2023-09-07 19:49:59 -04:00
request_roles = [ ctx . guild . get_role ( role_id ) for role_id in request_role_ids ]
match = any ( role in ctx . author . roles for role in request_roles )
2023-09-01 22:02:15 -04:00
passed_info = {
2023-09-07 19:49:59 -04:00
" ctx " : ctx
2023-09-01 22:02:15 -04:00
}
if match and reason :
passed_info . update ( { " reason " : reason } )
2023-09-07 19:20:07 -04:00
if match or ctx . author . id == ctx . channel . owner . id :
2023-09-01 22:02:15 -04:00
msg = await ctx . send ( " Are you sure you ' d like to mark this thread as resolved? " )
passed_info . update ( { " msg " : msg } )
await msg . edit ( view = self . ResolvedButtons ( timeout = 180 , passed_info = passed_info ) )
2023-09-07 19:35:46 -04:00
else :
await ctx . message . add_reaction ( " ❌ " )
2023-09-07 20:09:09 -04:00
await ctx . message . delete ( delay = 5 )
2023-09-01 22:02:15 -04:00
class ResolvedButtons ( ui . View ) :
def __init__ ( self , timeout , passed_info : dict ) :
super ( ) . __init__ ( )
self . timeout = timeout
self . ctx : commands . Context = passed_info [ ' ctx ' ]
self . msg : discord . Message = passed_info [ ' msg ' ]
2023-09-07 19:17:42 -04:00
if ' reason ' in passed_info :
2023-09-01 22:02:15 -04:00
self . reason : str = passed_info [ ' reason ' ]
2023-09-07 19:36:47 -04:00
else :
self . reason = False
2023-09-01 22:02:15 -04:00
self . config = Config . get_conf ( None , cog_name = ' Forums ' , identifier = 2352711325 )
@ui.button ( label = " Yes " , style = discord . ButtonStyle . success , emoji = " ✅ " )
2023-09-07 19:34:46 -04:00
async def resolved_button_yes ( self , interaction : discord . Interaction , button : ui . Button ) :
2023-09-07 19:49:59 -04:00
request_role_ids = await self . config . guild ( interaction . guild ) . request_roles ( )
request_roles = [ interaction . guild . get_role ( role_id ) for role_id in request_role_ids ]
match = any ( role in interaction . user . roles for role in request_roles )
2023-09-07 19:20:07 -04:00
if match or interaction . user . id == interaction . channel . owner . id :
2023-09-07 19:17:42 -04:00
await interaction . response . defer ( )
if self . reason :
response_reason = f " Thread closed by { interaction . user . mention } with reason: { self . reason } "
reason = f " Thread closed by { interaction . user . name } ( { interaction . user . id } ) with reason: { self . reason } "
else :
response_reason = f " Thread closed by { interaction . user . mention } "
reason = f " Thread closed by { interaction . user . name } ( { interaction . user . id } ) "
await self . msg . edit ( content = response_reason , view = None )
2023-09-07 19:51:36 -04:00
await self . ctx . message . delete ( )
2023-09-07 19:44:25 -04:00
tag = interaction . channel . parent . get_tag ( await self . config . guild ( interaction . guild ) . forum_tag ( ) )
if tag in interaction . channel . applied_tags :
await interaction . channel . edit ( locked = True , archived = True , reason = reason )
else :
await interaction . channel . edit ( locked = True , archived = True , applied_tags = interaction . channel . applied_tags + [ tag ] , reason = reason )
2023-09-07 19:17:42 -04:00
else :
await interaction . response . send_message ( content = " You cannot close this thread! " , ephemeral = True )
2023-09-07 19:27:18 -04:00
@ui.button ( label = " No " , style = discord . ButtonStyle . danger , emoji = " ✖️ " )
2023-09-07 19:34:46 -04:00
async def resolved_button_no ( self , interaction : discord . Interaction , button : ui . Button ) :
2023-09-07 19:49:59 -04:00
request_role_ids = await self . config . guild ( interaction . guild ) . request_roles ( )
request_roles = [ interaction . guild . get_role ( role_id ) for role_id in request_role_ids ]
match = any ( role in interaction . user . roles for role in request_roles )
2023-09-07 19:20:07 -04:00
if match or interaction . user . id == interaction . channel . owner . id :
2023-09-07 19:17:42 -04:00
await interaction . response . defer ( )
await self . msg . delete ( )
await self . ctx . message . delete ( )
else :
await interaction . response . send_message ( content = " You cannot close this thread! " , ephemeral = True )
2023-09-01 22:02:15 -04:00
2023-09-07 20:03:16 -04:00
@commands.group ( name = ' resolvedset ' , autohelp = True , aliases = [ ' resolvedconfig ' ] )
2023-09-01 22:02:15 -04:00
@commands.guild_only ( )
@commands.admin ( )
2023-09-07 20:03:16 -04:00
async def resolvedset ( self , ctx : commands . Context ) :
""" Manages the configuration for the [p]resolved command. """
2023-09-08 13:56:44 -04:00
@resolvedset.group ( name = ' show ' , aliases = [ ' settings ' ] )
async def resolvedset_show ( self , ctx : commands . Context ) :
""" Shows the current cog configuration. """
channel_id = await self . config . guild ( ctx . guild ) . forum_channel ( )
tag = await self . config . guild ( ctx . guild ) . forum_tag ( )
request_role_ids = await self . config . guild ( ctx . guild ) . request_roles ( )
split_content = ctx . message . content . split ( )
command = ' ' . join ( split_content [ : 1 ] )
already_in_list = [ ]
for role_id in request_role_ids :
role_obj = ctx . guild . get_role ( role_id )
if role_obj :
already_in_list . append ( role_obj . mention )
if already_in_list :
roles_list = " Roles already in the allowed roles list: \n " + " \n " . join ( already_in_list ) + f " \n Use ` { command } add` to add roles to this list. \n Use ` { command } remove` to remove roles from this list. "
else :
roles_list = f " No roles are currently in the allowed roles list. \n Use ` { command } add` to add some. "
tag_str = None
if channel_id is not None :
channel_obj = ctx . guild . get_channel ( channel_id )
if channel_obj is None :
channel = f " Channel: { channel_id } \n - ⚠️ This channel cannot be found in this guild. Is this the correct ID? \n \n "
else :
channel = f " Channel: { channel_obj . mention } \n \n "
if tag is not None :
tag_obj = channel_obj . get_tag ( tag )
if tag_obj is None :
tag_str = f " Tag: { tag } \n - ⚠️ This tag cannot be found in the set forums channel. Is this the correct ID? \n \n "
else :
tag_str = f " Tag: { tag_obj . emoji } { tag_obj . name } \n \n "
else :
channel = f " Channel: Not set! \n - Use ` { command } channel` to set the forums channel. \n \n "
if tag_str is None :
tag_str = f " Tag: Not set! \n - Use ` { command } tag` to set the tag. \n \n "
embed = discord . Embed ( title = " resolvedset Settings " , color = await self . bot . get_embed_color ( None ) , description = channel + tag_str + roles_list )
await ctx . reply ( embed = embed )
2023-09-07 20:03:16 -04:00
@resolvedset.group ( name = ' role ' , invoke_without_command = True , aliases = [ ' roles ' ] )
async def resolvedset_role ( self , ctx : commands . Context ) :
""" Manages the allowed roles list. """
2023-09-01 22:02:15 -04:00
current_list = await self . config . guild ( ctx . guild ) . request_roles ( )
already_in_list = [ ]
for role_id in current_list :
role_obj = ctx . guild . get_role ( role_id )
if role_obj :
already_in_list . append ( role_obj . mention )
2023-09-07 20:08:22 -04:00
split_content = ctx . message . content . split ( )
2023-09-07 20:10:26 -04:00
command = ' ' . join ( split_content [ : 2 ] )
2023-09-01 22:02:15 -04:00
if already_in_list :
2023-09-07 20:10:26 -04:00
await ctx . send ( " Roles already in the allowed roles list: \n " + " \n " . join ( already_in_list ) + f " \n Use ` { command } add` to add roles to this list. \n Use ` { command } remove` to remove roles from this list. " , allowed_mentions = discord . AllowedMentions ( roles = False ) )
2023-09-01 22:02:15 -04:00
else :
2023-09-07 20:08:22 -04:00
await ctx . send ( f " No roles are currently in the allowed roles list. \n Use ` { command } add` to add some! " )
2023-09-01 22:02:15 -04:00
2023-09-07 20:03:16 -04:00
@resolvedset_role.command ( name = ' add ' )
async def resolvedset_role_add ( self , ctx : commands . Context , role : discord . Role = None ) :
""" Adds roles to the allowed roles list. """
2023-09-01 22:02:15 -04:00
current_list = await self . config . guild ( ctx . guild ) . request_roles ( )
if role :
if role . id in current_list :
2023-09-07 20:03:16 -04:00
await ctx . send ( " This role is already in the allowed roles list! " )
2023-09-01 22:02:15 -04:00
return
else :
current_list . append ( role . id )
await self . config . guild ( ctx . guild ) . request_roles . set ( current_list )
2023-09-07 20:03:16 -04:00
await ctx . send ( f " { role . mention } has been added to the allowed roles list. " , allowed_mentions = discord . AllowedMentions ( roles = False ) )
2023-09-01 22:02:15 -04:00
else :
await ctx . send ( " Please provide a valid role. " )
2023-09-07 20:03:16 -04:00
@resolvedset_role.command ( name = ' remove ' )
async def resolvedset_role_remove ( self , ctx : commands . Context , role : discord . Role = None ) :
""" Removes roles from the allowed roles list. """
2023-09-01 22:02:15 -04:00
current_list = await self . config . guild ( ctx . guild ) . request_roles ( )
if role . id in current_list :
current_list . remove ( role . id )
await self . config . guild ( ctx . guild ) . request_roles . set ( current_list )
2023-09-07 20:03:16 -04:00
await ctx . send ( f " { role . mention } has been removed from the allowed roles list. " , allowed_mentions = discord . AllowedMentions ( roles = False ) )
2023-09-01 19:56:41 -04:00
else :
2023-09-07 20:03:16 -04:00
await ctx . send ( " Please provide a valid role that exists in the allowed roles list. " )
2023-09-01 22:02:15 -04:00
2023-09-01 22:04:59 -04:00
def create_select_options ( self , ctx : commands . Context , data ) :
2023-09-01 22:02:15 -04:00
options = [ ]
for tag in data :
2023-09-01 22:04:59 -04:00
emoji = ctx . guild . get_emoji ( tag . emoji . id ) if tag . emoji . id else str ( tag . emoji . name )
2023-09-07 18:55:49 -04:00
options . append ( discord . SelectOption ( label = tag . name , emoji = emoji , description = " " , value = tag . id ) )
2023-09-01 22:02:15 -04:00
return options
2023-09-07 23:25:50 -04:00
@resolvedset.command ( name = " channel " )
async def resolvedset_channel ( self , ctx : commands . Context , channel : discord . abc . GuildChannel ) :
""" Sets the forums channel used by the [p]resolved command. """
if isinstance ( channel , discord . ForumChannel ) :
await self . config . guild ( ctx . guild ) . forum_channel . set ( channel . id )
await ctx . send ( f " Forum channel has been set to { channel . mention } . " )
else :
await ctx . send ( f " { channel . mention } is not a forums channel! " )
2023-09-07 20:03:16 -04:00
@resolvedset.command ( name = " tag " )
async def resolvedset_tag ( self , ctx : commands . Context , channel : discord . ForumChannel ) :
""" Sets the tag used by the [p]resolved command. """
2023-09-01 22:04:59 -04:00
options = self . create_select_options ( ctx , channel . available_tags )
2023-09-08 13:56:44 -04:00
msg = await ctx . send ( " Select a forum tag below. " )
2023-09-01 22:15:42 -04:00
await msg . edit ( view = SelectView ( msg , options ) )
2023-09-01 22:02:15 -04:00
class Select ( ui . Select ) :
2023-09-01 22:13:26 -04:00
def __init__ ( self , message , options ) :
self . message = message
2023-09-01 22:02:15 -04:00
super ( ) . __init__ ( placeholder = " Select an option " , max_values = 1 , min_values = 1 , options = options )
async def callback ( self , interaction : discord . Interaction ) :
2023-09-01 22:13:26 -04:00
msg : discord . Message = self . message
config = Config . get_conf ( None , cog_name = ' Forums ' , identifier = 2352711325 )
2023-09-07 18:55:49 -04:00
await config . guild ( msg . guild ) . forum_tag . set ( int ( self . values [ 0 ] ) )
2023-09-01 22:30:45 -04:00
await msg . edit ( content = f " Set resolved tag to { self . values [ 0 ] } " , view = None )
2023-09-01 22:25:12 -04:00
await interaction . response . defer ( )
2023-09-01 22:02:15 -04:00
class SelectView ( ui . View ) :
2023-09-01 22:25:12 -04:00
def __init__ ( self , message , options , * , timeout = 180 ) :
2023-09-01 22:02:15 -04:00
super ( ) . __init__ ( timeout = timeout )
2023-09-01 22:25:12 -04:00
self . add_item ( Select ( message , options ) )