From b828557a6591b001e1c9783a01873b584553d138 Mon Sep 17 00:00:00 2001 From: Conner Harkness Date: Mon, 7 Jul 2025 14:27:03 -0600 Subject: [PATCH] Removed FS based permissions, checks admin priv instead --- bot.py | 213 ++++++++++++++++++++++++--------------------------------- 1 file changed, 89 insertions(+), 124 deletions(-) diff --git a/bot.py b/bot.py index 70b68ee..8649e23 100644 --- a/bot.py +++ b/bot.py @@ -5,16 +5,13 @@ import asyncio import shutil import discord -from pathlib import Path - -intents = discord.Intents(messages=True, guilds=True, message_content=True, reactions=True) +intents = discord.Intents(messages=True, guilds=True, message_content=True, reactions=True, members=True) client = discord.Client(intents=intents) settings = {} -def touch(input_path): - path = Path(input_path) - path.parent.mkdir(parents=True, exist_ok=True) - path.touch(exist_ok=True) +@client.event +async def on_ready(): + print("READY.") @client.event @@ -25,141 +22,113 @@ async def on_message(msg): guild = await client.fetch_guild(chl.guild.id) member = await guild.fetch_member(msg.author.id) bot = await guild.fetch_member(client.user.id) - args = msg.content.split(" ") - tree = f"guilds/{guild.id}" - stub = f"{tree}/{member.id}" - if len(args) > 0: + arg_str = msg.content + arg_str = re.sub(r"\s{1,}", " ", arg_str) + args = arg_str.split(" ") + cmd = args.pop(0) + arg_str = arg_str.lstrip(cmd).strip() - if args[0] == ".register": + # Allow creating quick roles: + if cmd == ".new": + if len(arg_str) > 0: if member.guild_permissions.administrator: - touch(stub) - - await msg.add_reaction("✅") - await asyncio.sleep(10) + new_role = await guild.create_role(name=arg_str) + await new_role.edit(position=bot.top_role.position - 1) await msg.delete() - - return - - if args[0] == ".revoke": - if member.guild_permissions.administrator: - shutil.rmtree(tree) - - await msg.add_reaction("✅") - await asyncio.sleep(10) - await msg.delete() - - return - - - - - if len(args) > 1: - # Handle .color command: - if args[0] == ".color": - color = args[1] - existing_role = None - color_regex = r"^#[A-Fa-f0-9]{6}$" - - # Discord treats all zeroes as transparent: - if color.lower() == "#000000": - color = "#010101" - - if not re.search(color_regex, color): - await msg.add_reaction("❌") - await asyncio.sleep(10) - await msg.delete() - return - - # Remove any previously assigned color roles: - for role in member.roles: - if re.search(color_regex, role.name): - await member.remove_roles(role) - - # Iterate through all guild roles, find existing role, and delete those without members: - for role in guild.roles: - if not re.match(color_regex, role.name): - continue - - if role.name.lower() == color.lower(): - existing_role = role - continue - - if len(role.members) < 1: - try: - await role.delete(reason="Role contains no more members.") - except: - pass - - if existing_role is None: - color_value = discord.Color(int(color.strip("#"), 16)) - existing_role = await guild.create_role(name=color, color=color_value) - - await existing_role.edit(position=bot.top_role.position - 1) - - await member.add_roles(existing_role) - await msg.delete() - - - if args[0] == ".new": - role_name = args[1] - - if member.guild_permissions.administrator: - new_role = await guild.create_role(name=role_name) - await new_role.edit(position=bot.top_role.position - 1) - await msg.add_reaction("✅") - await asyncio.sleep(10) - await msg.delete() - - return - - -async def on_raw_reaction_add_or_remove(rxn, add=True): - print("Reaction add or remove?") - print(rxn) - - guild_id = rxn.guild_id - channel_id = rxn.channel_id - message_id = rxn.message_id - guild = await client.fetch_guild(guild_id) - chl = await client.fetch_channel(rxn.channel_id) - msg = await chl.fetch_message(rxn.message_id) - author_id = msg.author.id - tree = f"guilds/{guild.id}" - stub = f"{tree}/{author_id}" - - if not os.path.exists(stub): return - - #if re.match(r"^Roles:", msg.content, re.IGNORECASE): + # Allow users to change their own color: + if cmd == ".color": + if len(args) > 0: + color = args[0].lower() + print(color) + existing_role = None + color_regex = r"^#[A-Fa-f0-9]{6}$" + + # Discord treats all zeroes as transparent: + if color == "#000000": + color = "#010101" + + if not re.search(color_regex, color): + await msg.add_reaction("❌") + await asyncio.sleep(10) + await msg.delete() + return + + # Remove any previously assigned color roles: + for role in member.roles: + if re.search(color_regex, role.name): + await member.remove_roles(role) + + # Cache the members early: + members = [member async for member in guild.fetch_members(limit=None)] + + # Iterate through all guild roles, find existing role, and delete those without members: + for role in guild.roles: + if not re.match(color_regex, role.name): + continue + + if role.name.lower() == color: + existing_role = role + break + + # Build a list of role members by iterating through members: + role_members = [m for m in members if role in m.roles] + + if len(role_members) < 1: + try: + await role.delete(reason="Role contains no more members.") + except: + pass + + if existing_role is None: + color_value = discord.Color(int(color.strip("#"), 16)) + existing_role = await guild.create_role(name=color, color=color_value) + + await existing_role.edit(position=bot.top_role.position - 1) + + await member.add_roles(existing_role) + await msg.delete() + +# Handle both reaction events: +async def on_raw_reaction_add_or_remove(rxn, add=True): + + guild_id = rxn.guild_id + channel_id = rxn.channel_id + message_id = rxn.message_id + guild = await client.fetch_guild(guild_id) + chl = await client.fetch_channel(rxn.channel_id) + msg = await chl.fetch_message(rxn.message_id) + author_member = await guild.fetch_member(msg.author.id) + user_member = await guild.fetch_member(rxn.user_id) + + # Exit early if: + if not author_member.guild_permissions.administrator: return + if user_member.bot: return + if client.user in msg.mentions: lines = msg.content.split("\n") found_line = None for line in lines: if rxn.emoji.name in line: - print("REACTION FOUND IN STR") found_line = line break role_id = re.search(r"<@&([0-9]{1,})>", found_line) + role_id = int(role_id.group(1)) if role_id is not None else None - if role_id is not None: - role_id = int(role_id.group(1)) - - role = await guild.fetch_role(role_id) - member = await guild.fetch_member(rxn.user_id) - - if member.bot: + if role_id is None: return + role = await guild.fetch_role(role_id) + if add: await msg.add_reaction(rxn.emoji.name) - await member.add_roles(role) + await user_member.add_roles(role) else: - await member.remove_roles(role) - + await user_member.remove_roles(role) @client.event async def on_raw_reaction_add(rxn): @@ -169,10 +138,6 @@ async def on_raw_reaction_add(rxn): async def on_raw_reaction_remove(rxn): await on_raw_reaction_add_or_remove(rxn, False) -@client.event -async def on_ready(): - print("READY.") - def main(): token = None with open("token.txt") as f: