Add och!groups command

This commit is contained in:
2021-03-12 14:14:05 +01:00
parent 02221b0790
commit da5450cd62
3 changed files with 114 additions and 2 deletions

90
bot.py
View File

@@ -3,6 +3,7 @@ import os
import random import random
import re import re
import time import time
from types import coroutine
from typing import Optional, List from typing import Optional, List
import discord import discord
@@ -12,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 from lib.utils import async_filter, find_category
load_dotenv() load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN') TOKEN = os.getenv('DISCORD_TOKEN')
@@ -346,6 +347,93 @@ async def quote_remove_command(ctx: commands.Context, author: str, quote: str):
await ctx.channel.send("No such quote found!") await ctx.channel.send("No such quote found!")
@bot.command(name='groups', brief="Manage groups")
async def group_command(ctx: commands.Context, subcommand: Optional[str], arg: Optional[str],
members: commands.Greedy[discord.Member]):
if subcommand is None:
await ctx.send("Available commands: `list`, `create`, `archive`")
return
guild: discord.Guild = ctx.guild
role_prefix = config_get("groups-role-prefix", guild.id)
def collect_group_channels(cat: discord.CategoryChannel) -> dict[str, discord.TextChannel]:
return {channel.name: channel for channel in cat.text_channels}
async def collect_group_roles() -> list[discord.Role]:
return list(filter(lambda role: role.name.startswith(role_prefix), await guild.fetch_roles()))
async def fail_category(type: str, expected: str):
await ctx.send("Unable to find channel category \"" + expected + "\" for " + type + ". Change in configs.")
def link_channel(channel: discord.TextChannel, italic: bool = False) -> str:
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) + ')'
groups_cat = find_category(guild, config_get("groups-category", guild.id))
if groups_cat is None:
await fail_category("groups", config_get("groups-category", guild.id))
return
if subcommand == 'list':
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
active_groups = collect_group_channels(groups_cat)
archived_groups = collect_group_channels(archive_cat)
msg = ""
for role in await collect_group_roles():
name = role.name[len(role_prefix):]
if name in active_groups:
msg += link_channel(active_groups[name]) + "\n"
elif name in archived_groups:
msg += link_channel(archived_groups[name], True) + "\n"
else:
msg += "*" + name + "*\n"
embed = discord.Embed(title="Groups", description=msg)
embed.set_footer(text="Italic groups are archived or unavailable.")
await ctx.send(embed=embed)
elif subcommand == 'archive':
if arg is None:
await ctx.send("Group name required!")
return
groups = collect_group_channels(groups_cat)
if arg in groups:
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
await groups[arg].edit(reason="Archive group " + arg, category=archive_cat)
else:
await ctx.send("Can't find that group!")
elif subcommand == 'create':
if arg is None:
await ctx.send("Group name required!")
return
arg.strip()
cor = groups_cat.create_text_channel(arg.lower(), reason="Create group " + arg)
cor_role = guild.create_role(name=config_get("groups-role-prefix", guild.id) + arg,
mentionable=True, reason="Create group " + arg)
channel: discord.TextChannel = await cor
cor = channel.edit(sync_permissions=True)
role: discord.Role = await cor_role
await cor
await channel.set_permissions(role, reason="Create group " + arg, read_messages=True)
if members:
for member in members:
await member.add_roles(role, reason="Create group " + arg)
await channel.send("Hi, @" + role.name)
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:
if message.clean_content.strip() == '': if message.clean_content.strip() == '':
return False return False

View File

@@ -4,6 +4,9 @@ from typing import Optional, Any
CONFIG = 'data/config.json' CONFIG = 'data/config.json'
config: dict = { config: dict = {
'groups-category': 'groups',
'groups-archive-category': 'archive',
'groups-role-prefix': 'group_',
'inf19x-insiders-enable': False, 'inf19x-insiders-enable': False,
'loeh-enable': False, 'loeh-enable': False,
'och-timeout': 10, 'och-timeout': 10,
@@ -13,6 +16,18 @@ config: dict = {
'last-och-time': 0, 'last-och-time': 0,
} }
config_meta: dict = { config_meta: dict = {
'groups-category': (
True,
'Set the channel category to use for groups'
),
'groups-archive-category': (
True,
'Sets the archive channel category for groups'
),
'groups-role-prefix': (
True,
'Prefix to use for group roles'
),
'inf19x-insiders-enable': ( 'inf19x-insiders-enable': (
True, True,
'Enables university insider jokes of INF19X' 'Enables university insider jokes of INF19X'

View File

@@ -1,8 +1,17 @@
from collections import AsyncIterable from collections import AsyncIterable
from typing import Callable, AsyncGenerator from typing import Callable, AsyncGenerator, Optional
import discord
async def async_filter(fun: Callable, iterable: AsyncIterable) -> AsyncGenerator: async def async_filter(fun: Callable, iterable: AsyncIterable) -> AsyncGenerator:
async for val in iterable: async for val in iterable:
if fun(val): if fun(val):
yield val yield val
def find_category(guild: discord.Guild, group: str) -> Optional[discord.CategoryChannel]:
group = group.lower()
for cat in guild.categories:
if cat.name.lower() == group:
return cat
return None