mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-09-30 09:06:22 +13:00
161 lines
6 KiB
Python
161 lines
6 KiB
Python
import asyncio
|
|
import discord
|
|
|
|
from typing import Optional, Literal
|
|
from redbot.core import Config, checks, commands
|
|
from redbot.core.utils.chat_formatting import *
|
|
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
|
|
|
from .discord_thread_feature import create_thread, add_user_thread, get_active_threads
|
|
|
|
|
|
class ThreadManager(commands.Cog):
|
|
"""
|
|
Better Thread Manager
|
|
"""
|
|
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.config = Config.get_conf(self, identifier=165164165133023130, force_registration=True)
|
|
|
|
# allowed roles maps role id (str) -> number of threads each user can create with this role (int)
|
|
# threads maps member id str -> list of active thread ids (int) that the user created in the channel
|
|
default_channel = {"allowed_roles": {}, "threads": {}}
|
|
default_guild = {"archive": 60}
|
|
self.config.register_channel(**default_channel)
|
|
self.config.register_guild(**default_guild)
|
|
|
|
@commands.group()
|
|
@commands.guild_only()
|
|
@checks.admin_or_permissions(administrator=True)
|
|
async def threadset(self, ctx):
|
|
"""
|
|
Manage threads
|
|
"""
|
|
pass
|
|
|
|
@threadset.command(name="list")
|
|
async def threadset_list(self, ctx):
|
|
"""
|
|
List all channels and their thread roles
|
|
"""
|
|
channel_data = await self.config.all_channels()
|
|
|
|
msg = ""
|
|
for id, data in channel_data.items():
|
|
channel = ctx.guild.get_channel(id)
|
|
if not channel:
|
|
continue
|
|
|
|
msg += f"#{channel.name}\n"
|
|
for role_id, num_threads in data["allowed_roles"].items():
|
|
role = ctx.guild.get_role(int(role_id))
|
|
if not role:
|
|
continue
|
|
msg += f"\t- @{role.name}: {num_threads}\n"
|
|
msg += "\n"
|
|
|
|
pages = list(pagify(msg, page_length=1700, delims=["\n"], priority=True))
|
|
pages = [box(f"{page}\n\n-----------------\nPage {i+1} of {len(pages)}") for i, page in enumerate(pages)]
|
|
|
|
if not pages:
|
|
await ctx.send("No channels setup to use thread manager.", delete_after=30)
|
|
else:
|
|
await menu(ctx, pages, DEFAULT_CONTROLS)
|
|
|
|
@threadset.command(name="archive")
|
|
async def threadset_archive(self, ctx, archive: int):
|
|
"""
|
|
Set the archive duration of user created threads
|
|
|
|
Must be one of: 60, 1440, 4320, and 10080
|
|
If your guild doesn't have longer thread archival features, the archive value is clipped to the highest value available.
|
|
"""
|
|
if archive not in [60, 1440, 4320, 10080]:
|
|
return await ctx.send("Invalid archive time, try again.", delete_after=30)
|
|
|
|
await self.config.guild(ctx.guild).archive.set(archive)
|
|
await ctx.tick()
|
|
|
|
@threadset.command(name="add")
|
|
async def threadset_add(self, ctx, channel: discord.TextChannel, num_threads: int, *, role: discord.Role):
|
|
"""
|
|
Set the number for threads anyone with role can create for channel
|
|
|
|
If a user has multiple roles, whatever role has the highest value is used
|
|
"""
|
|
async with self.config.channel(channel).allowed_roles() as allowed_roles:
|
|
allowed_roles[str(role.id)] = num_threads
|
|
await ctx.tick()
|
|
|
|
@threadset.command(name="del")
|
|
async def threadset_del(self, ctx, channel: discord.TextChannel, *, role: discord.Role):
|
|
"""
|
|
Delete a role from a channel
|
|
|
|
Does not cleanup threads currently active
|
|
"""
|
|
async with self.config.channel(channel).allowed_roles() as allowed_roles:
|
|
if str(role.id) in allowed_roles:
|
|
del allowed_roles[str(role.id)]
|
|
|
|
await ctx.tick()
|
|
|
|
@commands.command()
|
|
@commands.guild_only()
|
|
async def thread(self, ctx, *, name: str):
|
|
"""
|
|
Create a new thread from this channel
|
|
|
|
You must have proper permissions set
|
|
"""
|
|
channel = ctx.channel
|
|
guild = ctx.guild
|
|
user = ctx.author
|
|
|
|
allowed_roles = await self.config.channel(channel).allowed_roles()
|
|
roles = {int(r) for r in allowed_roles.keys()}
|
|
u_roles = {r.id for r in user.roles}
|
|
|
|
if not (roles & u_roles):
|
|
return await ctx.send(
|
|
"Sorry, you do not have a role that allows you to create threads here.", delete_after=15
|
|
)
|
|
|
|
possible_roles = roles & u_roles
|
|
num_threads = sorted([allowed_roles[str(r)] for r in possible_roles])[-1]
|
|
|
|
threads = await self.config.channel(channel).threads()
|
|
if str(user.id) not in threads:
|
|
threads[str(user.id)] = []
|
|
|
|
user_threads = threads[str(user.id)]
|
|
if len(user_threads) >= num_threads:
|
|
# first, need to update active threads for this channel
|
|
activate_threads = set(await get_active_threads(self.bot, guild))
|
|
still_active = set(user_threads) & activate_threads
|
|
|
|
# remove not active threads
|
|
user_threads = [t for t in user_threads if t in still_active]
|
|
# update config
|
|
threads[str(user.id)] = user_threads
|
|
await self.config.channel(channel).threads.set(threads)
|
|
|
|
if len(user_threads) >= num_threads:
|
|
return await ctx.send(
|
|
f"You have reached the maximum number ({num_threads}) of threads you can create for this channel. Please have a staff member archive one of your threads.",
|
|
delete_after=15,
|
|
)
|
|
|
|
# now we can create a thread
|
|
archive = await self.config.guild(guild).archive()
|
|
try:
|
|
thread = await create_thread(self.bot, channel, ctx.message, name=name, archive=archive)
|
|
await add_user_thread(self.bot, thread, user)
|
|
except:
|
|
return await ctx.send(
|
|
"Something went wrong, most likely a permissions issue. Please contact a staff member.", delete_after=30
|
|
)
|
|
|
|
threads[str(user.id)].append(thread)
|
|
await self.config.channel(channel).threads.set(threads)
|