diff --git a/CHANGELOG.md b/CHANGELOG.md index c4434ec0d0..e95d08c840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ These changes are available on the `master` branch, but have not yet been releas ### Added +- Added new parameters (`author`, `footer`, `image`, `thumbnail`) to `discord.Embed`. + ([#1996](https://github.com/Pycord-Development/pycord/pull/1996)) - Added new events `on_bridge_command`, `on_bridge_command_completion`, and `on_bridge_command_error`. ([#1916](https://github.com/Pycord-Development/pycord/pull/1916)) diff --git a/discord/embeds.py b/discord/embeds.py index ca3a9c5e72..1d6a7d11f2 100644 --- a/discord/embeds.py +++ b/discord/embeds.py @@ -34,6 +34,8 @@ __all__ = ( "Embed", "EmbedField", + "EmbedAuthor", + "EmbedFooter", ) @@ -62,7 +64,7 @@ def __repr__(self) -> str: inner = ", ".join( (f"{k}={v!r}" for k, v in self.__dict__.items() if not k.startswith("_")) ) - return f"EmbedProxy({inner})" + return f"{type(self).__name__}({inner})" def __getattr__(self, attr: str) -> _EmptyEmbed: return EmptyEmbed @@ -103,6 +105,64 @@ class _EmbedAuthorProxy(Protocol): proxy_icon_url: MaybeEmpty[str] +class EmbedAuthor(EmbedProxy): + """Represents the author on the :class:`Embed` object. + + .. versionadded:: 2.5 + + Attributes + ---------- + name: :class:`str` + The name of the author. + url: :class:`str` + The URL of the hyperlink created in the author's name. + icon_url: :class:`str` + The URL of the author icon image. + """ + + def __init__( + self, + name: str, + url: MaybeEmpty[str] = EmptyEmbed, + icon_url: MaybeEmpty[str] = EmptyEmbed, + proxy_icon_url: MaybeEmpty[str] = EmptyEmbed, + ) -> None: + layer = { + k: v + for k, v in locals().items() + if k in {"name", "url", "icon_url", "proxy_icon_url"} + and v is not EmptyEmbed + } + super().__init__(layer) + + +class EmbedFooter(EmbedProxy): + """Represents the footer on the :class:`Embed` object. + + .. versionadded:: 2.5 + + Attributes + ---------- + text: :class:`str` + The text inside the footer. + icon_url: :class:`str` + The URL of the footer icon image. + """ + + def __init__( + self, + text: str, + icon_url: MaybeEmpty[str] = EmptyEmbed, + proxy_icon_url: MaybeEmpty[str] = EmptyEmbed, + ) -> None: + layer = { + k: v + for k, v in locals().items() + if k in {"text", "icon_url", "proxy_icon_url"} and v is not EmptyEmbed + } + super().__init__(layer) + + class EmbedField: """Represents a field on the :class:`Embed` object. @@ -246,6 +306,10 @@ def __init__( description: MaybeEmpty[Any] = EmptyEmbed, timestamp: datetime.datetime = None, fields: list[EmbedField] | None = None, + author: MaybeEmpty[EmbedAuthor] = EmptyEmbed, + footer: MaybeEmpty[EmbedFooter] = EmptyEmbed, + image: MaybeEmpty[str] = EmptyEmbed, + thumbnail: MaybeEmpty[str] = EmptyEmbed, ): self.colour = colour if colour is not EmptyEmbed else color self.title = title @@ -266,6 +330,18 @@ def __init__( self.timestamp = timestamp self._fields: list[EmbedField] = fields or [] + if author is not EmptyEmbed: + self.set_author(**author.__dict__) + + if footer is not EmptyEmbed: + self.set_footer(**footer.__dict__) + + if image is not EmptyEmbed: + self.set_image(url=image) + + if thumbnail is not EmptyEmbed: + self.set_thumbnail(url=thumbnail) + @classmethod def from_dict(cls: type[E], data: Mapping[str, Any]) -> E: """Converts a :class:`dict` to a :class:`Embed` provided it is in the @@ -426,14 +502,14 @@ def timestamp(self, value: MaybeEmpty[datetime.datetime]): ) @property - def footer(self) -> _EmbedFooterProxy: + def footer(self) -> EmbedFooter: """Returns an ``EmbedProxy`` denoting the footer contents. See :meth:`set_footer` for possible values you can access. If the attribute has no value then :attr:`Empty` is returned. """ - return EmbedProxy(getattr(self, "_footer", {})) # type: ignore + return EmbedFooter(**getattr(self, "_footer", {})) def set_footer( self: E, @@ -618,14 +694,14 @@ def provider(self) -> _EmbedProviderProxy: return EmbedProxy(getattr(self, "_provider", {})) # type: ignore @property - def author(self) -> _EmbedAuthorProxy: + def author(self) -> EmbedAuthor: """Returns an ``EmbedProxy`` denoting the author contents. See :meth:`set_author` for possible values you can access. If the attribute has no value then :attr:`Empty` is returned. """ - return EmbedProxy(getattr(self, "_author", {})) # type: ignore + return EmbedAuthor(**getattr(self, "_author", {})) # type: ignore def set_author( self: E, diff --git a/docs/api/data_classes.rst b/docs/api/data_classes.rst index 236aa64851..f05b38d646 100644 --- a/docs/api/data_classes.rst +++ b/docs/api/data_classes.rst @@ -72,6 +72,18 @@ Embed .. autoclass:: EmbedField :members: +.. attributetable:: EmbedAuthor + +.. autoclass:: EmbedAuthor + :members: + + +.. attributetable:: EmbedFooter + +.. autoclass:: EmbedFooter + :members: + + Flags -----