Add och!groups command
This commit is contained in:
90
bot.py
90
bot.py
@@ -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
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
11
lib/utils.py
11
lib/utils.py
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user