Temporary group vcs and a bunch of fixes

This commit is contained in:
2021-03-12 19:09:59 +01:00
parent 4e605e548c
commit 8ffafcf51d
2 changed files with 93 additions and 13 deletions

99
bot.py
View File

@@ -13,7 +13,7 @@ from dotenv import load_dotenv
from lib.config import config, config_meta, config_load, config_save, config_get, config_set, config_get_descriptions, \ from lib.config import config, config_meta, config_load, config_save, config_get, config_set, config_get_descriptions, \
config_set_raw config_set_raw
from lib.utils import async_filter, find_category from lib.utils import async_filter, find_category, find_role_case_insensitive
load_dotenv() load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN') TOKEN = os.getenv('DISCORD_TOKEN')
@@ -49,6 +49,7 @@ OCH_LOEH_SOUND = "assets/och_loeh.mp3"
config_load() config_load()
intents = discord.Intents.default() intents = discord.Intents.default()
intents.members = True intents.members = True
intents.voice_states = True
bot = commands.Bot(command_prefix=config.get('prefix'), intents=intents) bot = commands.Bot(command_prefix=config.get('prefix'), intents=intents)
if 'LIBOPUS' in os.environ and not len(os.environ['LIBOPUS']) == 0: if 'LIBOPUS' in os.environ and not len(os.environ['LIBOPUS']) == 0:
@@ -200,6 +201,21 @@ async def on_message(message: discord.Message):
await bot.process_commands(message) await bot.process_commands(message)
@bot.event
async def on_voice_state_update(member: discord.Member, before: discord.VoiceState, after: discord.VoiceState):
if after.channel is None and before.channel is not None:
channel: discord.VoiceChannel = before.channel
if not channel.voice_states:
if channel.category is not None and channel.name.endswith("_vc"):
if channel.category.name.lower() == config_get("groups-category", channel.guild.id).lower():
name: str = channel.name[:-3]
role = await find_role_case_insensitive(channel.guild, name,
config_get("groups-role-prefix", channel.guild.id))
if role is not None:
await channel.delete(reason="Delete temporary group channel when last person left")
@bot.command(name='random_message', brief='Select a random message from a channel') @bot.command(name='random_message', brief='Select a random message from a channel')
async def random_message_command(ctx: commands.Context, channel: Optional[discord.TextChannel] = None, async def random_message_command(ctx: commands.Context, channel: Optional[discord.TextChannel] = None,
max_cnt: Optional[int] = 100, reaction_filter: Optional[str] = None): max_cnt: Optional[int] = 100, reaction_filter: Optional[str] = None):
@@ -354,13 +370,14 @@ async def group_command(ctx: commands.Context, subcommand: Optional[str], arg: O
await ctx.send("Access denied!") await ctx.send("Access denied!")
return return
if subcommand is None: if subcommand is None:
await ctx.send("Available commands: `list`, `create <group> <members>`, `archive <group>`, `delete <group>`") await ctx.send("Available commands: `list`, `create <group> <members>`, "
"`archive <group>`, `unarchive <group>`, `delete <group>`, `clear_vcs`")
return return
guild: discord.Guild = ctx.guild guild: discord.Guild = ctx.guild
role_prefix = config_get("groups-role-prefix", guild.id) role_prefix = config_get("groups-role-prefix", guild.id)
def collect_group_channels(cat: discord.CategoryChannel) -> dict[str, discord.TextChannel]: def collect_group_channels(cat: discord.CategoryChannel) -> dict[str, discord.abc.GuildChannel]:
return {channel.name: channel for channel in cat.text_channels} return {channel.name: channel for channel in cat.text_channels}
async def collect_group_roles() -> list[discord.Role]: async def collect_group_roles() -> list[discord.Role]:
@@ -369,9 +386,10 @@ async def group_command(ctx: commands.Context, subcommand: Optional[str], arg: O
async def fail_category(type: str, expected: str): async def fail_category(type: str, expected: str):
await ctx.send("Unable to find channel category \"" + expected + "\" for " + type + ". Change in configs.") await ctx.send("Unable to find channel category \"" + expected + "\" for " + type + ". Change in configs.")
def link_channel(channel: discord.TextChannel, italic: bool = False) -> str: def link_channel(channel: discord.abc.GuildChannel, italic: bool = False) -> str:
if italic: if italic:
return '[*' + channel.name + '*](https://discord.com/channels/' + str(guild.id) + '/' + str(channel.id) + ')' return '[*' + channel.name + '*](https://discord.com/channels/' + str(guild.id) + '/' + str(
channel.id) + ')'
return '[' + channel.name + '](https://discord.com/channels/' + str(guild.id) + '/' + str(channel.id) + ')' return '[' + channel.name + '](https://discord.com/channels/' + str(guild.id) + '/' + str(channel.id) + ')'
groups_cat = find_category(guild, config_get("groups-category", guild.id)) groups_cat = find_category(guild, config_get("groups-category", guild.id))
@@ -414,8 +432,29 @@ async def group_command(ctx: commands.Context, subcommand: Optional[str], arg: O
await fail_category("archive", config_get("groups-archive-category", guild.id)) await fail_category("archive", config_get("groups-archive-category", guild.id))
return return
await groups[channel_name].edit(reason="Archive group " + arg, category=archive_cat) await groups[channel_name].edit(reason="Archive group " + arg, category=archive_cat)
if channel_name + "_vc" in groups:
await groups[channel_name + "_vc"].delete(reason="Archive group" + arg)
await ctx.send("Group " + arg + " archived.") await ctx.send("Group " + arg + " archived.")
else:
await ctx.send("Can't find that group!")
elif subcommand == 'unarchive':
if arg is None:
await ctx.send("Group name required!")
return
channel_name = arg.lower()
archive_cat = find_category(guild, config_get("groups-archive-category", guild.id))
if archive_cat is None:
await fail_category("archive", config_get("groups-archive-category", guild.id))
return
archived_groups = collect_group_channels(archive_cat)
if channel_name in archived_groups:
await archived_groups[channel_name].edit(reason="Archive group " + arg, category=groups_cat)
await ctx.send("Group " + arg + " unarchived.")
else: else:
await ctx.send("Can't find that group!") await ctx.send("Can't find that group!")
elif subcommand == 'delete': elif subcommand == 'delete':
@@ -428,18 +467,18 @@ async def group_command(ctx: commands.Context, subcommand: Optional[str], arg: O
await fail_category("archive", config_get("groups-archive-category", guild.id)) await fail_category("archive", config_get("groups-archive-category", guild.id))
return return
active_groups = collect_group_channels(groups_cat) role = await find_role_case_insensitive(guild, arg, role_prefix)
archive_groups = collect_group_channels(archive_cat)
role = guild.get_role(config_get("groups-role-prefix", guild.id) + arg)
if role is not None: if role is not None:
await role.delete(reason="Delete group " + arg) await role.delete(reason="Delete group " + arg)
groups = collect_group_channels(groups_cat)
groups.update(collect_group_channels(archive_cat))
channel_name = arg.lower() channel_name = arg.lower()
if channel_name in active_groups: if channel_name in groups:
await active_groups[channel_name].delete(reason="Delete group " + arg) await groups[channel_name].delete(reason="Delete group " + arg)
if channel_name in archive_groups: if channel_name + "_vc" in groups:
await archive_groups[channel_name].delete(reason="Delete group " + arg) await groups[channel_name + "_vc"].delete(reason="Delete group " + arg)
await ctx.send("Group " + arg + " deleted.") await ctx.send("Group " + arg + " deleted.")
elif subcommand == 'create': elif subcommand == 'create':
@@ -463,6 +502,40 @@ async def group_command(ctx: commands.Context, subcommand: Optional[str], arg: O
await asyncio.sleep(5) await asyncio.sleep(5)
await channel.send("Hi, " + role.mention) await channel.send("Hi, " + role.mention)
await ctx.send("Group " + arg + " created.") await ctx.send("Group " + arg + " created.")
elif subcommand == 'clear_vcs':
cors: list[coroutine] = []
for vc in groups_cat.voice_channels:
cors.append(vc.delete(reason="Clear temporary vcs, as requested by " + ctx.author.mention))
for cor in cors:
await cor
@bot.command(name='groupvc', brief='Creates a temporary vc for the current group text channel')
async def groupvc_command(ctx: commands.Context):
if ctx.channel.category is not None:
guild: discord.Guild = ctx.guild
channel: discord.TextChannel = ctx.channel
if channel.category.name.lower() == config_get("groups-category", guild.id):
role = await find_role_case_insensitive(guild, channel.name, config_get("groups-role-prefix", guild.id))
if role is None:
await ctx.send("Couldn't resolve group role!")
return
category: discord.CategoryChannel = channel.category
for vc in category.voice_channels:
if vc.name.lower() == channel.name.lower() + "_vc":
await ctx.send("Temporary group channel already exists.")
return
vc = await category.create_voice_channel(channel.name + "_vc",
overwrites={
role: discord.PermissionOverwrite(view_channel=True)
},
reason="Create temporary vc for group " + channel.name)
await ctx.send("Created temporary vc for this group")
return
await ctx.send("Not an active group channel!")
def _is_message_valid_for_selection(message: discord.Message, reaction_filter: Optional[str] = None) -> bool: def _is_message_valid_for_selection(message: discord.Message, reaction_filter: Optional[str] = None) -> bool:

View File

@@ -15,3 +15,10 @@ def find_category(guild: discord.Guild, group: str) -> Optional[discord.Category
if cat.name.lower() == group: if cat.name.lower() == group:
return cat return cat
return None return None
async def find_role_case_insensitive(guild: discord.Guild, name: str, prefix: str = '') -> Optional[discord.Role]:
for role in await guild.fetch_roles():
if name.strip().lower() == role.name[len(prefix):].lower():
return role
return None