4 Commits

7 changed files with 65 additions and 73 deletions

View File

@ -245,15 +245,6 @@ class Asset(AssetMixin):
animated=animated, animated=animated,
) )
@classmethod
def _from_role_icon(cls, state, role_id: int, role_hash: str) -> Asset:
return cls(
state,
url=f"{cls.BASE}/role-icons/{role_id}/{role_hash}.png",
key=role_hash,
animated=False,
)
def __str__(self) -> str: def __str__(self) -> str:
return self._url return self._url

View File

@ -465,7 +465,6 @@ class Context(discord.abc.Messageable, Generic[BotT]):
kwargs.pop("nonce", None) kwargs.pop("nonce", None)
kwargs.pop("stickers", None) kwargs.pop("stickers", None)
kwargs.pop("reference", None) kwargs.pop("reference", None)
kwargs.pop("delete_after", None)
kwargs.pop("mention_author", None) kwargs.pop("mention_author", None)
if not ( if not (

View File

@ -2448,8 +2448,6 @@ class Guild(Hashable):
colour: Union[Colour, int] = ..., colour: Union[Colour, int] = ...,
hoist: bool = ..., hoist: bool = ...,
mentionable: bool = ..., mentionable: bool = ...,
icon: bytes = ...,
emoji: str = ...,
) -> Role: ) -> Role:
... ...
@ -2463,8 +2461,6 @@ class Guild(Hashable):
color: Union[Colour, int] = ..., color: Union[Colour, int] = ...,
hoist: bool = ..., hoist: bool = ...,
mentionable: bool = ..., mentionable: bool = ...,
icon: bytes = ...,
emoji: str = ...,
) -> Role: ) -> Role:
... ...
@ -2477,8 +2473,6 @@ class Guild(Hashable):
colour: Union[Colour, int] = MISSING, colour: Union[Colour, int] = MISSING,
hoist: bool = MISSING, hoist: bool = MISSING,
mentionable: bool = MISSING, mentionable: bool = MISSING,
icon: bytes = MISSING,
emoji: str = MISSING,
reason: Optional[str] = None, reason: Optional[str] = None,
) -> Role: ) -> Role:
"""|coro| """|coro|
@ -2508,10 +2502,6 @@ class Guild(Hashable):
mentionable: :class:`bool` mentionable: :class:`bool`
Indicates if the role should be mentionable by others. Indicates if the role should be mentionable by others.
Defaults to ``False``. Defaults to ``False``.
emoji: :class:`str`
The unicode emoji that is shown next to users with the role.
icon: :class:`bytes`
A custom image that is shown next to users with the role.
reason: Optional[:class:`str`] reason: Optional[:class:`str`]
The reason for creating this role. Shows up on the audit log. The reason for creating this role. Shows up on the audit log.
@ -2550,12 +2540,6 @@ class Guild(Hashable):
if name is not MISSING: if name is not MISSING:
fields["name"] = name fields["name"] = name
if emoji is not MISSING:
fields["unicode_emoji"] = emoji
if icon is not MISSING:
fields["icon"] = utils._bytes_to_base64_data(icon)
data = await self._state.http.create_role(self.id, reason=reason, **fields) data = await self._state.http.create_role(self.id, reason=reason, **fields)
role = Role(guild=self, data=data, state=self._state) role = Role(guild=self, data=data, state=self._state)

View File

@ -337,7 +337,7 @@ class Interaction:
self._state.store_view(view, message.id) self._state.store_view(view, message.id)
return message return message
async def delete_original_message(self) -> None: async def delete_original_message(self, delay: Optional[float] = None) -> None:
"""|coro| """|coro|
Deletes the original interaction response message. Deletes the original interaction response message.
@ -345,6 +345,14 @@ class Interaction:
This is a lower level interface to :meth:`InteractionMessage.delete` in case This is a lower level interface to :meth:`InteractionMessage.delete` in case
you do not want to fetch the message and save an HTTP request. you do not want to fetch the message and save an HTTP request.
Parameters
------------
delay: Optional[:class:`float`]
If provided, the number of seconds to wait before deleting the message.
The waiting is done in the background and deletion failures are ignored.
.. versionadded:: 2.0
Raises Raises
------- -------
HTTPException HTTPException
@ -352,6 +360,8 @@ class Interaction:
Forbidden Forbidden
Deleted a message that is not yours. Deleted a message that is not yours.
""" """
if delay is not None:
await asyncio.sleep(delay)
adapter = async_context.get() adapter = async_context.get()
await adapter.delete_original_interaction_response( await adapter.delete_original_interaction_response(
self.application_id, self.application_id,
@ -460,6 +470,7 @@ class InteractionResponse:
view: View = MISSING, view: View = MISSING,
tts: bool = False, tts: bool = False,
ephemeral: bool = False, ephemeral: bool = False,
delete_after: Optional[float] = None,
) -> None: ) -> None:
"""|coro| """|coro|
@ -483,6 +494,9 @@ class InteractionResponse:
Indicates if the message should only be visible to the user who started the interaction. Indicates if the message should only be visible to the user who started the interaction.
If a view is sent with an ephemeral message and it has no timeout set then the timeout If a view is sent with an ephemeral message and it has no timeout set then the timeout
is set to 15 minutes. is set to 15 minutes.
delete_after: Optional[:class:`float`]
The amount of seconds the bot should wait before deleting the message sent.
.. versionadded:: 2.0
Raises Raises
------- -------
@ -539,6 +553,8 @@ class InteractionResponse:
self._parent._state.store_view(view) self._parent._state.store_view(view)
self.responded_at = utils.utcnow() self.responded_at = utils.utcnow()
if delete_after is not None:
self._parent.delete_original_message(delay=delete_after)
async def edit_message( async def edit_message(
self, self,
@ -733,7 +749,7 @@ class InteractionMessage(Message):
allowed_mentions=allowed_mentions, allowed_mentions=allowed_mentions,
) )
async def delete(self, *, delay: Optional[float] = None) -> None: async def delete(self, *, delay: Optional[float] = None, silent: bool = False) -> None:
"""|coro| """|coro|
Deletes the message. Deletes the message.
@ -743,6 +759,12 @@ class InteractionMessage(Message):
delay: Optional[:class:`float`] delay: Optional[:class:`float`]
If provided, the number of seconds to wait before deleting the message. If provided, the number of seconds to wait before deleting the message.
The waiting is done in the background and deletion failures are ignored. The waiting is done in the background and deletion failures are ignored.
silent: :class:`bool`
If silent is set to ``True``, the error will not be raised, it will be ignored.
This defaults to ``False`
.. versionadded:: 2.0
Raises Raises
------ ------
@ -757,12 +779,15 @@ class InteractionMessage(Message):
if delay is not None: if delay is not None:
async def inner_call(delay: float = delay): async def inner_call(delay: float = delay):
await asyncio.sleep(delay)
try: try:
await self._state._interaction.delete_original_message() await self._state._interaction.delete_original_message(delay=delay)
except HTTPException: except HTTPException:
pass pass
asyncio.create_task(inner_call()) asyncio.create_task(inner_call())
else: else:
await self._state._interaction.delete_original_message() try:
await self._state._interaction.delete_original_message(delay=delay)
except Exception:
if not silent:
raise

View File

@ -23,14 +23,13 @@ DEALINGS IN THE SOFTWARE.
""" """
from __future__ import annotations from __future__ import annotations
from typing import Any, Dict, List, Optional, TypeVar, Union, TYPE_CHECKING from typing import Any, Dict, List, Optional, TypeVar, Union, overload, TYPE_CHECKING
from .asset import Asset
from .permissions import Permissions from .permissions import Permissions
from .errors import InvalidArgument from .errors import InvalidArgument
from .colour import Colour from .colour import Colour
from .mixins import Hashable from .mixins import Hashable
from .utils import snowflake_time, _get_as_snowflake, MISSING, _bytes_to_base64_data from .utils import snowflake_time, _get_as_snowflake, MISSING
__all__ = ( __all__ = (
"RoleTags", "RoleTags",
@ -159,15 +158,7 @@ class Role(Hashable):
guild: :class:`Guild` guild: :class:`Guild`
The guild the role belongs to. The guild the role belongs to.
hoist: :class:`bool` hoist: :class:`bool`
Indicates if the role will be displayed separately from other members. Indicates if the role will be displayed separately from other members.
icon: Optional[:class:`Asset`]
A custom image that is shown next to users with the role.
.. versionadded:: 2.0
emoji: Optional[:class:`str`]
The unicode emoji that is shown next to users with the role.
.. versionadded:: 2.0
position: :class:`int` position: :class:`int`
The position of the role. This number is usually positive. The bottom The position of the role. This number is usually positive. The bottom
role has a position of 0. role has a position of 0.
@ -200,8 +191,6 @@ class Role(Hashable):
"hoist", "hoist",
"guild", "guild",
"tags", "tags",
"_icon",
"emoji",
"_state", "_state",
) )
@ -262,8 +251,6 @@ class Role(Hashable):
self.position: int = data.get("position", 0) self.position: int = data.get("position", 0)
self._colour: int = data.get("color", 0) self._colour: int = data.get("color", 0)
self.hoist: bool = data.get("hoist", False) self.hoist: bool = data.get("hoist", False)
self.emoji: Optional[str] = data.get("unicode_emoji")
self._icon: Optional[str] = data.get("icon")
self.managed: bool = data.get("managed", False) self.managed: bool = data.get("managed", False)
self.mentionable: bool = data.get("mentionable", False) self.mentionable: bool = data.get("mentionable", False)
self.tags: Optional[RoleTags] self.tags: Optional[RoleTags]
@ -331,13 +318,6 @@ class Role(Hashable):
""":class:`str`: Returns a string that allows you to mention a role.""" """:class:`str`: Returns a string that allows you to mention a role."""
return f"<@&{self.id}>" return f"<@&{self.id}>"
@property
def icon(self) -> Optional[Asset]:
"""Optional[:class:`Asset`]: Returns the custom icon shown next to users with the role, if it exists."""
if self._icon is None:
return
return Asset._from_role_icon(self._state, self.id, self._icon)
@property @property
def members(self) -> List[Member]: def members(self) -> List[Member]:
"""List[:class:`Member`]: Returns all the members with this role.""" """List[:class:`Member`]: Returns all the members with this role."""
@ -381,8 +361,6 @@ class Role(Hashable):
hoist: bool = MISSING, hoist: bool = MISSING,
mentionable: bool = MISSING, mentionable: bool = MISSING,
position: int = MISSING, position: int = MISSING,
icon: bytes = MISSING,
emoji: str = MISSING,
reason: Optional[str] = MISSING, reason: Optional[str] = MISSING,
) -> Optional[Role]: ) -> Optional[Role]:
"""|coro| """|coro|
@ -415,10 +393,6 @@ class Role(Hashable):
position: :class:`int` position: :class:`int`
The new role's position. This must be below your top role's The new role's position. This must be below your top role's
position or it will fail. position or it will fail.
emoji: :class:`str`
The unicode emoji that is shown next to users with the role.
icon: :class:`bytes`
A custom image that is shown next to users with the role.
reason: Optional[:class:`str`] reason: Optional[:class:`str`]
The reason for editing this role. Shows up on the audit log. The reason for editing this role. Shows up on the audit log.
@ -462,12 +436,6 @@ class Role(Hashable):
if mentionable is not MISSING: if mentionable is not MISSING:
payload["mentionable"] = mentionable payload["mentionable"] = mentionable
if emoji is not MISSING:
payload["unicode_emoji"] = emoji
if icon is not MISSING:
payload["icon"] = _bytes_to_base64_data(icon)
data = await self._state.http.edit_role(self.guild.id, self.id, reason=reason, **payload) data = await self._state.http.edit_role(self.guild.id, self.id, reason=reason, **payload)
return Role(guild=self.guild, data=data, state=self._state) return Role(guild=self.guild, data=data, state=self._state)

View File

@ -29,9 +29,7 @@ from .snowflake import Snowflake
class _RoleOptional(TypedDict, total=False): class _RoleOptional(TypedDict, total=False):
icon: str
tags: RoleTags tags: RoleTags
unicode_emoji: str
class Role(_RoleOptional): class Role(_RoleOptional):

View File

@ -717,7 +717,7 @@ class WebhookMessage(Message):
allowed_mentions=allowed_mentions, allowed_mentions=allowed_mentions,
) )
async def delete(self, *, delay: Optional[float] = None) -> None: async def delete(self, *, delay: Optional[float] = None, silent: bool = False) -> None:
"""|coro| """|coro|
Deletes the message. Deletes the message.
@ -727,6 +727,12 @@ class WebhookMessage(Message):
delay: Optional[:class:`float`] delay: Optional[:class:`float`]
If provided, the number of seconds to wait before deleting the message. If provided, the number of seconds to wait before deleting the message.
The waiting is done in the background and deletion failures are ignored. The waiting is done in the background and deletion failures are ignored.
silent: :class:`bool`
If silent is set to ``True``, the error will not be raised, it will be ignored.
This defaults to ``False`
.. versionadded:: 2.0
Raises Raises
------ ------
@ -741,15 +747,18 @@ class WebhookMessage(Message):
if delay is not None: if delay is not None:
async def inner_call(delay: float = delay): async def inner_call(delay: float = delay):
await asyncio.sleep(delay)
try: try:
await self._state._webhook.delete_message(self.id) await self._state._webhook.delete_message(self.id, delay)
except HTTPException: except HTTPException:
pass pass
asyncio.create_task(inner_call()) asyncio.create_task(inner_call())
else: else:
await self._state._webhook.delete_message(self.id) try:
await self._state._webhook.delete_message(self.id, delay)
except Exception:
if not silent:
raise
class BaseWebhook(Hashable): class BaseWebhook(Hashable):
@ -1270,6 +1279,7 @@ class Webhook(BaseWebhook):
view: View = MISSING, view: View = MISSING,
thread: Snowflake = MISSING, thread: Snowflake = MISSING,
wait: bool = False, wait: bool = False,
delete_after: Optional[float] = None,
) -> Optional[WebhookMessage]: ) -> Optional[WebhookMessage]:
"""|coro| """|coro|
@ -1335,6 +1345,11 @@ class Webhook(BaseWebhook):
The thread to send this webhook to. The thread to send this webhook to.
.. versionadded:: 2.0 .. versionadded:: 2.0
delete_after: Optional[:class:`float`]
If provided, the number of seconds to wait before deleting the message.
The waiting is done in the background and deletion failures are ignored.
.. versionadded:: 2.0
Raises Raises
-------- --------
@ -1416,6 +1431,9 @@ class Webhook(BaseWebhook):
if view is not MISSING and not view.is_finished(): if view is not MISSING and not view.is_finished():
message_id = None if msg is None else msg.id message_id = None if msg is None else msg.id
self._state.store_view(view, message_id) self._state.store_view(view, message_id)
if delete_after is not None and msg is not None:
await msg.delete(delay=delete_after)
return msg return msg
@ -1570,7 +1588,7 @@ class Webhook(BaseWebhook):
self._state.store_view(view, message_id) self._state.store_view(view, message_id)
return message return message
async def delete_message(self, message_id: int, /) -> None: async def delete_message(self, message_id: int, delay: Optional[float] = None, /) -> None:
"""|coro| """|coro|
Deletes a message owned by this webhook. Deletes a message owned by this webhook.
@ -1584,6 +1602,12 @@ class Webhook(BaseWebhook):
------------ ------------
message_id: :class:`int` message_id: :class:`int`
The message ID to delete. The message ID to delete.
delay: Optional[:class:`float`]
If provided, the number of seconds to wait before deleting the message.
The waiting is done in the background and deletion failures are ignored.
.. versionadded:: 2.0
Raises Raises
------- -------
@ -1595,6 +1619,9 @@ class Webhook(BaseWebhook):
if self.token is None: if self.token is None:
raise InvalidArgument("This webhook does not have a token associated with it") raise InvalidArgument("This webhook does not have a token associated with it")
if delay is not None:
await asyncio.sleep(delay)
adapter = async_context.get() adapter = async_context.get()
await adapter.delete_webhook_message( await adapter.delete_webhook_message(
self.id, self.id,