Browse Source

Add support for role icons

* Document ROLE_ICONS guild feature
https://github.com/discord/discord-api-docs/pull/3847

* Add support for role icons
https://github.com/discord/discord-api-docs/pull/3847

* Add support for role icon/emoji changes in audit log
https://github.com/discord/discord-api-docs/pull/3847
pull/7494/head
jack1142 3 years ago
committed by GitHub
parent
commit
783513726f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      discord/audit_logs.py
  2. 18
      discord/guild.py
  3. 2
      discord/http.py
  4. 61
      discord/role.py
  5. 12
      discord/types/audit_log.py
  6. 1
      discord/types/guild.py
  7. 2
      discord/types/role.py
  8. 17
      docs/api.rst

5
discord/audit_logs.py

@ -119,7 +119,10 @@ def _transform_overwrites(
def _transform_icon(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]:
if data is None:
return None
return Asset._from_guild_icon(entry._state, entry.guild.id, data)
if entry.action is enums.AuditLogAction.guild_update:
return Asset._from_guild_icon(entry._state, entry.guild.id, data)
else:
return Asset._from_icon(entry._state, entry._target_id, data, path='role')
def _transform_avatar(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]:

18
discord/guild.py

@ -212,6 +212,7 @@ class Guild(Hashable):
- ``PARTNERED``: Guild is a partnered server.
- ``PREVIEW_ENABLED``: Guild can be viewed before being accepted via Membership Screening.
- ``PRIVATE_THREADS``: Guild has access to create private threads.
- ``ROLE_ICONS``: Guild is able to set role icons.
- ``SEVEN_DAY_THREAD_ARCHIVE``: Guild has access to the seven day archive time for threads.
- ``THREE_DAY_THREAD_ARCHIVE``: Guild has access to the three day archive time for threads.
- ``TICKETED_EVENTS_ENABLED``: Guild has enabled ticketed events.
@ -2394,6 +2395,7 @@ class Guild(Hashable):
permissions: Permissions = ...,
colour: Union[Colour, int] = ...,
hoist: bool = ...,
display_icon: Union[bytes, str] = MISSING,
mentionable: bool = ...,
) -> Role:
...
@ -2407,6 +2409,7 @@ class Guild(Hashable):
permissions: Permissions = ...,
color: Union[Colour, int] = ...,
hoist: bool = ...,
display_icon: Union[bytes, str] = MISSING,
mentionable: bool = ...,
) -> Role:
...
@ -2419,6 +2422,7 @@ class Guild(Hashable):
color: Union[Colour, int] = MISSING,
colour: Union[Colour, int] = MISSING,
hoist: bool = MISSING,
display_icon: Union[bytes, str] = MISSING,
mentionable: bool = MISSING,
reason: Optional[str] = None,
) -> Role:
@ -2434,6 +2438,9 @@ class Guild(Hashable):
.. versionchanged:: 1.6
Can now pass ``int`` to ``colour`` keyword-only parameter.
.. versionadded:: 2.0
The ``display_icon`` keyword-only parameter was added.
Parameters
-----------
name: :class:`str`
@ -2446,6 +2453,11 @@ class Guild(Hashable):
hoist: :class:`bool`
Indicates if the role should be shown separately in the member list.
Defaults to ``False``.
display_icon: Union[:class:`bytes`, :class:`str`]
A :term:`py:bytes-like object` representing the icon
or :class:`str` representing unicode emoji that should be used as a role icon.
Only PNG/JPEG is supported.
This is only available to guilds that contain ``ROLE_ICONS`` in :attr:`features`.
mentionable: :class:`bool`
Indicates if the role should be mentionable by others.
Defaults to ``False``.
@ -2481,6 +2493,12 @@ class Guild(Hashable):
if hoist is not MISSING:
fields['hoist'] = hoist
if display_icon is not MISSING:
if isinstance(display_icon, bytes):
fields['icon'] = utils._bytes_to_base64_data(display_icon)
else:
fields['unicode_emoji'] = display_icon
if mentionable is not MISSING:
fields['mentionable'] = mentionable

2
discord/http.py

@ -1422,7 +1422,7 @@ class HTTPClient:
self, guild_id: Snowflake, role_id: Snowflake, *, reason: Optional[str] = None, **fields: Any
) -> Response[role.Role]:
r = Route('PATCH', '/guilds/{guild_id}/roles/{role_id}', guild_id=guild_id, role_id=role_id)
valid_keys = ('name', 'permissions', 'color', 'hoist', 'mentionable')
valid_keys = ('name', 'permissions', 'color', 'hoist', 'icon', 'unicode_emoji', 'mentionable')
payload = {k: v for k, v in fields.items() if k in valid_keys}
return self.request(r, json=payload, reason=reason)

61
discord/role.py

@ -25,11 +25,12 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations
from typing import Any, Dict, List, Optional, TypeVar, Union, overload, TYPE_CHECKING
from .asset import Asset
from .permissions import Permissions
from .errors import InvalidArgument
from .colour import Colour
from .mixins import Hashable
from .utils import snowflake_time, _get_as_snowflake, MISSING
from .utils import snowflake_time, _bytes_to_base64_data, _get_as_snowflake, MISSING
__all__ = (
'RoleTags',
@ -163,6 +164,18 @@ class Role(Hashable):
compare for roles in the hierarchy is using the comparison
operators on the role objects themselves.
unicode_emoji: Optional[:class:`str`]
The role's unicode emoji, if available.
.. note::
If :attr:`icon` is not ``None``, it is displayed as role icon
instead of the unicode emoji under this attribute.
If you want the icon that a role has displayed, consider using :attr:`display_icon`.
.. versionadded:: 2.0
managed: :class:`bool`
Indicates if the role is managed by the guild through some form of
integrations such as Twitch.
@ -178,6 +191,8 @@ class Role(Hashable):
'_permissions',
'_colour',
'position',
'_icon',
'unicode_emoji',
'managed',
'mentionable',
'hoist',
@ -240,6 +255,8 @@ class Role(Hashable):
self.position: int = data.get('position', 0)
self._colour: int = data.get('color', 0)
self.hoist: bool = data.get('hoist', False)
self._icon: Optional[str] = data.get('icon')
self.unicode_emoji: Optional[str] = data.get('unicode_emoji')
self.managed: bool = data.get('managed', False)
self.mentionable: bool = data.get('mentionable', False)
self.tags: Optional[RoleTags]
@ -297,6 +314,30 @@ class Role(Hashable):
""":class:`Colour`: Returns the role color. An alias exists under ``colour``."""
return self.colour
@property
def icon(self) -> Optional[Asset]:
"""Optional[:class:`.Asset`]: Returns the role's icon asset, if available.
.. note::
If this is ``None``, the role might instead have unicode emoji as its icon
if :attr:`unicode_emoji` is not ``None``.
If you want the icon that a role has displayed, consider using :attr:`display_icon`.
.. versionadded:: 2.0
"""
if self._icon is None:
return None
return Asset._from_icon(self._state, self.id, self._icon, path='role')
@property
def display_icon(self) -> Optional[Union[Asset, str]]:
"""Optional[Union[:class:`.Asset`, :class:`str`]]: Returns the role's display icon, if available.
.. versionadded:: 2.0
"""
return self.icon or self.unicode_emoji
@property
def created_at(self) -> datetime.datetime:
""":class:`datetime.datetime`: Returns the role's creation time in UTC."""
@ -348,6 +389,7 @@ class Role(Hashable):
colour: Union[Colour, int] = MISSING,
color: Union[Colour, int] = MISSING,
hoist: bool = MISSING,
display_icon: Optional[Union[bytes, str]] = MISSING,
mentionable: bool = MISSING,
position: int = MISSING,
reason: Optional[str] = MISSING,
@ -367,6 +409,9 @@ class Role(Hashable):
.. versionchanged:: 2.0
Edits are no longer in-place, the newly edited role is returned instead.
.. versionadded:: 2.0
The ``display_icon`` keyword-only parameter was added.
Parameters
-----------
name: :class:`str`
@ -377,6 +422,12 @@ class Role(Hashable):
The new colour to change to. (aliased to color as well)
hoist: :class:`bool`
Indicates if the role should be shown separately in the member list.
display_icon: Optional[Union[:class:`bytes`, :class:`str`]]
A :term:`py:bytes-like object` representing the icon
or :class:`str` representing unicode emoji that should be used as a role icon.
Could be ``None`` to denote removal of the icon.
Only PNG/JPEG is supported.
This is only available to guilds that contain ``ROLE_ICONS`` in :attr:`features`.
mentionable: :class:`bool`
Indicates if the role should be mentionable by others.
position: :class:`int`
@ -422,6 +473,14 @@ class Role(Hashable):
if hoist is not MISSING:
payload['hoist'] = hoist
if display_icon is not MISSING:
payload['icon'] = None
payload['unicode_emoji'] = None
if isinstance(display_icon, bytes):
payload['icon'] = _bytes_to_base64_data(display_icon)
else:
payload['unicode_emoji'] = display_icon
if mentionable is not MISSING:
payload['mentionable'] = mentionable

12
discord/types/audit_log.py

@ -84,7 +84,17 @@ AuditLogEvent = Literal[
class _AuditLogChange_Str(TypedDict):
key: Literal[
'name', 'description', 'preferred_locale', 'vanity_url_code', 'topic', 'code', 'allow', 'deny', 'permissions', 'tags'
'name',
'description',
'preferred_locale',
'vanity_url_code',
'topic',
'code',
'allow',
'deny',
'permissions',
'tags',
'unicode_emoji',
]
new_value: str
old_value: str

1
discord/types/guild.py

@ -90,6 +90,7 @@ GuildFeature = Literal[
'PARTNERED',
'PREVIEW_ENABLED',
'PRIVATE_THREADS',
'ROLE_ICONS',
'SEVEN_DAY_THREAD_ARCHIVE',
'THREE_DAY_THREAD_ARCHIVE',
'TICKETED_EVENTS_ENABLED',

2
discord/types/role.py

@ -29,6 +29,8 @@ from .snowflake import Snowflake
class _RoleOptional(TypedDict, total=False):
icon: Optional[str]
unicode_emoji: Optional[str]
tags: RoleTags

17
docs/api.rst

@ -1994,6 +1994,8 @@ of :class:`enum.Enum`.
- :attr:`~AuditLogDiff.colour`
- :attr:`~AuditLogDiff.mentionable`
- :attr:`~AuditLogDiff.hoist`
- :attr:`~AuditLogDiff.icon`
- :attr:`~AuditLogDiff.unicode_emoji`
- :attr:`~AuditLogDiff.name`
- :attr:`~AuditLogDiff.permissions`
@ -2004,6 +2006,7 @@ of :class:`enum.Enum`.
- The name has changed
- The permissions have changed
- The colour has changed
- The role icon (or unicode emoji) has changed
- Its hoist/mentionable state has changed
When this is the action, the type of :attr:`~AuditLogEntry.target` is
@ -2014,6 +2017,8 @@ of :class:`enum.Enum`.
- :attr:`~AuditLogDiff.colour`
- :attr:`~AuditLogDiff.mentionable`
- :attr:`~AuditLogDiff.hoist`
- :attr:`~AuditLogDiff.icon`
- :attr:`~AuditLogDiff.unicode_emoji`
- :attr:`~AuditLogDiff.name`
- :attr:`~AuditLogDiff.permissions`
@ -2828,7 +2833,7 @@ AuditLogDiff
.. attribute:: icon
A guild's icon. See also :attr:`Guild.icon`.
A guild's or role's icon. See also :attr:`Guild.icon` or :attr:`Role.icon`.
:type: :class:`Asset`
@ -3202,7 +3207,15 @@ AuditLogDiff
The name of the emoji that represents a sticker being changed.
See also :attr:`GuildSticker.emoji`
See also :attr:`GuildSticker.emoji`.
:type: :class:`str`
.. attribute:: unicode_emoji
The unicode emoji that is used as an icon for the role being changed.
See also :attr:`Role.unicode_emoji`.
:type: :class:`str`

Loading…
Cancel
Save