Skip to content

Commit

Permalink
implement guild stickers
Browse files Browse the repository at this point in the history
  • Loading branch information
NCPlayz authored Jul 31, 2021
1 parent ecf239d commit 60d82cf
Show file tree
Hide file tree
Showing 16 changed files with 1,119 additions and 85 deletions.
21 changes: 18 additions & 3 deletions discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@
Callable,
Dict,
List,
Mapping,
Optional,
TYPE_CHECKING,
Protocol,
Sequence,
Tuple,
Type,
TypeVar,
Union,
overload,
Expand All @@ -53,6 +52,7 @@
from .invite import Invite
from .file import File
from .voice_client import VoiceClient, VoiceProtocol
from .sticker import GuildSticker, StickerItem
from . import utils

__all__ = (
Expand Down Expand Up @@ -1164,6 +1164,7 @@ async def send(
tts: bool = ...,
embed: Embed = ...,
file: File = ...,
stickers: Sequence[Union[GuildSticker, StickerItem]] = ...,
delete_after: float = ...,
nonce: Union[str, int] = ...,
allowed_mentions: AllowedMentions = ...,
Expand All @@ -1181,6 +1182,7 @@ async def send(
tts: bool = ...,
embed: Embed = ...,
files: List[File] = ...,
stickers: Sequence[Union[GuildSticker, StickerItem]] = ...,
delete_after: float = ...,
nonce: Union[str, int] = ...,
allowed_mentions: AllowedMentions = ...,
Expand All @@ -1198,6 +1200,7 @@ async def send(
tts: bool = ...,
embeds: List[Embed] = ...,
file: File = ...,
stickers: Sequence[Union[GuildSticker, StickerItem]] = ...,
delete_after: float = ...,
nonce: Union[str, int] = ...,
allowed_mentions: AllowedMentions = ...,
Expand All @@ -1215,6 +1218,7 @@ async def send(
tts: bool = ...,
embeds: List[Embed] = ...,
files: List[File] = ...,
stickers: Sequence[Union[GuildSticker, StickerItem]] = ...,
delete_after: float = ...,
nonce: Union[str, int] = ...,
allowed_mentions: AllowedMentions = ...,
Expand All @@ -1233,6 +1237,7 @@ async def send(
embeds=None,
file=None,
files=None,
stickers=None,
delete_after=None,
nonce=None,
allowed_mentions=None,
Expand Down Expand Up @@ -1304,6 +1309,10 @@ async def send(
embeds: List[:class:`~discord.Embed`]
A list of embeds to upload. Must be a maximum of 10.
.. versionadded:: 2.0
stickers: Sequence[Union[:class:`GuildSticker`, :class:`StickerItem`]]
A list of stickers to upload. Must be a maximum of 3.
.. versionadded:: 2.0
Raises
Expand Down Expand Up @@ -1340,6 +1349,9 @@ async def send(
raise InvalidArgument('embeds parameter must be a list of up to 10 elements')
embeds = [embed.to_dict() for embed in embeds]

if stickers is not None:
stickers = [sticker.id for sticker in stickers]

if allowed_mentions is not None:
if state.allowed_mentions is not None:
allowed_mentions = state.allowed_mentions.merge(allowed_mentions).to_dict()
Expand Down Expand Up @@ -1384,6 +1396,7 @@ async def send(
embeds=embeds,
nonce=nonce,
message_reference=reference,
stickers=stickers,
components=components,
)
finally:
Expand All @@ -1406,6 +1419,7 @@ async def send(
nonce=nonce,
allowed_mentions=allowed_mentions,
message_reference=reference,
stickers=stickers,
components=components,
)
finally:
Expand All @@ -1421,6 +1435,7 @@ async def send(
nonce=nonce,
allowed_mentions=allowed_mentions,
message_reference=reference,
stickers=stickers,
components=components,
)

Expand Down Expand Up @@ -1454,7 +1469,7 @@ def typing(self) -> Typing:
This means that both ``with`` and ``async with`` work with this.
Example Usage: ::
async with channel.typing():
# simulate something heavy
await asyncio.sleep(10)
Expand Down
6 changes: 3 additions & 3 deletions discord/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,11 @@ def _from_guild_icon(cls, state, guild_id: int, icon_hash: str) -> Asset:
)

@classmethod
def _from_sticker(cls, state, sticker_id: int, sticker_hash: str) -> Asset:
def _from_sticker_banner(cls, state, banner: int) -> Asset:
return cls(
state,
url=f'{cls.BASE}/stickers/{sticker_id}/{sticker_hash}.png?size=1024',
key=sticker_hash,
url=f'{cls.BASE}/app-assets/710982414301790216/store/{banner}.png',
key=str(banner),
animated=False,
)

Expand Down
27 changes: 19 additions & 8 deletions discord/audit_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from .types.snowflake import Snowflake
from .user import User
from .stage_instance import StageInstance
from .sticker import GuildSticker
from .threads import Thread


Expand All @@ -79,16 +80,15 @@ def _transform_channel(entry: AuditLogEntry, data: Optional[Snowflake]) -> Optio
return entry.guild.get_channel(int(data)) or Object(id=data)


def _transform_owner_id(entry: AuditLogEntry, data: Optional[Snowflake]) -> Union[Member, User, None]:
def _transform_member_id(entry: AuditLogEntry, data: Optional[Snowflake]) -> Union[Member, User, None]:
if data is None:
return None
return entry._get_member(int(data))


def _transform_inviter_id(entry: AuditLogEntry, data: Optional[Snowflake]) -> Union[Member, User, None]:
def _transform_guild_id(entry: AuditLogEntry, data: Optional[Snowflake]) -> Optional[Guild]:
if data is None:
return None
return entry._get_member(int(data))
return entry._state._get_guild(data)


def _transform_overwrites(
Expand Down Expand Up @@ -146,6 +146,11 @@ def _transform(entry: AuditLogEntry, data: int) -> T:

return _transform

def _transform_type(entry: AuditLogEntry, data: Union[int]) -> Union[enums.ChannelType, enums.StickerType]:
if entry.action.name.startswith('sticker_'):
return enums.try_enum(enums.StickerType, data)
else:
return enums.try_enum(enums.ChannelType, data)

class AuditLogDiff:
def __len__(self) -> int:
Expand Down Expand Up @@ -180,8 +185,8 @@ class AuditLogChanges:
'permissions': (None, _transform_permissions),
'id': (None, _transform_snowflake),
'color': ('colour', _transform_color),
'owner_id': ('owner', _transform_owner_id),
'inviter_id': ('inviter', _transform_inviter_id),
'owner_id': ('owner', _transform_member_id),
'inviter_id': ('inviter', _transform_member_id),
'channel_id': ('channel', _transform_channel),
'afk_channel_id': ('afk_channel', _transform_channel),
'system_channel_id': ('system_channel', _transform_channel),
Expand All @@ -195,12 +200,15 @@ class AuditLogChanges:
'icon_hash': ('icon', _transform_icon),
'avatar_hash': ('avatar', _transform_avatar),
'rate_limit_per_user': ('slowmode_delay', None),
'guild_id': ('guild', _transform_guild_id),
'tags': ('emoji', None),
'default_message_notifications': ('default_notifications', _enum_transformer(enums.NotificationLevel)),
'region': (None, _enum_transformer(enums.VoiceRegion)),
'rtc_region': (None, _enum_transformer(enums.VoiceRegion)),
'video_quality_mode': (None, _enum_transformer(enums.VideoQualityMode)),
'privacy_level': (None, _enum_transformer(enums.StagePrivacyLevel)),
'type': (None, _enum_transformer(enums.ChannelType)),
'format_type': (None, _enum_transformer(enums.StickerFormatType)),
'type': (None, _transform_type),
}
# fmt: on

Expand Down Expand Up @@ -438,7 +446,7 @@ def created_at(self) -> datetime.datetime:
return utils.snowflake_time(self.id)

@utils.cached_property
def target(self) -> Union[Guild, abc.GuildChannel, Member, User, Role, Invite, Emoji, Object, Thread, None]:
def target(self) -> Union[Guild, abc.GuildChannel, Member, User, Role, Invite, Emoji, StageInstance, GuildSticker, Thread, Object, None]:
try:
converter = getattr(self, '_convert_target_' + self.action.target_type)
except AttributeError:
Expand Down Expand Up @@ -509,5 +517,8 @@ def _convert_target_message(self, target_id: int) -> Union[Member, User, None]:
def _convert_target_stage_instance(self, target_id: int) -> Union[StageInstance, Object]:
return self.guild.get_stage_instance(target_id) or Object(id=target_id)

def _convert_target_sticker(self, target_id: int) -> Union[GuildSticker, Object]:
return self._state.get_sticker(target_id) or Object(id=target_id)

def _convert_target_thread(self, target_id: int) -> Union[Thread, Object]:
return self.guild.get_thread(target_id) or Object(id=target_id)
69 changes: 69 additions & 0 deletions discord/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
from .ui.view import View
from .stage_instance import StageInstance
from .threads import Thread
from .sticker import GuildSticker, StandardSticker, StickerPack, _sticker_factory

if TYPE_CHECKING:
from .abc import SnowflakeTime, PrivateChannel, GuildChannel, Snowflake
Expand Down Expand Up @@ -277,6 +278,14 @@ def emojis(self) -> List[Emoji]:
"""List[:class:`.Emoji`]: The emojis that the connected client has."""
return self._connection.emojis

@property
def stickers(self) -> List[GuildSticker]:
"""List[:class:`GuildSticker`]: The stickers that the connected client has.
.. versionadded:: 2.0
"""
return self._connection.stickers

@property
def cached_messages(self) -> Sequence[Message]:
"""Sequence[:class:`.Message`]: Read-only list of messages the connected client has cached.
Expand Down Expand Up @@ -777,6 +786,23 @@ def get_emoji(self, id) -> Optional[Emoji]:
"""
return self._connection.get_emoji(id)

def get_sticker(self, id: int) -> Optional[GuildSticker]:
"""Returns a guild sticker with the given ID.
.. versionadded:: 2.0
.. note::
To retrieve standard stickers, use :meth:`.fetch_sticker`.
or :meth:`.fetch_nitro_sticker_packs`.
Returns
--------
Optional[:class:`.GuildSticker`]
The sticker or ``None`` if not found.
"""
return self._connection.get_sticker(id)

def get_all_channels(self) -> Generator[GuildChannel, None, None]:
"""A generator that retrieves every :class:`.abc.GuildChannel` the client can 'access'.
Expand Down Expand Up @@ -1443,6 +1469,49 @@ async def fetch_webhook(self, webhook_id: int) -> Webhook:
data = await self.http.get_webhook(webhook_id)
return Webhook.from_state(data, state=self._connection)

async def fetch_sticker(self, sticker_id: int) -> Union[StandardSticker, GuildSticker]:
"""|coro|
Retrieves a :class:`.Sticker` with the specified ID.
.. versionadded:: 2.0
Raises
--------
:exc:`.HTTPException`
Retrieving the sticker failed.
:exc:`.NotFound`
Invalid sticker ID.
Returns
--------
Union[:class:`.StandardSticker`, :class:`.GuildSticker`]
The sticker you requested.
"""
data = await self.http.get_sticker(sticker_id)
cls, _ = _sticker_factory(data['type']) # type: ignore
return cls(state=self._connection, data=data) # type: ignore

async def fetch_nitro_sticker_packs(self) -> List[StickerPack]:
"""|coro|
Retrieves all available nitro sticker packs.
.. versionadded:: 2.0
Raises
-------
:exc:`.HTTPException`
Retrieving the sticker packs failed.
Returns
---------
List[:class:`.StickerPack`]
All available nitro sticker packs.
"""
data = await self.http.list_nitro_sticker_packs()
return [StickerPack(state=self._connection, data=pack) for pack in data['sticker_packs']]

async def create_dm(self, user: Snowflake) -> DMChannel:
"""|coro|
Expand Down
25 changes: 25 additions & 0 deletions discord/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
'ExpireBehaviour',
'ExpireBehavior',
'StickerType',
'StickerFormatType',
'InviteTarget',
'VideoQualityMode',
'ComponentType',
Expand Down Expand Up @@ -346,6 +347,9 @@ class AuditLogAction(Enum):
stage_instance_create = 83
stage_instance_update = 84
stage_instance_delete = 85
sticker_create = 90
sticker_update = 91
sticker_delete = 92
thread_create = 110
thread_update = 111
thread_delete = 112
Expand Down Expand Up @@ -393,6 +397,9 @@ def category(self) -> Optional[AuditLogActionCategory]:
AuditLogAction.stage_instance_create: AuditLogActionCategory.create,
AuditLogAction.stage_instance_update: AuditLogActionCategory.update,
AuditLogAction.stage_instance_delete: AuditLogActionCategory.delete,
AuditLogAction.sticker_create: AuditLogActionCategory.create,
AuditLogAction.sticker_update: AuditLogActionCategory.update,
AuditLogAction.sticker_delete: AuditLogActionCategory.delete,
AuditLogAction.thread_create: AuditLogActionCategory.create,
AuditLogAction.thread_update: AuditLogActionCategory.update,
AuditLogAction.thread_delete: AuditLogActionCategory.delete,
Expand Down Expand Up @@ -427,6 +434,8 @@ def target_type(self) -> Optional[str]:
return 'integration'
elif v < 90:
return 'stage_instance'
elif v < 93:
return 'sticker'
elif v < 113:
return 'thread'

Expand Down Expand Up @@ -484,10 +493,26 @@ class ExpireBehaviour(Enum):


class StickerType(Enum):
standard = 1
guild = 2


class StickerFormatType(Enum):
png = 1
apng = 2
lottie = 3

@property
def file_extension(self) -> str:
# fmt: off
lookup: Dict[StickerFormatType, str] = {
StickerFormatType.png: 'png',
StickerFormatType.apng: 'png',
StickerFormatType.lottie: 'json',
}
# fmt: on
return lookup[self]


class InviteTarget(Enum):
unknown = 0
Expand Down
Loading

0 comments on commit 60d82cf

Please sign in to comment.