# SPDX-License-Identifier: MIT from __future__ import annotations from typing import TYPE_CHECKING, Any, List, NoReturn, Optional from .guild import Guild, Member from .utils import MISSING, _assetbytes_to_base64_data, parse_time __all__ = ("Template",) if TYPE_CHECKING: import datetime from .asset import AssetBytes from .flags import MemberCacheFlags from .state import ConnectionState from .types.emoji import Emoji as EmojiPayload from .types.template import Template as TemplatePayload from .user import ClientUser, User class _FriendlyHttpAttributeErrorHelper: __slots__ = () def __getattr__(self, attr) -> NoReturn: raise AttributeError("PartialTemplateState does not support http methods.") class _PartialTemplateState: def __init__(self, *, state: ConnectionState) -> None: self.__state: ConnectionState = state self.http = _FriendlyHttpAttributeErrorHelper() @property def shard_count(self) -> Optional[int]: return self.__state.shard_count @property def user(self) -> ClientUser: return self.__state.user @property def self_id(self) -> int: return self.__state.user.id @property def member_cache_flags(self) -> MemberCacheFlags: return self.__state.member_cache_flags def store_emoji(self, guild: Guild, data: EmojiPayload) -> None: return None def _get_voice_client(self, id: int) -> None: return None def _get_message(self, id: int) -> None: return None def _get_guild(self, id) -> Optional[Guild]: return self.__state._get_guild(id) async def query_members(self, **kwargs: Any) -> List[Member]: return [] def __getattr__(self, attr) -> NoReturn: raise AttributeError(f"PartialTemplateState does not support {attr!r}.") class Template: """Represents a Discord template. .. versionadded:: 1.4 Attributes ---------- code: :class:`str` The template code. uses: :class:`int` How many times the template has been used. name: :class:`str` The name of the template. description: :class:`str` The description of the template. creator: :class:`User` The creator of the template. created_at: :class:`datetime.datetime` An aware datetime in UTC representing when the template was created. updated_at: :class:`datetime.datetime` An aware datetime in UTC representing when the template was last updated. This is referred to as "last synced" in the official Discord client. source_guild: :class:`Guild` The source guild. is_dirty: Optional[:class:`bool`] Whether the template has unsynced changes. .. versionadded:: 2.0 """ __slots__ = ( "code", "uses", "name", "description", "creator", "created_at", "updated_at", "source_guild", "is_dirty", "_state", ) def __init__(self, *, state: ConnectionState, data: TemplatePayload) -> None: self._state = state self._store(data) def _store(self, data: TemplatePayload) -> None: self.code: str = data["code"] self.uses: int = data["usage_count"] self.name: str = data["name"] self.description: Optional[str] = data["description"] creator_data = data.get("creator") self.creator: Optional[User] = ( None if creator_data is None else self._state.create_user(creator_data) ) self.created_at: Optional[datetime.datetime] = parse_time(data.get("created_at")) self.updated_at: Optional[datetime.datetime] = parse_time(data.get("updated_at")) guild_id = int(data["source_guild_id"]) guild: Optional[Guild] = self._state._get_guild(guild_id) self.source_guild: Guild if guild is None: source_serialised = data["serialized_source_guild"] source_serialised["id"] = guild_id state = _PartialTemplateState(state=self._state) # Guild expects a ConnectionState, we're passing a _PartialTemplateState self.source_guild = Guild(data=source_serialised, state=state) # type: ignore else: self.source_guild = guild self.is_dirty: Optional[bool] = data.get("is_dirty", None) def __repr__(self) -> str: return ( f"