Add och!groups command
This commit is contained in:
90
bot.py
90
bot.py
@@ -3,6 +3,7 @@ import os
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
from types import coroutine
|
||||
from typing import Optional, List
|
||||
|
||||
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, \
|
||||
config_set_raw
|
||||
from lib.utils import async_filter
|
||||
from lib.utils import async_filter, find_category
|
||||
|
||||
load_dotenv()
|
||||
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!")
|
||||
|
||||
|
||||
@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:
|
||||
if message.clean_content.strip() == '':
|
||||
return False
|
||||
|
||||
@@ -4,6 +4,9 @@ from typing import Optional, Any
|
||||
|
||||
CONFIG = 'data/config.json'
|
||||
config: dict = {
|
||||
'groups-category': 'groups',
|
||||
'groups-archive-category': 'archive',
|
||||
'groups-role-prefix': 'group_',
|
||||
'inf19x-insiders-enable': False,
|
||||
'loeh-enable': False,
|
||||
'och-timeout': 10,
|
||||
@@ -13,6 +16,18 @@ config: dict = {
|
||||
'last-och-time': 0,
|
||||
}
|
||||
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': (
|
||||
True,
|
||||
'Enables university insider jokes of INF19X'
|
||||
|
||||
11
lib/utils.py
11
lib/utils.py
@@ -1,8 +1,17 @@
|
||||
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 for val in iterable:
|
||||
if fun(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
|
||||
|
||||
Reference in New Issue
Block a user