# SPDX-License-Identifier: MIT from __future__ import annotations from typing import TYPE_CHECKING, Any, NoReturn, Optional from .guild import Guild from .utils import MISSING, _assetbytes_to_base64_data, parse_time __all__ = ("Template",) if TYPE_CHECKING: import datetime from .asset import AssetBytes from .state import ConnectionState from .types.template import Template as TemplatePayload from .user import User class _FriendlyHttpAttributeErrorHelper: __slots__ = () def __getattr__(self, attr) -> NoReturn: raise AttributeError("PartialTemplateState does not support http methods.") class _PartialTemplateState: def __init__(self, *, state) -> None: self.__state = state self.http = _FriendlyHttpAttributeErrorHelper() @property def shard_count(self): return self.__state.shard_count @property def user(self): return self.__state.user @property def self_id(self): return self.__state.user.id @property def member_cache_flags(self): return self.__state.member_cache_flags def store_emoji(self, guild, packet): return None def _get_voice_client(self, id): return None def _get_message(self, id): return None def _get_guild(self, id): return self.__state._get_guild(id) async def query_members(self, **kwargs: Any): 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"