From 8a95c0190c9e8dee81c7c0a6bf85e8eb4a834f82 Mon Sep 17 00:00:00 2001 From: DA344 <108473820+DA-344@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:42:17 +0100 Subject: [PATCH] Add support for embed flags and update attachment flags Co-authored-by: Danny <1695103+Rapptz@users.noreply.github.com> --- discord/embeds.py | 19 ++++++++- discord/flags.py | 89 ++++++++++++++++++++++++++++++++++++++++++ discord/types/embed.py | 2 + docs/api.rst | 8 ++++ 4 files changed, 117 insertions(+), 1 deletion(-) diff --git a/discord/embeds.py b/discord/embeds.py index efa6537db..4be644688 100644 --- a/discord/embeds.py +++ b/discord/embeds.py @@ -29,6 +29,7 @@ from typing import Any, Dict, List, Mapping, Optional, Protocol, TYPE_CHECKING, from . import utils from .colour import Colour +from .flags import AttachmentFlags, EmbedFlags # fmt: off __all__ = ( @@ -76,6 +77,7 @@ if TYPE_CHECKING: proxy_url: Optional[str] height: Optional[int] width: Optional[int] + flags: Optional[AttachmentFlags] class _EmbedVideoProxy(Protocol): url: Optional[str] @@ -146,6 +148,10 @@ class Embed: colour: Optional[Union[:class:`Colour`, :class:`int`]] The colour code of the embed. Aliased to ``color`` as well. This can be set during initialisation. + flags: Optional[:class:`EmbedFlags`] + The flags of this embed. + + .. versionadded:: 2.5 """ __slots__ = ( @@ -162,6 +168,7 @@ class Embed: '_author', '_fields', 'description', + 'flags', ) def __init__( @@ -181,6 +188,7 @@ class Embed: self.type: EmbedType = type self.url: Optional[str] = url self.description: Optional[str] = description + self.flags: Optional[EmbedFlags] = None if self.title is not None: self.title = str(self.title) @@ -245,6 +253,11 @@ class Embed: else: setattr(self, '_' + attr, value) + try: + self.flags = EmbedFlags._from_value(data['flags']) + except KeyError: + pass + return self def copy(self) -> Self: @@ -399,11 +412,15 @@ class Embed: - ``proxy_url`` - ``width`` - ``height`` + - ``flags`` If the attribute has no value then ``None`` is returned. """ # Lying to the type checker for better developer UX. - return EmbedProxy(getattr(self, '_image', {})) # type: ignore + data = getattr(self, '_image', {}) + if 'flags' in data: + data['flags'] = AttachmentFlags._from_value(data['flags']) + return EmbedProxy(data) # type: ignore def set_image(self, *, url: Optional[Any]) -> Self: """Sets the image for the embed content. diff --git a/discord/flags.py b/discord/flags.py index de806ba9c..20f8c5470 100644 --- a/discord/flags.py +++ b/discord/flags.py @@ -63,6 +63,7 @@ __all__ = ( 'RoleFlags', 'AppInstallationType', 'SKUFlags', + 'EmbedFlags', ) BF = TypeVar('BF', bound='BaseFlags') @@ -2173,6 +2174,30 @@ class AttachmentFlags(BaseFlags): """:class:`bool`: Returns ``True`` if the attachment has been edited using the remix feature.""" return 1 << 2 + @flag_value + def spoiler(self): + """:class:`bool`: Returns ``True`` if the attachment was marked as a spoiler. + + .. versionadded:: 2.5 + """ + return 1 << 3 + + @flag_value + def contains_explicit_media(self): + """:class:`bool`: Returns ``True`` if the attachment was flagged as sensitive content. + + .. versionadded:: 2.5 + """ + return 1 << 4 + + @flag_value + def animated(self): + """:class:`bool`: Returns ``True`` if the attachment is an animated image. + + .. versionadded:: 2.5 + """ + return 1 << 5 + @fill_with_flags() class RoleFlags(BaseFlags): @@ -2308,3 +2333,67 @@ class SKUFlags(BaseFlags): def user_subscription(self): """:class:`bool`: Returns ``True`` if the SKU is a user subscription.""" return 1 << 8 + + +@fill_with_flags() +class EmbedFlags(BaseFlags): + r"""Wraps up the Discord Embed flags + + .. versionadded:: 2.5 + + .. container:: operations + + .. describe:: x == y + + Checks if two EmbedFlags are equal. + + .. describe:: x != y + + Checks if two EmbedFlags are not equal. + + .. describe:: x | y, x |= y + + Returns an EmbedFlags instance with all enabled flags from + both x and y. + + .. describe:: x ^ y, x ^= y + + Returns an EmbedFlags instance with only flags enabled on + only one of x or y, not on both. + + .. describe:: ~x + + Returns an EmbedFlags instance with all flags inverted from x. + + .. describe:: hash(x) + + Returns the flag's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(name, value)`` pairs. This allows it + to be, for example, constructed as a dict or a list of pairs. + Note that aliases are not shown. + + .. describe:: bool(b) + + Returns whether any flag is set to ``True``. + + Attributes + ---------- + value: :class:`int` + The raw value. You should query flags via the properties + rather than using this raw value. + """ + + @flag_value + def contains_explicit_media(self): + """:class:`bool`: Returns ``True`` if the embed was flagged as sensitive content.""" + return 1 << 4 + + @flag_value + def content_inventory_entry(self): + """:class:`bool`: Returns ``True`` if the embed is a reply to an activity card, and is no + longer displayed. + """ + return 1 << 5 diff --git a/discord/types/embed.py b/discord/types/embed.py index 376df3a1a..f8354a3f3 100644 --- a/discord/types/embed.py +++ b/discord/types/embed.py @@ -50,6 +50,7 @@ class EmbedVideo(TypedDict, total=False): proxy_url: str height: int width: int + flags: int class EmbedImage(TypedDict, total=False): @@ -88,3 +89,4 @@ class Embed(TypedDict, total=False): provider: EmbedProvider author: EmbedAuthor fields: List[EmbedField] + flags: int diff --git a/docs/api.rst b/docs/api.rst index 8da2ba80c..0b2edcd3d 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -5708,6 +5708,14 @@ SKUFlags .. autoclass:: SKUFlags() :members: +EmbedFlags +~~~~~~~~~~ + +.. attributetable:: EmbedFlags + +.. autoclass:: EmbedFlags() + :members: + ForumTag ~~~~~~~~~