Removed FS based permissions, checks admin priv instead

This commit is contained in:
Conner Harkness 2025-07-07 14:27:03 -06:00
parent cc55f7adda
commit b828557a65

123
bot.py
View File

@ -5,16 +5,13 @@ import asyncio
import shutil import shutil
import discord import discord
from pathlib import Path intents = discord.Intents(messages=True, guilds=True, message_content=True, reactions=True, members=True)
intents = discord.Intents(messages=True, guilds=True, message_content=True, reactions=True)
client = discord.Client(intents=intents) client = discord.Client(intents=intents)
settings = {} settings = {}
def touch(input_path): @client.event
path = Path(input_path) async def on_ready():
path.parent.mkdir(parents=True, exist_ok=True) print("READY.")
path.touch(exist_ok=True)
@client.event @client.event
@ -25,44 +22,32 @@ async def on_message(msg):
guild = await client.fetch_guild(chl.guild.id) guild = await client.fetch_guild(chl.guild.id)
member = await guild.fetch_member(msg.author.id) member = await guild.fetch_member(msg.author.id)
bot = await guild.fetch_member(client.user.id) bot = await guild.fetch_member(client.user.id)
args = msg.content.split(" ")
tree = f"guilds/{guild.id}"
stub = f"{tree}/{member.id}"
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()
# Allow creating quick roles:
if cmd == ".new":
if len(arg_str) > 0:
if member.guild_permissions.administrator:
new_role = await guild.create_role(name=arg_str)
await new_role.edit(position=bot.top_role.position - 1)
await msg.delete()
return
# Allow users to change their own color:
if cmd == ".color":
if len(args) > 0: if len(args) > 0:
color = args[0].lower()
if args[0] == ".register": print(color)
if member.guild_permissions.administrator:
touch(stub)
await msg.add_reaction("")
await asyncio.sleep(10)
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 existing_role = None
color_regex = r"^#[A-Fa-f0-9]{6}$" color_regex = r"^#[A-Fa-f0-9]{6}$"
# Discord treats all zeroes as transparent: # Discord treats all zeroes as transparent:
if color.lower() == "#000000": if color == "#000000":
color = "#010101" color = "#010101"
if not re.search(color_regex, color): if not re.search(color_regex, color):
@ -76,16 +61,22 @@ async def on_message(msg):
if re.search(color_regex, role.name): if re.search(color_regex, role.name):
await member.remove_roles(role) 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: # Iterate through all guild roles, find existing role, and delete those without members:
for role in guild.roles: for role in guild.roles:
if not re.match(color_regex, role.name): if not re.match(color_regex, role.name):
continue continue
if role.name.lower() == color.lower(): if role.name.lower() == color:
existing_role = role existing_role = role
continue break
if len(role.members) < 1: # 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: try:
await role.delete(reason="Role contains no more members.") await role.delete(reason="Role contains no more members.")
except: except:
@ -100,23 +91,8 @@ async def on_message(msg):
await member.add_roles(existing_role) await member.add_roles(existing_role)
await msg.delete() await msg.delete()
# Handle both reaction events:
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): async def on_raw_reaction_add_or_remove(rxn, add=True):
print("Reaction add or remove?")
print(rxn)
guild_id = rxn.guild_id guild_id = rxn.guild_id
channel_id = rxn.channel_id channel_id = rxn.channel_id
@ -124,42 +100,35 @@ async def on_raw_reaction_add_or_remove(rxn, add=True):
guild = await client.fetch_guild(guild_id) guild = await client.fetch_guild(guild_id)
chl = await client.fetch_channel(rxn.channel_id) chl = await client.fetch_channel(rxn.channel_id)
msg = await chl.fetch_message(rxn.message_id) msg = await chl.fetch_message(rxn.message_id)
author_id = msg.author.id author_member = await guild.fetch_member(msg.author.id)
tree = f"guilds/{guild.id}" user_member = await guild.fetch_member(rxn.user_id)
stub = f"{tree}/{author_id}"
if not os.path.exists(stub): # Exit early if:
return if not author_member.guild_permissions.administrator: return
if user_member.bot: return
#if re.match(r"^Roles:", msg.content, re.IGNORECASE):
if client.user in msg.mentions: if client.user in msg.mentions:
lines = msg.content.split("\n") lines = msg.content.split("\n")
found_line = None found_line = None
for line in lines: for line in lines:
if rxn.emoji.name in line: if rxn.emoji.name in line:
print("REACTION FOUND IN STR")
found_line = line found_line = line
break break
role_id = re.search(r"<@&([0-9]{1,})>", found_line) 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: if role_id is None:
role_id = int(role_id.group(1)) return
role = await guild.fetch_role(role_id) role = await guild.fetch_role(role_id)
member = await guild.fetch_member(rxn.user_id)
if member.bot:
return
if add: if add:
await msg.add_reaction(rxn.emoji.name) await msg.add_reaction(rxn.emoji.name)
await member.add_roles(role) await user_member.add_roles(role)
else: else:
await member.remove_roles(role) await user_member.remove_roles(role)
@client.event @client.event
async def on_raw_reaction_add(rxn): 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): async def on_raw_reaction_remove(rxn):
await on_raw_reaction_add_or_remove(rxn, False) await on_raw_reaction_add_or_remove(rxn, False)
@client.event
async def on_ready():
print("READY.")
def main(): def main():
token = None token = None
with open("token.txt") as f: with open("token.txt") as f: