Discord/cogs/data.py

184 lines
6.7 KiB
Python
Raw Normal View History

2023-05-06 18:56:25 +03:00
import logging
2023-05-06 19:48:04 +03:00
from os import makedirs
2023-05-06 18:56:25 +03:00
from pathlib import Path
from typing import Union, List, Dict, Any
2023-05-06 18:56:25 +03:00
from uuid import uuid4
from discord import ApplicationContext, Embed, File, option, Role, TextChannel
2023-05-06 18:56:25 +03:00
from discord import utils as ds_utils
2023-05-06 19:48:04 +03:00
from discord.commands import SlashCommandGroup
2023-05-06 18:56:25 +03:00
from discord.ext import commands
2024-12-16 00:36:48 +02:00
from libbot import config_get
2024-06-23 13:05:03 +03:00
from libbot.pycord.classes import PycordBot
2024-12-16 00:36:48 +02:00
from libbot.sync import config_get as sync_config_get
from libbot.sync import json_write as sync_json_write
2023-05-06 18:56:25 +03:00
2024-06-23 13:05:03 +03:00
from classes.holo_user import HoloUser
from enums import Color
2023-05-06 19:48:04 +03:00
from modules.database import col_users
2024-12-16 00:36:48 +02:00
from modules.utils_sync import guild_name
2023-05-06 18:56:25 +03:00
logger = logging.getLogger(__name__)
class Data(commands.Cog):
2024-06-23 13:05:03 +03:00
def __init__(self, client: PycordBot):
self.client: PycordBot = client
2023-05-06 18:56:25 +03:00
data: SlashCommandGroup = SlashCommandGroup("data", "Керування даними користувачів")
2023-05-06 19:48:04 +03:00
@data.command(
2023-05-06 18:56:25 +03:00
name="export",
description="Експортувати дані",
2024-12-16 00:36:48 +02:00
guild_ids=[sync_config_get("guild")],
2023-05-06 18:56:25 +03:00
)
2023-05-06 19:48:04 +03:00
@option(
"kind", description="Тип даних, які треба експортувати", choices=["Користувачі"]
)
async def data_export_cmd(self, ctx: ApplicationContext, kind: str) -> None:
2023-05-06 18:56:25 +03:00
await ctx.defer()
2024-12-16 00:21:41 +02:00
# Return if the user is not an owner and not in the council
if (ctx.user.id not in self.client.owner_ids) and not (
2024-12-16 17:25:35 +02:00
await HoloUser.is_council(ctx.author)
2023-05-08 16:45:00 +03:00
):
2023-05-06 18:56:25 +03:00
logging.info(
2024-06-23 13:05:03 +03:00
"User %s tried to use /export but permission denied",
guild_name(ctx.user),
2023-05-06 18:56:25 +03:00
)
2024-12-16 00:21:41 +02:00
2023-05-06 18:56:25 +03:00
await ctx.respond(
embed=Embed(
2023-05-06 19:48:04 +03:00
title="Відмовлено в доступі",
description="Здається, це команда лише для модераторів",
color=Color.FAIL,
2023-05-06 19:48:04 +03:00
)
)
2024-12-16 00:21:41 +02:00
mod_role: Union[Role, None] = ds_utils.get(
2023-05-08 16:48:15 +03:00
ctx.user.guild.roles, id=await config_get("moderators", "roles")
2023-05-06 19:48:04 +03:00
)
admin_chan: Union[TextChannel, None] = ds_utils.get(
2023-05-06 19:48:04 +03:00
ctx.user.guild.channels,
id=await config_get("adminchat", "channels", "text"),
)
2024-12-16 00:21:41 +02:00
2023-05-06 19:48:04 +03:00
await admin_chan.send(
content="" if mod_role is None else mod_role.mention,
2023-05-06 19:48:04 +03:00
embed=Embed(
title="Неавторизований запит",
description=f"Користувач {ctx.user.mention} запитав у каналі {ctx.channel.mention} команду, до якої не повинен мати доступу/бачити.",
color=Color.FAIL,
2023-05-06 19:48:04 +03:00
),
)
2024-12-16 00:21:41 +02:00
return
logging.info("Moderator %s exported current users list", guild_name(ctx.user))
makedirs("tmp", exist_ok=True)
uuid: str = str(uuid4())
2024-12-16 00:21:41 +02:00
if kind == "Користувачі":
users: List[Dict[str, Any]] = []
2024-12-16 00:21:41 +02:00
for member in ctx.guild.members:
users.append(
{
"id": member.id,
"nick": member.nick,
"username": f"{member.name}#{member.discriminator}",
"bot": member.bot,
}
)
2024-12-16 00:36:48 +02:00
sync_json_write(users, Path(f"tmp/{uuid}"))
2024-12-16 00:21:41 +02:00
2024-12-16 00:36:48 +02:00
await ctx.respond(file=File(Path(f"tmp/{uuid}"), filename="users.json"))
2024-12-16 00:21:41 +02:00
2023-05-06 19:48:04 +03:00
@data.command(
name="migrate",
description="Мігрувати всіх користувачів до бази",
2024-12-16 00:36:48 +02:00
guild_ids=[sync_config_get("guild")],
2023-05-06 19:48:04 +03:00
)
@option(
"kind", description="Тип даних, які треба експортувати", choices=["Користувачі"]
)
async def data_migrate_cmd(self, ctx: ApplicationContext, kind: str) -> None:
2023-05-06 19:48:04 +03:00
await ctx.defer()
2024-12-16 00:21:41 +02:00
# Return if the user is not an owner and not in the council
if (ctx.user.id not in self.client.owner_ids) and not (
2024-12-16 17:25:35 +02:00
await HoloUser.is_council(ctx.author)
2023-05-08 16:45:00 +03:00
):
2023-05-06 19:48:04 +03:00
logging.info(
2024-06-23 13:05:03 +03:00
"User %s tried to use /migrate but permission denied",
guild_name(ctx.user),
2023-05-06 19:48:04 +03:00
)
2024-12-16 00:21:41 +02:00
2023-05-06 19:48:04 +03:00
await ctx.respond(
embed=Embed(
2023-05-06 18:56:25 +03:00
title="Відмовлено в доступі",
description="Здається, це команда лише для модераторів",
color=Color.FAIL,
2023-05-06 18:56:25 +03:00
)
)
2024-12-16 00:21:41 +02:00
mod_role: Union[Role, None] = ds_utils.get(
2023-05-08 16:48:15 +03:00
ctx.user.guild.roles, id=await config_get("moderators", "roles")
2023-05-06 18:56:25 +03:00
)
admin_chan: Union[TextChannel, None] = ds_utils.get(
2023-05-06 18:56:25 +03:00
ctx.user.guild.channels,
id=await config_get("adminchat", "channels", "text"),
)
2024-12-16 00:21:41 +02:00
if admin_chan is not None:
await admin_chan.send(
content="" if mod_role is None else mod_role.mention,
embed=Embed(
title="Неавторизований запит",
description=f"Користувач {ctx.user.mention} запитав у каналі {ctx.channel.mention} команду, до якої не повинен мати доступу/бачити.",
color=Color.FAIL,
),
)
2024-06-23 13:05:03 +03:00
2024-12-16 00:21:41 +02:00
return
logging.info(
"Moderator %s started migration of all members to the database",
guild_name(ctx.user),
)
if kind == "Користувачі":
for member in ctx.guild.members:
if member.bot:
continue
2024-12-16 17:25:35 +02:00
if (await col_users.find_one({"user": member.id})) is None:
user: Dict[str, Any] = {}
defaults: Dict[str, Any] = await config_get("user", "defaults")
2024-12-16 00:21:41 +02:00
user["user"] = member.id
for key in defaults:
user[key] = defaults[key]
2024-12-16 17:25:35 +02:00
await col_users.insert_one(document=user)
2024-12-16 00:21:41 +02:00
logging.info(
"Added DB record for user %s during migration", member.id
)
await ctx.respond(
embed=Embed(
title="Міграцію завершено",
description="Всім користувачам сервера було створено записи в базі даних.",
color=Color.SUCCESS,
2024-12-16 00:21:41 +02:00
)
)
2024-06-23 13:05:03 +03:00
def setup(client: PycordBot) -> None:
2024-06-23 13:05:03 +03:00
client.add_cog(Data(client))