Browse Source

Allow discord.File in places where UnfurledMediaItem or str are allowed

auto/crowdin
Rapptz 13 hours ago
parent
commit
4854c56d58
  1. 24
      discord/components.py
  2. 8
      discord/file.py
  3. 25
      discord/ui/file.py
  4. 18
      discord/ui/media_gallery.py
  5. 26
      discord/ui/thumbnail.py

24
discord/components.py

@ -47,6 +47,7 @@ from .enums import (
) )
from .flags import AttachmentFlags from .flags import AttachmentFlags
from .colour import Colour from .colour import Colour
from .file import File
from .utils import get_slots, MISSING, _get_as_snowflake from .utils import get_slots, MISSING, _get_as_snowflake
from .partial_emoji import PartialEmoji, _EmojiTag from .partial_emoji import PartialEmoji, _EmojiTag
@ -1009,7 +1010,7 @@ class MediaGalleryItem:
Parameters Parameters
---------- ----------
media: Union[:class:`str`, :class:`UnfurledMediaItem`] media: Union[:class:`str`, :class:`discord.File`, :class:`UnfurledMediaItem`]
The media item data. This can be a string representing a local The media item data. This can be a string representing a local
file uploaded as an attachment in the message, which can be accessed file uploaded as an attachment in the message, which can be accessed
using the ``attachment://<filename>`` format, or an arbitrary url. using the ``attachment://<filename>`` format, or an arbitrary url.
@ -1029,14 +1030,21 @@ class MediaGalleryItem:
def __init__( def __init__(
self, self,
media: Union[str, UnfurledMediaItem], media: Union[str, File, UnfurledMediaItem],
*, *,
description: Optional[str] = None, description: Optional[str] = MISSING,
spoiler: bool = False, spoiler: bool = MISSING,
) -> None: ) -> None:
self.media = media self.media = media
self.description: Optional[str] = description
self.spoiler: bool = spoiler if isinstance(media, File):
if description is MISSING:
description = media.description
if spoiler is MISSING:
spoiler = media.spoiler
self.description: Optional[str] = None if description is MISSING else description
self.spoiler: bool = bool(spoiler)
self._state: Optional[ConnectionState] = None self._state: Optional[ConnectionState] = None
def __repr__(self) -> str: def __repr__(self) -> str:
@ -1048,11 +1056,13 @@ class MediaGalleryItem:
return self._media return self._media
@media.setter @media.setter
def media(self, value: Union[str, UnfurledMediaItem]) -> None: def media(self, value: Union[str, File, UnfurledMediaItem]) -> None:
if isinstance(value, str): if isinstance(value, str):
self._media = UnfurledMediaItem(value) self._media = UnfurledMediaItem(value)
elif isinstance(value, UnfurledMediaItem): elif isinstance(value, UnfurledMediaItem):
self._media = value self._media = value
elif isinstance(value, File):
self._media = UnfurledMediaItem(value.uri)
else: else:
raise TypeError(f'Expected a str or UnfurledMediaItem, not {value.__class__.__name__}') raise TypeError(f'Expected a str or UnfurledMediaItem, not {value.__class__.__name__}')

8
discord/file.py

@ -130,6 +130,14 @@ class File:
def filename(self, value: str) -> None: def filename(self, value: str) -> None:
self._filename, self.spoiler = _strip_spoiler(value) self._filename, self.spoiler = _strip_spoiler(value)
@property
def uri(self) -> str:
""":class:`str`: Returns the ``attachment://<filename>`` URI for this file.
.. versionadded:: 2.6
"""
return f'attachment://{self.filename}'
def reset(self, *, seek: Union[int, bool] = True) -> None: def reset(self, *, seek: Union[int, bool] = True) -> None:
# The `seek` parameter is needed because # The `seek` parameter is needed because
# the retry-loop is iterated over multiple times # the retry-loop is iterated over multiple times

25
discord/ui/file.py

@ -21,13 +21,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Literal, Optional, TypeVar, Union from typing import TYPE_CHECKING, Literal, Optional, TypeVar, Union
from .item import Item from .item import Item
from ..components import FileComponent, UnfurledMediaItem from ..components import FileComponent, UnfurledMediaItem
from ..enums import ComponentType from ..enums import ComponentType
from ..utils import MISSING
from ..file import File as SendableFile
if TYPE_CHECKING: if TYPE_CHECKING:
from typing_extensions import Self from typing_extensions import Self
@ -60,7 +64,7 @@ class File(Item[V]):
Parameters Parameters
---------- ----------
media: Union[:class:`str`, :class:`.UnfurledMediaItem`] media: Union[:class:`str`, :class:`.UnfurledMediaItem`, :class:`discord.File`]
This file's media. If this is a string it must point to a local This file's media. If this is a string it must point to a local
file uploaded within the parent view of this item, and must file uploaded within the parent view of this item, and must
meet the ``attachment://<filename>`` format. meet the ``attachment://<filename>`` format.
@ -78,15 +82,22 @@ class File(Item[V]):
def __init__( def __init__(
self, self,
media: Union[str, UnfurledMediaItem], media: Union[str, UnfurledMediaItem, SendableFile],
*, *,
spoiler: bool = False, spoiler: bool = MISSING,
id: Optional[int] = None, id: Optional[int] = None,
) -> None: ) -> None:
super().__init__() super().__init__()
if isinstance(media, SendableFile):
self._underlying = FileComponent._raw_construct(
media=UnfurledMediaItem(media.uri),
spoiler=media.spoiler if spoiler is MISSING else spoiler,
id=id,
)
else:
self._underlying = FileComponent._raw_construct( self._underlying = FileComponent._raw_construct(
media=UnfurledMediaItem(media) if isinstance(media, str) else media, media=UnfurledMediaItem(media) if isinstance(media, str) else media,
spoiler=spoiler, spoiler=bool(spoiler),
id=id, id=id,
) )
self.id = id self.id = id
@ -108,13 +119,15 @@ class File(Item[V]):
return self._underlying.media return self._underlying.media
@media.setter @media.setter
def media(self, value: Union[str, UnfurledMediaItem]) -> None: def media(self, value: Union[str, SendableFile, UnfurledMediaItem]) -> None:
if isinstance(value, str): if isinstance(value, str):
self._underlying.media = UnfurledMediaItem(value) self._underlying.media = UnfurledMediaItem(value)
elif isinstance(value, UnfurledMediaItem): elif isinstance(value, UnfurledMediaItem):
self._underlying.media = value self._underlying.media = value
elif isinstance(value, SendableFile):
self._underlying.media = UnfurledMediaItem(value.uri)
else: else:
raise TypeError(f'expected a str or UnfurledMediaItem, not {value.__class__.__name__!r}') raise TypeError(f'expected a str or UnfurledMediaItem or File, not {value.__class__.__name__!r}')
@property @property
def url(self) -> str: def url(self) -> str:

18
discord/ui/media_gallery.py

@ -27,6 +27,8 @@ from typing import TYPE_CHECKING, List, Literal, Optional, TypeVar, Union
from .item import Item from .item import Item
from ..enums import ComponentType from ..enums import ComponentType
from ..utils import MISSING
from ..file import File
from ..components import ( from ..components import (
MediaGalleryItem, MediaGalleryItem,
MediaGalleryComponent, MediaGalleryComponent,
@ -110,9 +112,9 @@ class MediaGallery(Item[V]):
def add_item( def add_item(
self, self,
*, *,
media: Union[str, UnfurledMediaItem], media: Union[str, File, UnfurledMediaItem],
description: Optional[str] = None, description: Optional[str] = MISSING,
spoiler: bool = False, spoiler: bool = MISSING,
) -> Self: ) -> Self:
"""Adds an item to this gallery. """Adds an item to this gallery.
@ -121,7 +123,7 @@ class MediaGallery(Item[V]):
Parameters Parameters
---------- ----------
media: Union[:class:`str`, :class:`.UnfurledMediaItem`] media: Union[:class:`str`, :class:`discord.File`, :class:`.UnfurledMediaItem`]
The media item data. This can be a string representing a local The media item data. This can be a string representing a local
file uploaded as an attachment in the message, which can be accessed file uploaded as an attachment in the message, which can be accessed
using the ``attachment://<filename>`` format, or an arbitrary url. using the ``attachment://<filename>`` format, or an arbitrary url.
@ -176,9 +178,9 @@ class MediaGallery(Item[V]):
self, self,
index: int, index: int,
*, *,
media: Union[str, UnfurledMediaItem], media: Union[str, File, UnfurledMediaItem],
description: Optional[str] = None, description: Optional[str] = MISSING,
spoiler: bool = False, spoiler: bool = MISSING,
) -> Self: ) -> Self:
"""Inserts an item before a specified index to the media gallery. """Inserts an item before a specified index to the media gallery.
@ -189,7 +191,7 @@ class MediaGallery(Item[V]):
---------- ----------
index: :class:`int` index: :class:`int`
The index of where to insert the field. The index of where to insert the field.
media: Union[:class:`str`, :class:`.UnfurledMediaItem`] media: Union[:class:`str`, :class:`discord.File`, :class:`.UnfurledMediaItem`]
The media item data. This can be a string representing a local The media item data. This can be a string representing a local
file uploaded as an attachment in the message, which can be accessed file uploaded as an attachment in the message, which can be accessed
using the ``attachment://<filename>`` format, or an arbitrary url. using the ``attachment://<filename>`` format, or an arbitrary url.

26
discord/ui/thumbnail.py

@ -21,6 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, TypeVar, Union from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, TypeVar, Union
@ -28,6 +29,8 @@ from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, TypeVar, Union
from .item import Item from .item import Item
from ..enums import ComponentType from ..enums import ComponentType
from ..components import UnfurledMediaItem from ..components import UnfurledMediaItem
from ..file import File
from ..utils import MISSING
if TYPE_CHECKING: if TYPE_CHECKING:
from typing_extensions import Self from typing_extensions import Self
@ -47,7 +50,7 @@ class Thumbnail(Item[V]):
Parameters Parameters
---------- ----------
media: Union[:class:`str`, :class:`discord.UnfurledMediaItem`] media: Union[:class:`str`, :class:`discord.File`, :class:`discord.UnfurledMediaItem`]
The media of the thumbnail. This can be a URL or a reference The media of the thumbnail. This can be a URL or a reference
to an attachment that matches the ``attachment://filename.extension`` to an attachment that matches the ``attachment://filename.extension``
structure. structure.
@ -74,16 +77,23 @@ class Thumbnail(Item[V]):
def __init__( def __init__(
self, self,
media: Union[str, UnfurledMediaItem], media: Union[str, File, UnfurledMediaItem],
*, *,
description: Optional[str] = None, description: Optional[str] = MISSING,
spoiler: bool = False, spoiler: bool = MISSING,
id: Optional[int] = None, id: Optional[int] = None,
) -> None: ) -> None:
super().__init__() super().__init__()
if isinstance(media, File):
description = description if description is not MISSING else media.description
spoiler = spoiler if spoiler is not MISSING else media.spoiler
media = media.uri
self._media: UnfurledMediaItem = UnfurledMediaItem(media) if isinstance(media, str) else media self._media: UnfurledMediaItem = UnfurledMediaItem(media) if isinstance(media, str) else media
self.description: Optional[str] = description self.description: Optional[str] = None if description is MISSING else description
self.spoiler: bool = spoiler self.spoiler: bool = bool(spoiler)
self.id = id self.id = id
@property @property
@ -96,11 +106,13 @@ class Thumbnail(Item[V]):
return self._media return self._media
@media.setter @media.setter
def media(self, value: Union[str, UnfurledMediaItem]) -> None: def media(self, value: Union[str, File, UnfurledMediaItem]) -> None:
if isinstance(value, str): if isinstance(value, str):
self._media = UnfurledMediaItem(value) self._media = UnfurledMediaItem(value)
elif isinstance(value, UnfurledMediaItem): elif isinstance(value, UnfurledMediaItem):
self._media = value self._media = value
elif isinstance(value, File):
self._media = UnfurledMediaItem(value.uri)
else: else:
raise TypeError(f'expected a str or UnfurledMediaItem, not {value.__class__.__name__!r}') raise TypeError(f'expected a str or UnfurledMediaItem, not {value.__class__.__name__!r}')

Loading…
Cancel
Save