Skip to content

Commit

Permalink
Cleanup of deserializing media and handling of the media object(s)
Browse files Browse the repository at this point in the history
  • Loading branch information
mplatypus committed Mar 9, 2025
1 parent 04f5fa1 commit 2c1272c
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 23 deletions.
31 changes: 17 additions & 14 deletions hikari/api/special_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2258,10 +2258,6 @@ def add_text_menu(
"""


MessageActionRowBuilderComponentsT = typing.Union[ButtonBuilder, SelectMenuBuilder]
"""FIXME: Document me."""


class MessageMediaResourceBuilder(abc.ABC):
"""Builder class for media items."""

Expand Down Expand Up @@ -2699,16 +2695,6 @@ def add_file(
"""


MessageContainerBuilderComponentsT = typing.Union[ # FIXME: I got no idea where this should be put.
MessageActionRowBuilder,
MessageTextDisplayBuilder,
MessageSectionBuilder,
MessageMediaGalleryBuilder,
MessageSeparatorBuilder,
MessageFileBuilder,
]


class ModalActionRowBuilder(ComponentBuilder, abc.ABC):
"""Builder class for modal action row components."""

Expand Down Expand Up @@ -2789,3 +2775,20 @@ def add_text_input(
ModalActionRowBuilder
The modal action row builder to enable call chaining.
"""


MessageContainerBuilderComponentsT = typing.Union[ # FIXME: I got no idea where this should be put.
MessageActionRowBuilder,
MessageTextDisplayBuilder,
MessageSectionBuilder,
MessageMediaGalleryBuilder,
MessageSeparatorBuilder,
MessageFileBuilder,
]
"""FIXME: Document me."""


MessageActionRowBuilderComponentsT = typing.Union[ # FIXME: I got no idea where this should be put.
ButtonBuilder, SelectMenuBuilder
]
"""FIXME: Document me."""
8 changes: 4 additions & 4 deletions hikari/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,16 +413,16 @@ class MediaResource(files.Resource[files.AsyncReader]):
populated on any received embed attached to a message event.
"""

width: int = attrs.field(repr=True)
width: undefined.UndefinedNoneOr[int] = attrs.field(repr=True)
"""The width of media item."""

height: int = attrs.field(repr=True)
height: undefined.UndefinedNoneOr[int] = attrs.field(repr=True)
"""The height of the media item."""

content_type: str = attrs.field(repr=True)
content_type: undefined.UndefinedNoneOr[str] = attrs.field(repr=True)
"""The content type of the media item."""

loading_state: MediaLoadingType = attrs.field(repr=True)
loading_state: undefined.UndefinedNoneOr[MediaLoadingType] = attrs.field(repr=True)
"""The loading state of the media item."""

@property
Expand Down
31 changes: 26 additions & 5 deletions hikari/impl/entity_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -3083,13 +3083,32 @@ def _deserialize_text_input(self, payload: data_binding.JSONObject) -> component
)

def _deserialize_media(self, payload: data_binding.JSONObject) -> component_models.MediaResource:
height: undefined.UndefinedNoneOr[int] = undefined.UNDEFINED
if "height" in payload:
height = payload.get("height")

width: undefined.UndefinedNoneOr[int] = undefined.UNDEFINED
if "width" in payload:
width = payload.get("width")

content_type: undefined.UndefinedNoneOr[str] = undefined.UNDEFINED
if "content_type" in payload:
content_type = payload.get("content_type")

loading_state: undefined.UndefinedNoneOr[component_models.MediaLoadingType] = undefined.UNDEFINED
if "loading_state" in payload:
if state := payload.get("loading_state"):
loading_state = component_models.MediaLoadingType(state)
else:
loading_state = None

return component_models.MediaResource(
resource=files.ensure_resource(payload["url"]), # FIXME: Idk if this is how its supposed to work.
proxy_resource=files.ensure_resource(payload["proxy_url"]),
height=payload["height"],
width=payload["width"],
content_type=payload["content_type"],
loading_state=component_models.MediaLoadingType(payload["loading_state"]),
proxy_resource=files.ensure_resource(payload["proxy_url"]) if "proxy_url" in payload else None,
height=height,
width=width,
content_type=content_type,
loading_state=loading_state,
)

def _deserialize_action_row_component(
Expand All @@ -3113,6 +3132,8 @@ def _deserialize_action_row_component(
type=component_models.ComponentType.ACTION_ROW, id=payload.get("id"), components=components
)

return None

def _deserialize_section_component(self, payload: data_binding.JSONObject) -> component_models.SectionComponent:
accessory_payload = payload["accessory"]

Expand Down
28 changes: 28 additions & 0 deletions tests/hikari/impl/test_entity_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5719,6 +5719,34 @@ def test__deserialize_media(self, entity_factory_impl, media_payload):

assert isinstance(media, component_models.MediaResource)

def test__deserialize_media_with_unset_fields(self, entity_factory_impl, media_payload):
del media_payload["proxy_url"]
del media_payload["width"]
del media_payload["height"]
del media_payload["content_type"]

media = entity_factory_impl._deserialize_media(media_payload)

assert media.proxy_url is None
assert media.width is undefined.UNDEFINED
assert media.height is undefined.UNDEFINED
assert media.content_type is undefined.UNDEFINED

assert isinstance(media, component_models.MediaResource)

def test__deserialize_media_with_nullable_fields(self, entity_factory_impl, media_payload):
media_payload["width"] = None
media_payload["height"] = None
media_payload["content_type"] = None

media = entity_factory_impl._deserialize_media(media_payload)

assert media.width is None
assert media.height is None
assert media.content_type is None

assert isinstance(media, component_models.MediaResource)

def test__deserialize_action_row_component(self, entity_factory_impl, action_row_payload, button_payload):
action_row = entity_factory_impl._deserialize_action_row_component(action_row_payload)

Expand Down

0 comments on commit 2c1272c

Please sign in to comment.