Discord/cogs/custom_channels.py

239 lines
9.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
from typing import Any, Dict, Union
from discord import ApplicationContext, Embed, option, TextChannel, Role
from discord import utils as ds_utils
from discord.abc import GuildChannel
from discord.commands import SlashCommandGroup
from discord.ext import commands
from libbot import config_get
from libbot.sync import config_get as sync_config_get
from classes.holo_bot import HoloBot
from classes.holo_user import HoloUser
from enums import Color
from modules.database import col_users
from modules.utils_sync import guild_name
logger = logging.getLogger(__name__)
class CustomChannels(commands.Cog):
def __init__(self, client: HoloBot):
self.client: HoloBot = client
@commands.Cog.listener()
async def on_guild_channel_delete(self, channel: GuildChannel) -> None:
await col_users.find_one_and_update(
{"customchannel": channel.id}, {"$set": {"customchannel": None}}
)
custom_channel_group: SlashCommandGroup = SlashCommandGroup(
"customchannel", "Керування особистим каналом"
)
@custom_channel_group.command(
name="get",
description="Отримати персональний текстовий канал",
guild_ids=[sync_config_get("guild")],
)
@option("name", description="Назва каналу")
@option("reactions", description="Дозволити реакції")
@option("threads", description="Дозволити гілки")
async def custom_channel_get_cmd(
self, ctx: ApplicationContext, name: str, reactions: bool, threads: bool
) -> None:
holo_user_ctx: HoloUser = HoloUser(ctx.user)
# Return if the user is using the command outside of a guild
if not hasattr(ctx.author, "guild"):
await ctx.defer(ephemeral=True)
await ctx.respond(
embed=Embed(
title="Помилка виконання",
description="Виконання за межами сервера не є можливим.",
color=Color.FAIL,
)
)
return
# Return if the user already has a custom channel
if holo_user_ctx.customchannel is not None:
await ctx.defer(ephemeral=True)
await ctx.respond(
embed=Embed(
title="Помилка виконання",
description="У вас вже є особистий канал.\nДля редагування каналу є `/customchannel edit` або просто відкрийте меню керування вашим каналом.",
color=Color.FAIL,
)
)
return
await ctx.defer()
created_channel: TextChannel = await ctx.user.guild.create_text_channel(
name=name,
reason=f"Користувач {guild_name(ctx.user)} отримав власний приватний канал",
category=ds_utils.get(
ctx.author.guild.categories,
id=await config_get("customchannels", "categories"),
),
)
await created_channel.set_permissions(
ctx.user.guild.default_role,
send_messages=False,
add_reactions=reactions,
create_public_threads=threads,
create_private_threads=threads,
)
await created_channel.set_permissions(
ctx.user,
attach_files=True,
manage_messages=True,
send_messages=True,
embed_links=True,
manage_channels=True,
)
await holo_user_ctx.set("customchannel", created_channel.id)
await ctx.respond(
embed=Embed(
title="Створено канал",
description=f"Вітаємо! Ви створили канал {created_channel.mention}. Для керування ним користуйтесь меню налаштувань каналу а також командою `/customchannel edit`",
color=Color.SUCCESS,
)
)
bots: Dict[str, Any] = await config_get("bots")
for bot in bots:
role: Union[Role, None] = ds_utils.get(
ctx.user.guild.roles, id=bots[bot]["role"]
)
if role is not None:
await created_channel.set_permissions(
role,
view_channel=False,
)
@custom_channel_group.command(
name="edit",
description="Змінити параметри особистого каналу",
guild_ids=[sync_config_get("guild")],
)
@option("name", description="Назва каналу")
@option("reactions", description="Дозволити реакції")
@option("threads", description="Дозволити гілки")
async def custom_channel_edit_cmd(
self, ctx: ApplicationContext, name: str, reactions: bool, threads: bool
) -> None:
holo_user_ctx: HoloUser = HoloUser(ctx.user)
custom_channel: Union[TextChannel, None] = ds_utils.get(
ctx.guild.channels, id=holo_user_ctx.customchannel
)
# Return if the channel was not found
if custom_channel is None:
await ctx.respond(
embed=Embed(
title="Канал не знайдено",
description="Канал, вказаний як ваш, не існує. Можливо, його було вручну видалено раніше.",
color=Color.FAIL,
)
)
return
await custom_channel.edit(name=name)
await custom_channel.set_permissions(
ctx.user.guild.default_role,
send_messages=False,
add_reactions=reactions,
create_public_threads=threads,
create_private_threads=threads,
)
await ctx.respond(
embed=Embed(
title="Канал змінено",
description=f"Назва каналу тепер `{name}`, реакції `{reactions}` та дозволено треди `{threads}`",
color=Color.FAIL,
)
)
@custom_channel_group.command(
name="remove",
description="Відібрати канал, знищуючи його, та частково повернути кошти",
guild_ids=[sync_config_get("guild")],
)
@option("confirm", description="Підтвердження операції")
async def custom_channel_remove_cmd(
self, ctx: ApplicationContext, confirm: bool = False
) -> None:
holo_user_ctx: HoloUser = HoloUser(ctx.user)
# Return if the user does not have a custom channel
if holo_user_ctx.customchannel is None:
await ctx.defer(ephemeral=True)
await ctx.respond(
embed=Embed(
title="Помилка виконання",
description="У вас немає особистого каналу.",
color=Color.FAIL,
)
)
return
await ctx.defer()
custom_channel: Union[TextChannel, None] = ds_utils.get(
ctx.guild.channels, id=holo_user_ctx.customchannel
)
# Return if the channel was not found
if custom_channel is None:
await ctx.respond(
embed=Embed(
title="Канал не знайдено",
description="Канал, вказаний як ваш, не існує. Можливо, його було вручну видалено раніше.",
color=Color.FAIL,
)
)
await holo_user_ctx.set("customchannel", None)
return
# Return if the confirmation is missing
if not confirm:
await ctx.respond(
embed=Embed(
title="Підтвердження не надано",
description="Для підтвердження операції додайте до команди параметр `confirm` зі значенням `True`.",
color=Color.FAIL,
)
)
return
await custom_channel.delete(reason="Власник запросив видалення")
await holo_user_ctx.set("customchannel", None)
try:
await ctx.respond(
embed=Embed(
title="Канал знищено",
description="Ви відмовились від каналу та видалили його.",
color=Color.DEFAULT,
)
)
except Exception as exc:
logger.warning(
"Could not send a custom channel removal confirmation due to: %s", exc
)
def setup(client: HoloBot) -> None:
client.add_cog(CustomChannels(client))