import os import tomllib from io import BytesIO from typing import Annotated, Self import aiohttp import discord from pydantic import BaseModel, StringConstraints StrippedStr = Annotated[str, StringConstraints(strip_whitespace=True)] class Post(BaseModel): # users authorized to posts users: list[int] # where to put posts channel: int def get_channel( self, client: discord.Client, ) -> discord.Thread | discord.TextChannel: """ Zielkanal für Posts finden """ channel = client.get_channel(self.channel) assert isinstance(channel, discord.Thread | discord.TextChannel) return channel class InfoCommand(BaseModel): name: StrippedStr description: StrippedStr = "..." content: StrippedStr = "" class FileCommand(InfoCommand): file_url: str = "" file_name: str = "" @property async def as_bytes(self) -> bytes | None: async with aiohttp.ClientSession() as session: async with session.get(self.file_url) as response: if response.status != 200: return None return await response.read() @property async def as_discord_file(self) -> discord.File | None: if (as_bytes := await self.as_bytes) is not None: return discord.File( fp=BytesIO(as_bytes), filename=self.file_name, ) class ClubInfo(BaseModel): channels: list[int] info: InfoCommand vorstand: InfoCommand linktree: InfoCommand beitreten: InfoCommand fest: InfoCommand aktion: InfoCommand class Config(BaseModel): discord_token: str command_prefix: str command_failed: str post: Post ev_info: ClubInfo @classmethod def get(cls) -> Self: cfg_path = os.getenv( key="CONFIG_PATH", default="/usr/local/etc/lenaverse-bot/lenaverse-bot.toml", ) with open(cfg_path, "rb") as cfg_file: return cls.model_validate(tomllib.load(cfg_file)) CONFIG = Config.get()