Diff
checker
文本
文本
图像
文档
Excel
文件夹
Legal
Enterprise
桌面版
定价
登录
下载 Diffchecker 桌面版
比较文本
查找两个文本文件之间的差异
工具
历史
显示
视图
拆分
统一
实时编辑器
隐藏空白更改
折叠未更改行
关闭换行
比对精度
智能
语法
无
更改外观
处理
忽略
文本转换
转到第一个差异
编辑输入
Diffchecker Desktop
运行Diffchecker最安全的方式。获取Diffchecker桌面应用:您的差异永远不会离开您的电脑!
获取桌面版
stuff
创建于
2年前
差异永不过期
清除
导出
分享
解释
268 删除
行
总计
删除
字符
总计
删除
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
526 行
全部复制
147 添加
行
总计
添加
字符
总计
添加
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
404 行
全部复制
复制
已复制
复制
已复制
diff --git a/
discord
/client.py b/
discord
/client.py
diff --git a/
disnake
/client.py b/
disnake
/client.py
--- a/
discord
/client.py
--- a/
disnake
/client.py
+++ b/
discord
/client.py
+++ b/
disnake
/client.py
-from .emoji import Emoji
-from .emoji import Emoji
复制
已复制
复制
已复制
+from .emoji import App
Emoji, GuildEmoji
+from .emoji import App
lication
Emoji, GuildEmoji
+
cache_app_emojis:
:class:`
bool
`
+
cache_app_emojis:
bool
= False,
+ Whether to automatically fetch and cache the application's emojis on startup and when fetching. Defaults to ``False``.
+
cache_app_
emojis
=cache_app_emojis,
+
+
cache
_app_emojis: bool,
+ .. warning::
+
cache_app
_emojis
=cache_app_emojis,
+
- def emojis(self) ->
L
ist[Emoji]:
+
There are no events related to application
emojis
- if any are created/deleted on the
- """
List[:class:`.Emoji`]:
The emojis that the connected client has."""
+
Developer Dashboard while the client is running, the
cache
will not be updated until you manually
+ def emojis(self) ->
L
ist[
Union[
GuildEmoji
,
App
lication
Emoji]
]
:
+
run :func:`fetch
_emojis
`.
+
+ .. versionadded:: 2.7
- def emojis(self) ->
l
ist[Emoji]:
- """
The emojis that the connected client has."""
+ def emojis(self) ->
l
ist[
GuildEmoji
|
App
Emoji]
:
+ """The emojis that the connected client has.
+ """The emojis that the connected client has.
+
+
+ .. note::
+ .. note::
复制
已复制
复制
已复制
+
+ This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is
+ This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is
``True``.
+
``True``.
+ """
+ """
复制
已复制
复制
已复制
- def get_emoji(self, id: int, /) ->
Emoji
| None
:
- def get_emoji(self, id: int, /) ->
Optional[
Emoji
]
:
+ def get_emoji(self, id: int, /) ->
GuildEmoji | AppEmoji | None:
+ def get_emoji(self, id: int, /) ->
Optional[
Union[
GuildEmoji
,
App
lication
Emoji
]]:
-
Optional[
:class:`.Emoji`]
+ Optional[:class:`.
GuildEmoji
` | :class:`.
App
Emoji
`]
+
+
复制
已复制
复制
已复制
+ async def fetch_
emojis(self) -> list[App
Emoji]:
+ async def fetch_
application_
emojis(self) -> list[App
lication
Emoji]:
+ r"""|coro|
+ r"""|coro|
复制
已复制
复制
已复制
+
+ Retrieves all custom :class:`App
lication
Emoji`\s from the application.
+ Retrieves all custom :class:`App
Emoji`\s from the application.
+
+
+ Raises
+ Raises
复制
已复制
复制
已复制
+ ------
---
+ ------
+ HTTPException
+ HTTPException
+ An error occurred fetching the emojis.
+ An error occurred fetching the emojis.
+
+
+ Returns
+ Returns
复制
已复制
复制
已复制
+ -------
-
+ -------
+ List[:class:`App
Emoji`]
+ List[:class:`App
lication
Emoji`]
+ The retrieved emojis.
+ The retrieved emojis.
+ """
+ """
复制
已复制
复制
已复制
+ data = await self._
state
.http.get_all_application_emojis(self.application_id)
+ data = await self._
connection
.http.get_all_application_emojis(self.application_id)
+ return [
+ return [
复制
已复制
复制
已复制
+ self._
state.maybe_
store_
app
_emoji(self.application_id, d)
+ self._
connection.
store_
application
_emoji(self.application_id, d)
for d in data["items"]
+
for d in data["items"]
+ ]
+ ]
+
+
复制
已复制
复制
已复制
+ async def fetch_
emoji(self, emoji_id: int, /) -> App
Emoji:
+ async def fetch_
application_
emoji(self, emoji_id: int, /) -> App
lication
Emoji:
+ """|coro|
+ """|coro|
复制
已复制
复制
已复制
+
+ Retrieves a custom :class:`App
lication
Emoji` from the application.
+ Retrieves a custom :class:`App
Emoji` from the application.
+
+
+ Parameters
+ Parameters
+ ----------
+ ----------
+ emoji_id: :class:`int`
+ emoji_id: :class:`int`
+ The emoji's ID.
+ The emoji's ID.
+
+
+ Returns
+ Returns
+ -------
+ -------
复制
已复制
复制
已复制
+ :class:`App
Emoji`
+ :class:`App
lication
Emoji`
+ The retrieved emoji.
+ The retrieved emoji.
+
+
+ Raises
+ Raises
+ ------
+ ------
+ NotFound
+ NotFound
+ The emoji requested could not be found.
+ The emoji requested could not be found.
+ HTTPException
+ HTTPException
+ An error occurred fetching the emoji.
+ An error occurred fetching the emoji.
+ """
+ """
复制
已复制
复制
已复制
+ data = await self._
state
.http.get_application_emoji(
+ data = await self._
connection
.http.get_application_emoji(
self.application_id, emoji_id
)
+
self.application_id, emoji_id
+ return self._
connection.
store_
application
_emoji(self.application_id, data)
+
)
+ return self._
state.maybe_
store_
app
_emoji(self.application_id, data)
+
+
复制
已复制
复制
已复制
+ async def create_
emoji(
+ async def create_
application_
emoji(
+ self,
+ self,
+ *,
+ *,
+ name: str,
+ name: str,
+ image: bytes,
+ image: bytes,
复制
已复制
复制
已复制
+ ) -> App
Emoji:
+ ) -> App
lication
Emoji:
+ r"""|coro|
+ r"""|coro|
复制
已复制
复制
已复制
+
+ Creates a custom :class:`App
lication
Emoji` for the application.
+ Creates a custom :class:`App
Emoji` for the application.
+
+ There is currently a limit of 2000 emojis per application.
+ There is currently a limit of 2000 emojis per application.
+
+
+ Parameters
+ Parameters
复制
已复制
复制
已复制
+ ----------
-
+ ----------
+ name: :class:`str`
+ name: :class:`str`
+ The emoji name. Must be at least 2 characters.
+ The emoji name. Must be at least 2 characters.
+ image: :class:`bytes`
+ image: :class:`bytes`
+ The :term:`py:bytes-like object` representing the image data to use.
+ The :term:`py:bytes-like object` representing the image data to use.
+ Only JPG, PNG and GIF images are supported.
+ Only JPG, PNG and GIF images are supported.
+
+
+ Raises
+ Raises
复制
已复制
复制
已复制
+ ------
-
+ ------
+ Forbidden
+ Forbidden
+ You are not allowed to create emojis.
+ You are not allowed to create emojis.
+ HTTPException
+ HTTPException
+ An error occurred creating an emoji.
+ An error occurred creating an emoji.
+
+
+ Returns
+ Returns
复制
已复制
复制
已复制
+ -------
-
+ -------
+ :class:`App
Emoji`
+ :class:`App
lication
Emoji`
+ The created emoji.
+ The created emoji.
+ """
+ """
复制
已复制
复制
已复制
+
+ img = utils._bytes_to_base64_data(image)
+ img = utils._bytes_to_base64_data(image)
复制
已复制
复制
已复制
+ data = await self._
state
.http.create_application_emoji(
+ data = await self._
connection
.http.create_application_emoji(
self.application_id, name, img
)
+
self.application_id, name, img
+ return self._
connection.
store_
application_emoji(self.application_id,
data)
+
)
diff --git a/
disnake
/emoji.py b/
disnake
/emoji.py
+ return self._
state.maybe_
store_
app_emoji(self.application_id, data)
--- a/
disnake
/emoji.py
+
+++ b/
disnake
/emoji.py
+ async def delete_emoji(
-from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple, Union
+ self, emoji: Snowflake, *, reason: str | None = None
+from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple
+ ) -> None:
+ """|coro|
+
+ Deletes the custom :class:`AppEmoji` from the application.
+
+ Parameters
+ ----------
+ emoji: :class:`abc.Snowflake`
+ The emoji you are deleting.
+
+ Raises
+ ------
+ HTTPException
+ An error occurred deleting the emoji.
+ """
+
+ await self._state.http.delete_
application_emoji(self.application_id,
emoji.id)
+ if self._state.cache_app_emojis and self._state.get_emoji(emoji.id):
+ self._state.remove_emoji(emoji)
diff --git a/
discord
/emoji.py b/
discord
/emoji.py
--- a/
discord
/emoji.py
+++ b/
discord
/emoji.py
-__all__ = ("Emoji",)
-__all__ = ("Emoji",)
复制
已复制
复制
已复制
+__all__ = (
+__all__ = (
"Emoji",
"GuildEmoji",
"App
lication
Emoji"
)
+
"Emoji",
- from .guild_preview import GuildPreview
+
"GuildEmoji",
+
"App
Emoji"
,
+)
-class Emoji(_EmojiTag, AssetMixin):
-class Emoji(_EmojiTag, AssetMixin):
复制
已复制
复制
已复制
- """Represents a custom emoji.
-
- Depending on the way this object was created, some attributes can
- have a value of ``None``.
-
- .. container:: operations
-
- .. describe:: x == y
-
- Checks if two emoji are the same.
-
- .. describe:: x != y
-
- Checks if two emoji are not the same.
-
- .. describe:: hash(x)
-
- Return the emoji's hash.
-
- .. describe:: iter(x)
-
- Returns an iterator of ``(field, value)`` pairs. This allows this class
- to be used as an iterable in list/dict/etc constructions.
-
- .. describe:: str(x)
-
- Returns the emoji rendered for discord.
-
- Attributes
- ----------
- name: :class:`str`
- The name of the emoji.
- id: :class:`int`
- The emoji's ID.
- require_colons: :class:`bool`
- If colons are required to use this emoji in the client (:PJSalt: vs PJSalt).
- animated: :class:`bool`
- Whether an emoji is animated or not.
- managed: :class:`bool`
- If this emoji is managed by a Twitch integration.
- guild_id: :class:`int`
- The guild ID the emoji belongs to.
- available: :class:`bool`
- Whether the emoji is available for use.
- user: Optional[:class:`User`]
- The user that created the emoji. This can only be retrieved using :meth:`Guild.fetch_emoji` and
- having the :attr:`~Permissions.manage_emojis` permission.
- """
+class BaseEmoji(_EmojiTag, AssetMixin):
+class BaseEmoji(_EmojiTag, AssetMixin):
+ "application_id",
+ "application_id",
复制
已复制
复制
已复制
- def __init__(
self, *, guild:
Guild
, state: ConnectionState, data: EmojiPayload
)
:
- def __init__(
-
self, *, guild:
Union[
Guild
, GuildPreview]
, state: ConnectionState, data: EmojiPayload
- ) -> None
:
- self.guild_id: int = guild.id
- self.guild_id: int = guild.id
复制
已复制
复制
已复制
+ def __init__(self, *, state: ConnectionState, data: EmojiPayload)
:
+ def __init__(self, *, state: ConnectionState, data: EmojiPayload)
-> None
:
-
"<Emoji
"
-
return f
"<Emoji
id={self.id} name={self.name!r} animated={self.animated} managed={self.managed}>"
- f"
id={self.id} name={self.name!r} animated={self.animated} managed={self.managed}>"
+
return f
"<BaseEmoji
id={self.id} name={self.name!r} animated={self.animated}>"
+
"<BaseEmoji
" f"
id={self.id} name={self.name!r} animated={self.animated}>"
+
+
+class GuildEmoji(BaseEmoji):
+class GuildEmoji(BaseEmoji):
+ """Represents a custom emoji in a guild.
+ """Represents a custom emoji in a guild.
+
+
复制
已复制
复制
已复制
+ Depending on the way this object was created, some
attributes can
+ Depending on the way this object was created, some
of the
attributes can
+ have a value of ``None``.
+ have a value of ``None``.
+
+
复制
已复制
复制
已复制
+ ..
container
:: operations
+ ..
collapse
:: operations
已保存差异
原始文本
打开文件
diff --git a/discord/client.py b/discord/client.py --- a/discord/client.py +++ b/discord/client.py -from .emoji import Emoji +from .emoji import AppEmoji, GuildEmoji + cache_app_emojis: :class:`bool` + Whether to automatically fetch and cache the application's emojis on startup and when fetching. Defaults to ``False``. + + .. warning:: + + There are no events related to application emojis - if any are created/deleted on the + Developer Dashboard while the client is running, the cache will not be updated until you manually + run :func:`fetch_emojis`. + + .. versionadded:: 2.7 - def emojis(self) -> list[Emoji]: - """The emojis that the connected client has.""" + def emojis(self) -> list[GuildEmoji | AppEmoji]: + """The emojis that the connected client has. + + .. note:: + + This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is ``True``. + """ - def get_emoji(self, id: int, /) -> Emoji | None: + def get_emoji(self, id: int, /) -> GuildEmoji | AppEmoji | None: - Optional[:class:`.Emoji`] + Optional[:class:`.GuildEmoji` | :class:`.AppEmoji`] + + async def fetch_emojis(self) -> list[AppEmoji]: + r"""|coro| + + Retrieves all custom :class:`AppEmoji`\s from the application. + + Raises + --------- + HTTPException + An error occurred fetching the emojis. + + Returns + -------- + List[:class:`AppEmoji`] + The retrieved emojis. + """ + data = await self._state.http.get_all_application_emojis(self.application_id) + return [ + self._state.maybe_store_app_emoji(self.application_id, d) + for d in data["items"] + ] + + async def fetch_emoji(self, emoji_id: int, /) -> AppEmoji: + """|coro| + + Retrieves a custom :class:`AppEmoji` from the application. + + Parameters + ---------- + emoji_id: :class:`int` + The emoji's ID. + + Returns + ------- + :class:`AppEmoji` + The retrieved emoji. + + Raises + ------ + NotFound + The emoji requested could not be found. + HTTPException + An error occurred fetching the emoji. + """ + data = await self._state.http.get_application_emoji( + self.application_id, emoji_id + ) + return self._state.maybe_store_app_emoji(self.application_id, data) + + async def create_emoji( + self, + *, + name: str, + image: bytes, + ) -> AppEmoji: + r"""|coro| + + Creates a custom :class:`AppEmoji` for the application. + + There is currently a limit of 2000 emojis per application. + + Parameters + ----------- + name: :class:`str` + The emoji name. Must be at least 2 characters. + image: :class:`bytes` + The :term:`py:bytes-like object` representing the image data to use. + Only JPG, PNG and GIF images are supported. + + Raises + ------- + Forbidden + You are not allowed to create emojis. + HTTPException + An error occurred creating an emoji. + + Returns + -------- + :class:`AppEmoji` + The created emoji. + """ + + img = utils._bytes_to_base64_data(image) + data = await self._state.http.create_application_emoji( + self.application_id, name, img + ) + return self._state.maybe_store_app_emoji(self.application_id, data) + + async def delete_emoji( + self, emoji: Snowflake, *, reason: str | None = None + ) -> None: + """|coro| + + Deletes the custom :class:`AppEmoji` from the application. + + Parameters + ---------- + emoji: :class:`abc.Snowflake` + The emoji you are deleting. + + Raises + ------ + HTTPException + An error occurred deleting the emoji. + """ + + await self._state.http.delete_application_emoji(self.application_id, emoji.id) + if self._state.cache_app_emojis and self._state.get_emoji(emoji.id): + self._state.remove_emoji(emoji) diff --git a/discord/emoji.py b/discord/emoji.py --- a/discord/emoji.py +++ b/discord/emoji.py -__all__ = ("Emoji",) +__all__ = ( + "Emoji", + "GuildEmoji", + "AppEmoji", +) -class Emoji(_EmojiTag, AssetMixin): - """Represents a custom emoji. - - Depending on the way this object was created, some attributes can - have a value of ``None``. - - .. container:: operations - - .. describe:: x == y - - Checks if two emoji are the same. - - .. describe:: x != y - - Checks if two emoji are not the same. - - .. describe:: hash(x) - - Return the emoji's hash. - - .. describe:: iter(x) - - Returns an iterator of ``(field, value)`` pairs. This allows this class - to be used as an iterable in list/dict/etc constructions. - - .. describe:: str(x) - - Returns the emoji rendered for discord. - - Attributes - ---------- - name: :class:`str` - The name of the emoji. - id: :class:`int` - The emoji's ID. - require_colons: :class:`bool` - If colons are required to use this emoji in the client (:PJSalt: vs PJSalt). - animated: :class:`bool` - Whether an emoji is animated or not. - managed: :class:`bool` - If this emoji is managed by a Twitch integration. - guild_id: :class:`int` - The guild ID the emoji belongs to. - available: :class:`bool` - Whether the emoji is available for use. - user: Optional[:class:`User`] - The user that created the emoji. This can only be retrieved using :meth:`Guild.fetch_emoji` and - having the :attr:`~Permissions.manage_emojis` permission. - """ +class BaseEmoji(_EmojiTag, AssetMixin): + "application_id", - def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): - self.guild_id: int = guild.id + def __init__(self, *, state: ConnectionState, data: EmojiPayload): - "<Emoji" - f" id={self.id} name={self.name!r} animated={self.animated} managed={self.managed}>" + "<BaseEmoji" f" id={self.id} name={self.name!r} animated={self.animated}>" + +class GuildEmoji(BaseEmoji): + """Represents a custom emoji in a guild. + + Depending on the way this object was created, some attributes can + have a value of ``None``. + + .. container:: operations + + .. describe:: x == y + + Checks if two emoji are the same. + + .. describe:: x != y + + Checks if two emoji are not the same. + + .. describe:: hash(x) + + Return the emoji's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(field, value)`` pairs. This allows this class + to be used as an iterable in list/dict/etc constructions. + + .. describe:: str(x) + + Returns the emoji rendered for discord. + + Attributes + ---------- + name: :class:`str` + The name of the emoji. + id: :class:`int` + The emoji's ID. + require_colons: :class:`bool` + If colons are required to use this emoji in the client (:PJSalt: vs PJSalt). + animated: :class:`bool` + Whether an emoji is animated or not. + managed: :class:`bool` + If this emoji is managed by a Twitch integration. + guild_id: :class:`int` + The guild ID the emoji belongs to. + available: :class:`bool` + Whether the emoji is available for use. + user: Optional[:class:`User`] + The user that created the emoji. This can only be retrieved using :meth:`Guild.fetch_emoji` and + having the :attr:`~Permissions.manage_emojis` permission. + """ + + def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): + self.guild_id: int = guild.id + super().__init__(state, data) + + def __repr__(self) -> str: + return ( + "<GuildEmoji" + f" id={self.id} name={self.name!r} animated={self.animated} managed={self.managed}>" + ) + - ) -> Emoji: + ) -> GuildEmoji: - :class:`Emoji` + :class:`GuildEmoji` - return Emoji(guild=self.guild, data=data, state=self._state) + return GuildEmoji(guild=self.guild, data=data, state=self._state) + + +Emoji = GuildEmoji + + +class AppEmoji(BaseEmoji): + """Represents a custom emoji from an application. + + Depending on the way this object was created, some attributes can + have a value of ``None``. + + .. versionadded:: 2.7 + + .. container:: operations + + .. describe:: x == y + + Checks if two emoji are the same. + + .. describe:: x != y + + Checks if two emoji are not the same. + + .. describe:: hash(x) + + Return the emoji's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(field, value)`` pairs. This allows this class + to be used as an iterable in list/dict/etc constructions. + + .. describe:: str(x) + + Returns the emoji rendered for discord. + + Attributes + ---------- + name: :class:`str` + The name of the emoji. + id: :class:`int` + The emoji's ID. + require_colons: :class:`bool` + If colons are required to use this emoji in the client (:PJSalt: vs PJSalt). + animated: :class:`bool` + Whether an emoji is animated or not. + managed: :class:`bool` + If this emoji is managed by a Twitch integration. + application_id: Optional[:class:`int`] + The application ID the emoji belongs to, if available. + available: :class:`bool` + Whether the emoji is available for use. + user: Optional[:class:`User`] + The user that created the emoji. + """ + + def __init__( + self, *, application_id: int, state: ConnectionState, data: EmojiPayload + ): + self.application_id: int = application_id + super().__init__(state, data) + + def __repr__(self) -> str: + return "<AppEmoji" f" id={self.id} name={self.name!r} animated={self.animated}>" + + @property + def guild(self) -> Guild: + """The guild this emoji belongs to. This is always `None` for :class:`AppEmoji`.""" + return None + + @property + def roles(self) -> list[Role]: + """A :class:`list` of roles that is allowed to use this emoji. This is always empty for :class:`AppEmoji`.""" + return [] + + def is_usable(self) -> bool: + """Whether the bot can use this emoji.""" + return self.application_id == self._state.application_id + + async def delete(self) -> None: + """|coro| + + Deletes the application emoji. + + You must own the emoji to do this. + + Raises + ------ + Forbidden + You are not allowed to delete the emoji. + HTTPException + An error occurred deleting the emoji. + """ + + await self._state.http.delete_application_emoji(self.application_id, self.id) + if self._state.cache_app_emojis and self._state.get_emoji(self.id): + self._state._remove_emoji(self) + + async def edit( + self, + *, + name: str = MISSING, + ) -> AppEmoji: + r"""|coro| + + Edits the application emoji. + + You must own the emoji to do this. + + Parameters + ----------- + name: :class:`str` + The new emoji name. + + Raises + ------- + Forbidden + You are not allowed to edit the emoji. + HTTPException + An error occurred editing the emoji. + + Returns + -------- + :class:`AppEmoji` + The newly updated emoji. + """ + + payload = {} + if name is not MISSING: + payload["name"] = name + + data = await self._state.http.edit_application_emoji( + self.application_id, self.id, payload=payload + ) + return self._state.maybe_store_app_emoji(self.application_id, data) diff --git a/discord/http.py b/discord/http.py --- a/discord/http.py +++ b/discord/http.py + def get_all_application_emojis( + self, application_id: Snowflake + ) -> Response[list[emoji.Emoji]]: + return self.request( + Route( + "GET", + "/applications/{application_id}/emojis", + application_id=application_id, + ) + ) + + def get_application_emoji( + self, application_id: Snowflake, emoji_id: Snowflake + ) -> Response[emoji.Emoji]: + return self.request( + Route( + "GET", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + ) + + def create_application_emoji( + self, + application_id: Snowflake, + name: str, + image: bytes, + ) -> Response[emoji.Emoji]: + payload = { + "name": name, + "image": image, + } + + r = Route( + "POST", + "/applications/{application_id}/emojis", + application_id=application_id, + ) + return self.request(r, json=payload) + + def delete_application_emoji( + self, + application_id: Snowflake, + emoji_id: Snowflake, + ) -> Response[None]: + r = Route( + "DELETE", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + return self.request(r) + + def edit_application_emoji( + self, + application_id: Snowflake, + emoji_id: Snowflake, + *, + payload: dict[str, Any], + ) -> Response[emoji.Emoji]: + r = Route( + "PATCH", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + return self.request(r, json=payload) + diff --git a/discord/state.py b/discord/state.py --- a/discord/state.py +++ b/discord/state.py -from .emoji import Emoji +from .emoji import AppEmoji, Emoji, GuildEmoji + self.cache_app_emojis: bool = options.get("cache_app_emojis", False) + - def store_emoji(self, guild: Guild, data: EmojiPayload) -> Emoji: + def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: - self._emojis[emoji_id] = emoji = Emoji(guild=guild, state=self, data=data) + self._emojis[emoji_id] = emoji = GuildEmoji(guild=guild, state=self, data=data) + return emoji + + def maybe_store_app_emoji( + self, application_id: int, data: EmojiPayload + ) -> AppEmoji: + # the id will be present here + emoji = AppEmoji(application_id=application_id, state=self, data=data) + if self.cache_app_emojis: + emoji_id = int(data["id"]) # type: ignore + self._emojis[emoji_id] = emoji - self._emojis.pop(emoji.id, None) + self._remove_emoji(emoji) - def emojis(self) -> list[Emoji]: + def emojis(self) -> list[GuildEmoji | AppEmoji]: - def get_emoji(self, emoji_id: int | None) -> Emoji | None: + def get_emoji(self, emoji_id: int | None) -> GuildEmoji | AppEmoji | None: + def _remove_emoji(self, emoji: GuildEmoji | AppEmoji) -> None: + self._emojis.pop(emoji.id, None) + + if self.cache_app_emojis and self.application_id: + data = await self.http.get_all_application_emojis(self.application_id) + for e in data.get("items", []): + self.maybe_store_app_emoji(self.application_id, e) + diff --git a/docs/api/models.rst b/docs/api/models.rst --- a/docs/api/models.rst +++ b/docs/api/models.rst -.. attributetable:: Emoji +.. attributetable:: GuildEmoji -.. autoclass:: Emoji() +.. autoclass:: GuildEmoji() + :members: + :inherited-members: + +.. attributetable:: AppEmoji + +.. autoclass:: AppEmoji()
更改后文本
打开文件
diff --git a/disnake/client.py b/disnake/client.py --- a/disnake/client.py +++ b/disnake/client.py -from .emoji import Emoji +from .emoji import ApplicationEmoji, GuildEmoji + cache_app_emojis: bool = False, + cache_app_emojis=cache_app_emojis, + cache_app_emojis: bool, + cache_app_emojis=cache_app_emojis, - def emojis(self) -> List[Emoji]: - """List[:class:`.Emoji`]: The emojis that the connected client has.""" + def emojis(self) -> List[Union[GuildEmoji, ApplicationEmoji]]: + """The emojis that the connected client has. + + .. note:: + This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is + ``True``. + """ - def get_emoji(self, id: int, /) -> Optional[Emoji]: + def get_emoji(self, id: int, /) -> Optional[Union[GuildEmoji, ApplicationEmoji]]: + + async def fetch_application_emojis(self) -> list[ApplicationEmoji]: + r"""|coro| + Retrieves all custom :class:`ApplicationEmoji`\s from the application. + + Raises + ------ + HTTPException + An error occurred fetching the emojis. + + Returns + ------- + List[:class:`ApplicationEmoji`] + The retrieved emojis. + """ + data = await self._connection.http.get_all_application_emojis(self.application_id) + return [ + self._connection.store_application_emoji(self.application_id, d) for d in data["items"] + ] + + async def fetch_application_emoji(self, emoji_id: int, /) -> ApplicationEmoji: + """|coro| + Retrieves a custom :class:`ApplicationEmoji` from the application. + + Parameters + ---------- + emoji_id: :class:`int` + The emoji's ID. + + Returns + ------- + :class:`ApplicationEmoji` + The retrieved emoji. + + Raises + ------ + NotFound + The emoji requested could not be found. + HTTPException + An error occurred fetching the emoji. + """ + data = await self._connection.http.get_application_emoji(self.application_id, emoji_id) + return self._connection.store_application_emoji(self.application_id, data) + + async def create_application_emoji( + self, + *, + name: str, + image: bytes, + ) -> ApplicationEmoji: + r"""|coro| + Creates a custom :class:`ApplicationEmoji` for the application. + There is currently a limit of 2000 emojis per application. + + Parameters + ---------- + name: :class:`str` + The emoji name. Must be at least 2 characters. + image: :class:`bytes` + The :term:`py:bytes-like object` representing the image data to use. + Only JPG, PNG and GIF images are supported. + + Raises + ------ + Forbidden + You are not allowed to create emojis. + HTTPException + An error occurred creating an emoji. + + Returns + ------- + :class:`ApplicationEmoji` + The created emoji. + """ + img = utils._bytes_to_base64_data(image) + data = await self._connection.http.create_application_emoji(self.application_id, name, img) + return self._connection.store_application_emoji(self.application_id, data) diff --git a/disnake/emoji.py b/disnake/emoji.py --- a/disnake/emoji.py +++ b/disnake/emoji.py -from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple, Union +from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple -__all__ = ("Emoji",) +__all__ = ("Emoji", "GuildEmoji", "ApplicationEmoji") - from .guild_preview import GuildPreview -class Emoji(_EmojiTag, AssetMixin): +class BaseEmoji(_EmojiTag, AssetMixin): + "application_id", - def __init__( - self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload - ) -> None: - self.guild_id: int = guild.id + def __init__(self, *, state: ConnectionState, data: EmojiPayload) -> None: - return f"<Emoji id={self.id} name={self.name!r} animated={self.animated} managed={self.managed}>" + return f"<BaseEmoji id={self.id} name={self.name!r} animated={self.animated}>" + +class GuildEmoji(BaseEmoji): + """Represents a custom emoji in a guild. + + Depending on the way this object was created, some of the attributes can + have a value of ``None``. + + .. collapse:: operations + + .. describe:: x == y + + Checks if two emoji are the same. + + .. describe:: x != y + + Checks if two emoji are not the same. + + .. describe:: hash(x) + + Return the emoji's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(field, value)`` pairs. This allows this class + to be used as an iterable in list/dict/etc constructions. + + .. describe:: str(x) + + Returns the emoji rendered for Discord. + + Attributes + ---------- + name: :class:`str` + The emoji's name. + id: :class:`int` + The emoji's ID. + require_colons: :class:`bool` + Whether colons are required to use this emoji in the client (:PJSalt: vs PJSalt). + animated: :class:`bool` + Whether the emoji is animated or not. + managed: :class:`bool` + Whether the emoji is managed by a Twitch integration. + guild_id: :class:`int` + The guild ID the emoji belongs to. + available: :class:`bool` + Whether the emoji is available for use. + user: Optional[:class:`User`] + The user that created this emoji. This can only be retrieved using + :meth:`Guild.fetch_emoji`/:meth:`Guild.fetch_emojis` while + having the :attr:`~Permissions.manage_guild_expressions` permission. + """ + + def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): + self.guild_id: int = guild.id + super().__init__(state=state, data=data) + + def __repr__(self) -> str: + return f"<GuildEmoji id={self.id} name={self.name!r} animated={self.animated} managed={self.managed}>" + - ) -> Emoji: + ) -> GuildEmoji: - :class:`Emoji` + :class:`GuildEmoji` - return Emoji(guild=self.guild, data=data, state=self._state) + return GuildEmoji(guild=self.guild, data=data, state=self._state) + + +Emoji = GuildEmoji + + +class ApplicationEmoji(BaseEmoji): + """Represents a custom emoji from an application. + + Depending on the way this object was created, some attributes can + have a value of ``None``. + + .. container:: operations + + .. describe:: x == y + + Checks if two emoji are the same. + + .. describe:: x != y + + Checks if two emoji are not the same. + + .. describe:: hash(x) + + Return the emoji's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(field, value)`` pairs. This allows this class + to be used as an iterable in list/dict/etc constructions. + + .. describe:: str(x) + + Returns the emoji rendered for discord. + + Attributes + ---------- + name: :class:`str` + The name of the emoji. + id: :class:`int` + The emoji's ID. + require_colons: :class:`bool` + If colons are required to use this emoji in the client (:PJSalt: vs PJSalt). + animated: :class:`bool` + Whether an emoji is animated or not. + managed: :class:`bool` + If this emoji is managed by a Twitch integration. + application_id: Optional[:class:`int`] + The application ID the emoji belongs to, if available. + available: :class:`bool` + Whether the emoji is available for use. + user: Optional[:class:`User`] + The user that created the emoji. + """ + + def __init__(self, *, application_id: int, state: ConnectionState, data: EmojiPayload): + self.application_id: int = application_id + super().__init__(state=state, data=data) + + def __repr__(self): + return f"<ApplicationEmoji id={self.id} name={self.name!r} animated={self.animated}>" + + def is_usable(self) -> bool: + """Whether the bot can use this emoji.""" + return self.application_id == self._state.application_id + + async def delete(self) -> None: + """|coro| + Deletes the application emoji. + You must own the emoji to do this. + + Raises + ------ + Forbidden + You are not allowed to delete the emoji. + HTTPException + An error occurred deleting the emoji. + """ + await self._state.http.delete_application_emoji(self.application_id, self.id) + if self._state.cache_app_emojis and self._state.get_emoji(self.id): + self._state._remove_emoji(self) + + async def edit( + self, + *, + name: str = MISSING, + ) -> ApplicationEmoji: + r"""|coro| + Edits the application emoji. + You must own the emoji to do this. + + Parameters + ---------- + name: :class:`str` + The new emoji name. + + Raises + ------ + Forbidden + You are not allowed to edit the emoji. + HTTPException + An error occurred editing the emoji. + + Returns + ------- + :class:`ApplicationEmoji` + The newly updated emoji. + """ + payload = {} + if name is not MISSING: + payload["name"] = name + + data = await self._state.http.edit_application_emoji( + self.application_id, self.id, payload=payload + ) + return self._state.store_application_emoji(self.application_id, data) diff --git a/disnake/ext/commands/bot.py b/disnake/ext/commands/bot.py --- a/disnake/ext/commands/bot.py +++ b/disnake/ext/commands/bot.py + + cache_app_emojis: :class:`bool` + Whether to automatically fetch and cache the application's emojis on startup and when fetching. + Defaults to ``False``. + cache_app_emojis: bool = False, + cache_app_emojis: bool = False, + + cache_app_emojis: :class:`bool` + Whether to automatically fetch and cache the application's emojis on startup and when fetching. + Defaults to ``False``. + cache_app_emojis: bool = False, + cache_app_emojis: bool = False, diff --git a/disnake/http.py b/disnake/http.py --- a/disnake/http.py +++ b/disnake/http.py + def get_all_application_emojis(self, application_id: Snowflake) -> Response[List[emoji.Emoji]]: + return self.request( + Route("GET", "/applications/{application_id}/emojis", application_id=application_id) + ) + + def get_application_emoji( + self, application_id: Snowflake, emoji_id: Snowflake + ) -> Response[emoji.Emoji]: + return self.request( + Route( + "GET", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + ) + + def create_application_emoji( + self, + application_id: Snowflake, + name: str, + image: str, + ) -> Response[emoji.Emoji]: + payload = {"name": name, "image": image} + r = Route("POST", "/applications/{application_id}/emojis", application_id=application_id) + return self.request(r, json=payload) + + def delete_application_emoji( + self, + application_id: Snowflake, + emoji_id: Snowflake, + ) -> Response[None]: + r = Route( + "DELETE", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + return self.request(r) + + def edit_application_emoji( + self, + application_id: Snowflake, + emoji_id: Snowflake, + *, + payload: dict[str, Any], + ) -> Response[emoji.Emoji]: + r = Route( + "PATCH", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + return self.request(r, json=payload) + diff --git a/disnake/state.py b/disnake/state.py --- a/disnake/state.py +++ b/disnake/state.py -from .emoji import Emoji +from .emoji import ApplicationEmoji, Emoji, GuildEmoji + cache_app_emojis: bool = False, + self.cache_app_emojis: bool = cache_app_emojis + - self._emojis: Dict[int, Emoji] = {} + self._emojis: Dict[int, Emoji, ApplicationEmoji] = {} - def store_emoji(self, guild: Guild, data: EmojiPayload) -> Emoji: + def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: - self._emojis[emoji_id] = emoji = Emoji(guild=guild, state=self, data=data) + self._emojis[emoji_id] = emoji = GuildEmoji(guild=guild, state=self, data=data) + return emoji + + def store_application_emoji(self, application_id: int, data: EmojiPayload) -> ApplicationEmoji: + emoji = ApplicationEmoji(application_id=application_id, state=self, data=data) + if self.cache_app_emojis: + emoji_id = int(data["id"]) # type: ignore + self._emojis[emoji_id] = emoji - self._emojis.pop(emoji.id, None) + self._remove_emoji(emoji.id) - def emojis(self) -> List[Emoji]: + def emojis(self) -> List[Union[GuildEmoji, ApplicationEmoji]]: - def get_emoji(self, emoji_id: Optional[int]) -> Optional[Emoji]: + def get_emoji(self, emoji_id: Optional[int]) -> Optional[Union[GuildEmoji, ApplicationEmoji]]: + def _remove_emoji(self, emoji: Union[GuildEmoji, ApplicationEmoji]) -> None: + self._emojis.pop(emoji.id, None) + + if self.cache_app_emojis and self.application_id: + data = await self.http.get_all_application_emojis(self.application_id) + for e in data.get("items", []): + self.store_application_emoji(self.application_id, e) +
查找差异