from discord import ChannelType, Forbidden, Guild, HTTPException, InvalidData, NotFound, Role, User from discord.abc import Messageable from redbot.core.bot import Red from .base import AuroraBaseModel, AuroraGuildModel class PartialUser(AuroraBaseModel): id: int username: str discriminator: int _obj: User | None @property def name(self): return f"{self.username}#{self.discriminator}" if self.discriminator != 0 else self.username def __str__(self): return self.name def __repr__(self): return f"<{self.__class__.__name__} id={self.id}>" @classmethod async def from_id(cls, bot: Red, user_id: int) -> "PartialUser": user = bot.get_user(user_id) if not user: try: user = await bot.fetch_user(user_id) return cls(bot=bot, id=user.id, username=user.name, discriminator=user.discriminator, _obj=user) except NotFound: return cls(bot=bot, id=user_id, username="Deleted User", discriminator=0, _obj=None) return cls(bot=bot, id=user.id, username=user.name, discriminator=user.discriminator, _obj=user) class PartialChannel(AuroraGuildModel): id: int name: str type: ChannelType _obj: Messageable | None @property def mention(self): if self.name in ["Deleted Channel", "Forbidden Channel"]: return self.name return f"<#{self.id}>" def __str__(self): return self.mention def __repr__(self): return f"<{self.__class__.__name__} id={self.id} guild_id={self.guild_id}>" @classmethod async def from_id(cls, bot: Red, channel_id: int, guild: Guild) -> "PartialChannel": channel = bot.get_channel(channel_id) if not channel: try: channel = await bot.fetch_channel(channel_id) return cls(bot=bot, guild_id=channel.guild.id, guild=guild, id=channel.id, name=channel.name, type=channel.type, _obj=channel) except (NotFound, InvalidData, HTTPException, Forbidden) as e: if e == Forbidden: return cls(bot=bot, guild_id=0, id=channel_id, name="Forbidden Channel") return cls(bot=bot, guild_id=0, id=channel_id, name="Deleted Channel", type=ChannelType.text, _obj=None) return cls(bot=bot, guild_id=channel.guild.id, guild=guild, id=channel.id, name=channel.name, type=channel.type, _obj=channel) class PartialRole(AuroraGuildModel): id: int name: str _obj: Role | None @property def mention(self): if self.name in ["Deleted Role", "Forbidden Role"]: return self.name return f"<@&{self.id}>" def __str__(self): return self.mention def __repr__(self) -> str: return f"<{self.__class__.__name__} id={self.id} guild_id={self.guild_id}>" @classmethod async def from_id(cls, bot: Red, guild: Guild, role_id: int) -> "PartialRole": role = guild.get_role(role_id) if not role: return cls(bot=bot, guild_id=guild.id, id=role_id, name="Deleted Role", _obj=None) return cls(bot=bot, guild_id=guild.id, id=role.id, name=role.name, _obj=role)