async def programs(ctx, bot, user: str) -> Tuple[bool, discord.Embed]: """Display's a user's programs Args: ctx (discord.ext.commands.Context): Context bot (discord.ClientUser.bot): Bot user (str): User's programs to display Returns: Tuple[bool, discord.Embed]: [Status: bool, Embed: discord.Embed] """ # Check if user is None: return ( False, create_embed_template("Invalid Arguments", "User was Null.", "error"), ) # Gets the user's id user = parse_id(user) db = await Programs_DB(ctx.guild.id) # Grabs all of the programs programs_list = await db.grab_programs(user) # Empty list if programs_list is None: return ( False, create_embed_template( "Invalid User", "That user doesn't have any programs, have them use /programs add.", "error", ), ) programs_list = programs_list.split("\n") # Creates the message message = "" space_amount = (len(programs_list) // 10) + 1 for i in range(len(programs_list)): if programs_list[i] != "" and programs_list[i] is not None: # Ensure the numbers line up number = f"{i + 1}".rjust(space_amount, " ") # Only add a newline if it's required message += f"{number}. {programs_list[i]}" + ( "\n" if i != (len(programs_list) - 1) else "") user = bot.get_user(user) return ( True, create_embed(f"{user.name}#{user.discriminator}'s Programs", message, "orange"), )
def grab_user(content): user = re.search(r"<@(?:&|!|)[0-9]{18}>", " ".join(content)) if not user: return None, content else: content = " ".join(content).replace(user, "").split(" ") user = parse_id(user.group()) return user, content
async def _programs(self, ctx): """!programs command""" content = ctx.message.content.split(" ") if len(content) == 1: embed = create_embed( "Command: !programs", "**Description**: Allows you to interact with programs commands.\n**Sub Commands**:\n!programs {user} - Allows you to see a user's programs. (ex: !programs <@749359897405161522>)\n!programs add - Allows you to add programs to your list.\n!programs remove - Allows you to remove programs from your list.\n!programs edit - Allows you to edit one of your programs.\n!commands setup - Allows an admin to setup a programs confirmation channel.", "orange", ) await ctx.send(embed=embed) return subcommand = content[1] def grab_user(content): user = re.search(r"<@(?:&|!|)[0-9]{18}>", " ".join(content)) if not user: return None, content else: content = " ".join(content).replace(user, "").split(" ") user = parse_id(user.group()) return user, content if subcommand == "add" or subcommand == "a": #: !programs add Queens CS if len(content) == 2: embed = create_embed( "Command: !programs add", "**Description**: Allows you to add programs to your list.\n**Usage**:\n!programs add Queens CS, Mcgill CS, UW CS\n!programs add Queens CS, UW CS <@749359897405161522>", "orange", ) await ctx.send(embed=embed) else: content = content[2::] user, content = grab_user(content) if user is None: user = ctx.author.id potential_programs = " ".join(content).split("\n") if len(potential_programs) == 1: potential_programs = [ i.strip() for i in potential_programs[0].split(",") ] else: p = [] for i in potential_programs: additions = [g.strip() for g in i.split(",")] p.extend(additions) potential_programs = p result = await programs_add(ctx, self.bot, potential_programs, user) await ctx.send(embed=result[1]) elif subcommand == "remove" or subcommand == "r": if len(content) == 2: embed = create_embed( "Command: !programs remove", "**Description**: Allows you to remove programs from your list. Provide a comma seperated list of numbers, or * to remove all of your programs.\n**Usage**:\n!programs remove 1, 2, 3\n!programs remove * <@749359897405161522>", "orange", ) await ctx.send(embed=embed) return content = content[2::] user, content = grab_user(content) if user is None: user = ctx.author.id result = await programs_remove(ctx, " ".join(content), user) await ctx.send(embed=result[1]) elif subcommand == "edit" or subcommand == "e": #: !command edit 1 New Program if len(content) < 4: embed = create_embed( "Command: !programs edit", "**Description**: Allows you to edit a program in your list. Provide the number for the program, and the new text.\n**Usage**:\n!programs edit 1 Queens CS\n!programs edit 1 Queens CS <@749359897405161522>", "orange", ) await ctx.send(embed=embed) return content = content[2::] user, content = grab_user(content) if user is None: user = ctx.author.id before = content[0] after = " ".join(content[1::]) result = await programs_edit(ctx, self.bot, user, before, after) await ctx.send(embed=result[1]) elif subcommand == "setup" or subcommand == "s": #: !command setup <#846962522065993768> if len(content) == 2 or len(content) > 3: embed = create_embed( "Command: !programs setup", "**Description**: Allows an administrator to setup a programs verification channel.\n**Usage**:\n!programs setup <@799848795050606607>", "orange", ) await ctx.send(embed=embed) return channel_id = parse_id(content[2]) if not channel_id: embed = create_embed_template("Invalid Setup Channel", "", "error") await ctx.send(embed=embed) return result = await programs_setup(ctx, channel_id) await ctx.send(embed=result[1]) else: attempt_user = parse_id(subcommand) if attempt_user: user_id = attempt_user else: user_id = ctx.guild.get_member_named(subcommand).id p = await programs(ctx, self.bot, user_id) await ctx.send(embed=p[1])
async def programs_reaction_handling(ctx: discord.RawReactionActionEvent, client: discord.ClientUser.bot) -> bool: """Handles Reactions for programs verification Args: ctx (discord.ext.commands.Context): Context client (discord.ClientUser.bot): Bot Returns: bool: If it was a programs related reaction """ db = await Programs_DB(ctx.guild_id) db_guild = await Guild_DB(ctx.guild_id) # Grabs the verification channel settings = await db_guild.grab_settings() if settings is None or settings["programs_channel"] is None: return False mod_channel_id = settings["programs_channel"] if mod_channel_id != ctx.channel.id: return False # Grabs the message & embeds m = await client.get_channel(ctx.channel.id).fetch_message(ctx.message.id) embeds = m.embeds[0] reactions = m.reactions # Checks to ensure no one else has already added the reactions if not ((reactions[0].count == 1 and reactions[1].count == 2) or (reactions[0].count == 2 and reactions[1].count == 1)): # An administrator/moderator has already reacted, no need to perform the action twice return False # Deals with programs if m.embeds[0].title == "Programs Verification Required": if ctx.emoji.name == "❌": # Delete await m.delete() return True elif ctx.emoji.name == "✅": user_id = parse_id(embeds.fields[0].value) if not user_id: return True # Checks to see if the user already has a programs list # If they don't count = await db.check_programs_exists(user_id) if count != 1: # Delete the message programs = embeds.fields[1].value await m.delete() if not programs: return False # Add the programs await db.add_programs(user_id, programs) # If they do else: # Delete the message program_additions = embeds.fields[1].value.split("\n") await m.delete() if not program_additions: return False # Grabs the current programs current_programs = await db.grab_programs(user_id) current_programs += "\n" # Adds the additions len_program_additions = len(program_additions) for program in range(len_program_additions): current_programs += program_additions[program] + ( "\n" if program + 1 != len_program_additions else "") # Updates the database to the newer longer version await db.update_programs(user_id, current_programs) # Grabs the user & makes a DM channel user = client.get_user(user_id) dm_channel = user.dm_channel if dm_channel is None: await user.create_dm() dm_channel = user.dm_channel # Sends an embed w/ the new programs embed = create_embed("!Programs Command Created Successfully", "", "light_green") add_field(embed, "Programs", current_programs, True) try: await dm_channel.send(embed=embed) except: return True return True elif m.embeds[0].title == "Programs (Edit) Verification Required": if ctx.emoji.name == "❌": # Delete await m.delete() return True elif ctx.emoji.name == "✅": # User user_id = parse_id(embeds.fields[0].value) if not user_id: await m.delete() return True # New addition & Current program_change = embeds.fields[1].value programs_newmsg = embeds.fields[2].value # Delete await m.delete() # Invalid if not programs_newmsg or not program_change: return True # Grabs current programs current_programs = await db.grab_programs(user_id) # All programs into a dictionary programs = {} i = 1 for p in current_programs.split("\n"): if p == program_change: programs[i] = programs_newmsg else: programs[i] = p i += 1 # Creates a message w/ the programs final_programs = "" p_values = list(programs.values()) len_p_values = len(p_values) for i in range(len_p_values): final_programs += p_values[i] + ("\n" if i + 1 != len_p_values else "") # Update in the databse await db.update_programs(user_id, final_programs) # Open a DM user = client.get_user(user_id) dm_channel = user.dm_channel if dm_channel is None: await user.create_dm() dm_channel = user.dm_channel # Send a status message embed = create_embed("Programs Edit Was Successful", "", "light_green") add_field(embed, "Programs", final_programs, True) try: await dm_channel.send(embed=embed) except: return True return True
async def programs_edit( ctx: discord.ext.commands.Context, client: discord.ClientUser.bot, user: int, before: str, after: str, ) -> Tuple[bool, discord.Embed]: """Edits one of a user's programs Args: ctx (discord.ext.commands.Context): Context client (discord.ClientUser.bot): Bot instance user (int): User's ID before (str): The program to edit after (str): The new text to replace the program Returns: Tuple[bool, discord.Embed]: [Status: bool, Embed: discord.Embed] """ # Check user if user is None: return ( False, create_embed_template("Invalid Arguments", "User was null.", "error"), ) # Check before and after if before is None or after is None: return ( False, create_embed_template("Invalid Arguments", "*Before* or *after* value is invalid.", "error"), ) try: before = int(before) except: return ( False, create_embed_template( "Invalid Arguments", "*Before* value is invalid (not a number).", "error", ), ) user = parse_id(user) db = await Programs_DB(ctx.guild.id) db_guild = await Guild_DB(ctx.guild.id) # Channel for verification settings = await db_guild.grab_settings() if settings is None or settings["programs_channel"] is None: return ( False, create_embed_template( "Invalid Channel", "The admins haven't created a programs channel. Have an admin run /programs setup.", "error", ), ) programs_channel = settings["programs_channel"] programs = (await db.grab_programs(user)).split("\n") # Entire programs list p = {} i = 1 for program in programs: p[i] = program i += 1 if before not in p.keys(): return ( False, create_embed_template( "Invalid Program", "You do not have a program with that *before* value.", "error", ), ) # Create a verification Embed embed = create_embed("Programs (Edit) Verification Required", "", "magenta") add_field(embed, "User", f"{(await client.fetch_user(user)).mention}", True) add_field(embed, "Before", p[before], True) add_field(embed, "After", after, True) verify_channel = client.get_channel(int(programs_channel)) verify_msg = await verify_channel.send(embed=embed) # Add emojis for emoji in ["✅", "❌"]: await verify_msg.add_reaction(emoji) embed = create_embed("Program Edit successfully sent to the moderators.", "", "light_green") add_field(embed, "Before", p[before], True) add_field(embed, "After", after, True) return True, embed