mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-15 18:29:52 +00:00
Add support for guild banners
Document banner attribute of Guild and Invite Update discord/utils.py Co-Authored-By: SnowyLuma <38926001+SnowyLuma@users.noreply.github.com>
This commit is contained in:
parent
616616b847
commit
42a7c4f7e5
@ -95,6 +95,8 @@ class Guild(Hashable):
|
|||||||
all be None. It is best to not do anything with the guild if it is unavailable.
|
all be None. It is best to not do anything with the guild if it is unavailable.
|
||||||
|
|
||||||
Check the :func:`on_guild_unavailable` and :func:`on_guild_available` events.
|
Check the :func:`on_guild_unavailable` and :func:`on_guild_available` events.
|
||||||
|
banner: Optional[:class:`str`]
|
||||||
|
The guild's banner.
|
||||||
mfa_level: :class:`int`
|
mfa_level: :class:`int`
|
||||||
Indicates the guild's two factor authorisation level. If this value is 0 then
|
Indicates the guild's two factor authorisation level. If this value is 0 then
|
||||||
the guild does not require 2FA for their administrative members. If the value is
|
the guild does not require 2FA for their administrative members. If the value is
|
||||||
@ -119,7 +121,7 @@ class Guild(Hashable):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('afk_timeout', 'afk_channel', '_members', '_channels', 'icon',
|
__slots__ = ('afk_timeout', 'afk_channel', '_members', '_channels', 'icon',
|
||||||
'name', 'id', 'unavailable', 'name', 'region', '_state',
|
'name', 'id', 'unavailable', 'banner', 'region', '_state',
|
||||||
'_default_role', '_roles', '_member_count', '_large',
|
'_default_role', '_roles', '_member_count', '_large',
|
||||||
'owner_id', 'mfa_level', 'emojis', 'features',
|
'owner_id', 'mfa_level', 'emojis', 'features',
|
||||||
'verification_level', 'explicit_content_filter', 'splash',
|
'verification_level', 'explicit_content_filter', 'splash',
|
||||||
@ -211,6 +213,7 @@ class Guild(Hashable):
|
|||||||
self.explicit_content_filter = try_enum(ContentFilter, guild.get('explicit_content_filter', 0))
|
self.explicit_content_filter = try_enum(ContentFilter, guild.get('explicit_content_filter', 0))
|
||||||
self.afk_timeout = guild.get('afk_timeout')
|
self.afk_timeout = guild.get('afk_timeout')
|
||||||
self.icon = guild.get('icon')
|
self.icon = guild.get('icon')
|
||||||
|
self.banner = guild.get('banner')
|
||||||
self.unavailable = guild.get('unavailable', False)
|
self.unavailable = guild.get('unavailable', False)
|
||||||
self.id = int(guild['id'])
|
self.id = int(guild['id'])
|
||||||
self._roles = {}
|
self._roles = {}
|
||||||
@ -409,7 +412,7 @@ class Guild(Hashable):
|
|||||||
"""Returns a friendly URL version of the guild's icon. Returns an empty string if it has no icon.
|
"""Returns a friendly URL version of the guild's icon. Returns an empty string if it has no icon.
|
||||||
|
|
||||||
The format must be one of 'webp', 'jpeg', 'jpg', or 'png'. The
|
The format must be one of 'webp', 'jpeg', 'jpg', or 'png'. The
|
||||||
size must be a power of 2 between 16 and 2048.
|
size must be a power of 2 between 16 and 4096.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -429,7 +432,7 @@ class Guild(Hashable):
|
|||||||
Bad image format passed to ``format`` or invalid ``size``.
|
Bad image format passed to ``format`` or invalid ``size``.
|
||||||
"""
|
"""
|
||||||
if not valid_icon_size(size):
|
if not valid_icon_size(size):
|
||||||
raise InvalidArgument("size must be a power of 2 between 16 and 2048")
|
raise InvalidArgument("size must be a power of 2 between 16 and 4096")
|
||||||
if format not in VALID_ICON_FORMATS:
|
if format not in VALID_ICON_FORMATS:
|
||||||
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
||||||
|
|
||||||
@ -438,6 +441,44 @@ class Guild(Hashable):
|
|||||||
|
|
||||||
return 'https://cdn.discordapp.com/icons/{0.id}/{0.icon}.{1}?size={2}'.format(self, format, size)
|
return 'https://cdn.discordapp.com/icons/{0.id}/{0.icon}.{1}?size={2}'.format(self, format, size)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def banner_url(self):
|
||||||
|
"""Returns the URL version of the guild's banner. Returns an empty string if it has no banner."""
|
||||||
|
return self.banner_url_as()
|
||||||
|
|
||||||
|
def banner_url_as(self, *, format='webp', size=2048):
|
||||||
|
"""Returns a friendly URL version of the guild's banner. Returns an empty string if it has no banner.
|
||||||
|
|
||||||
|
The format must be one of 'webp', 'jpeg', or 'png'. The
|
||||||
|
size must be a power of 2 between 16 and 4096.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
format: str
|
||||||
|
The format to attempt to convert the banner to.
|
||||||
|
size: int
|
||||||
|
The size of the image to display.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
str
|
||||||
|
The resulting CDN URL.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
InvalidArgument
|
||||||
|
Bad image format passed to ``format`` or invalid ``size``.
|
||||||
|
"""
|
||||||
|
if not valid_icon_size(size):
|
||||||
|
raise InvalidArgument("size must be a power of 2 between 16 and 4096")
|
||||||
|
if format not in VALID_ICON_FORMATS:
|
||||||
|
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
||||||
|
|
||||||
|
if self.banner is None:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
return 'https://cdn.discordapp.com/banners/{0.id}/{0.banner}.{1}?size={2}'.format(self, format, size)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def splash_url(self):
|
def splash_url(self):
|
||||||
"""Returns the URL version of the guild's invite splash. Returns an empty string if it has no splash."""
|
"""Returns the URL version of the guild's invite splash. Returns an empty string if it has no splash."""
|
||||||
@ -447,7 +488,7 @@ class Guild(Hashable):
|
|||||||
"""Returns a friendly URL version of the guild's invite splash. Returns an empty string if it has no splash.
|
"""Returns a friendly URL version of the guild's invite splash. Returns an empty string if it has no splash.
|
||||||
|
|
||||||
The format must be one of 'webp', 'jpeg', 'jpg', or 'png'. The
|
The format must be one of 'webp', 'jpeg', 'jpg', or 'png'. The
|
||||||
size must be a power of 2 between 16 and 2048.
|
size must be a power of 2 between 16 and 4096.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -467,7 +508,7 @@ class Guild(Hashable):
|
|||||||
Bad image format passed to ``format`` or invalid ``size``.
|
Bad image format passed to ``format`` or invalid ``size``.
|
||||||
"""
|
"""
|
||||||
if not valid_icon_size(size):
|
if not valid_icon_size(size):
|
||||||
raise InvalidArgument("size must be a power of 2 between 16 and 2048")
|
raise InvalidArgument("size must be a power of 2 between 16 and 4096")
|
||||||
if format not in VALID_ICON_FORMATS:
|
if format not in VALID_ICON_FORMATS:
|
||||||
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
||||||
|
|
||||||
@ -764,6 +805,9 @@ class Guild(Hashable):
|
|||||||
icon: bytes
|
icon: bytes
|
||||||
A :term:`py:bytes-like object` representing the icon. Only PNG/JPEG supported.
|
A :term:`py:bytes-like object` representing the icon. Only PNG/JPEG supported.
|
||||||
Could be ``None`` to denote removal of the icon.
|
Could be ``None`` to denote removal of the icon.
|
||||||
|
banner: bytes
|
||||||
|
A :term:`py:bytes-like object` representing the banner.
|
||||||
|
Could be ``None`` to denote removal of the banner.
|
||||||
splash: bytes
|
splash: bytes
|
||||||
A :term:`py:bytes-like object` representing the invite splash.
|
A :term:`py:bytes-like object` representing the invite splash.
|
||||||
Only PNG/JPEG supported. Could be ``None`` to denote removing the
|
Only PNG/JPEG supported. Could be ``None`` to denote removing the
|
||||||
@ -814,6 +858,16 @@ class Guild(Hashable):
|
|||||||
else:
|
else:
|
||||||
icon = None
|
icon = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
banner_bytes = fields['banner']
|
||||||
|
except KeyError:
|
||||||
|
banner = self.banner
|
||||||
|
else:
|
||||||
|
if banner_bytes is not None:
|
||||||
|
banner = utils._bytes_to_base64_data(banner_bytes)
|
||||||
|
else:
|
||||||
|
banner = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vanity_code = fields['vanity_code']
|
vanity_code = fields['vanity_code']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -832,6 +886,7 @@ class Guild(Hashable):
|
|||||||
splash = None
|
splash = None
|
||||||
|
|
||||||
fields['icon'] = icon
|
fields['icon'] = icon
|
||||||
|
fields['banner'] = banner
|
||||||
fields['splash'] = splash
|
fields['splash'] = splash
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -568,7 +568,7 @@ class HTTPClient:
|
|||||||
valid_keys = ('name', 'region', 'icon', 'afk_timeout', 'owner_id',
|
valid_keys = ('name', 'region', 'icon', 'afk_timeout', 'owner_id',
|
||||||
'afk_channel_id', 'splash', 'verification_level',
|
'afk_channel_id', 'splash', 'verification_level',
|
||||||
'system_channel_id', 'default_message_notifications',
|
'system_channel_id', 'default_message_notifications',
|
||||||
'description', 'explicit_content_filter')
|
'description', 'explicit_content_filter', 'banner')
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
k: v for k, v in fields.items() if k in valid_keys
|
k: v for k, v in fields.items() if k in valid_keys
|
||||||
|
@ -81,7 +81,7 @@ class PartialInviteChannel(namedtuple('PartialInviteChannel', 'id name type')):
|
|||||||
"""Returns the channel's creation time in UTC."""
|
"""Returns the channel's creation time in UTC."""
|
||||||
return utils.snowflake_time(self.id)
|
return utils.snowflake_time(self.id)
|
||||||
|
|
||||||
class PartialInviteGuild(namedtuple('PartialInviteGuild', 'features icon id name splash verification_level')):
|
class PartialInviteGuild(namedtuple('PartialInviteGuild', 'features icon banner id name splash verification_level')):
|
||||||
"""Represents a "partial" invite guild.
|
"""Represents a "partial" invite guild.
|
||||||
|
|
||||||
This model will be given when the user is not part of the
|
This model will be given when the user is not part of the
|
||||||
@ -117,6 +117,8 @@ class PartialInviteGuild(namedtuple('PartialInviteGuild', 'features icon id name
|
|||||||
A list of features the guild has. See :attr:`Guild.features` for more information.
|
A list of features the guild has. See :attr:`Guild.features` for more information.
|
||||||
icon: Optional[:class:`str`]
|
icon: Optional[:class:`str`]
|
||||||
The partial guild's icon.
|
The partial guild's icon.
|
||||||
|
banner: Optional[:class:`str`]
|
||||||
|
The partial guild's banner.
|
||||||
splash: Optional[:class:`str`]
|
splash: Optional[:class:`str`]
|
||||||
The partial guild's invite splash.
|
The partial guild's invite splash.
|
||||||
"""
|
"""
|
||||||
@ -139,7 +141,7 @@ class PartialInviteGuild(namedtuple('PartialInviteGuild', 'features icon id name
|
|||||||
def icon_url_as(self, *, format='webp', size=1024):
|
def icon_url_as(self, *, format='webp', size=1024):
|
||||||
""":class:`str`: The same operation as :meth:`Guild.icon_url_as`."""
|
""":class:`str`: The same operation as :meth:`Guild.icon_url_as`."""
|
||||||
if not valid_icon_size(size):
|
if not valid_icon_size(size):
|
||||||
raise InvalidArgument("size must be a power of 2 between 16 and 2048")
|
raise InvalidArgument("size must be a power of 2 between 16 and 4096")
|
||||||
if format not in VALID_ICON_FORMATS:
|
if format not in VALID_ICON_FORMATS:
|
||||||
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
||||||
|
|
||||||
@ -148,6 +150,23 @@ class PartialInviteGuild(namedtuple('PartialInviteGuild', 'features icon id name
|
|||||||
|
|
||||||
return 'https://cdn.discordapp.com/icons/{0.id}/{0.icon}.{1}?size={2}'.format(self, format, size)
|
return 'https://cdn.discordapp.com/icons/{0.id}/{0.icon}.{1}?size={2}'.format(self, format, size)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def banner_url(self):
|
||||||
|
"""Returns the URL version of the guild's banner. Returns an empty string if it has no banner."""
|
||||||
|
return self.banner_url_as()
|
||||||
|
|
||||||
|
def banner_url_as(self, *, format='webp', size=2048):
|
||||||
|
""":class:`str`: The same operation as :meth:`Guild.banner_url_as`."""
|
||||||
|
if not valid_icon_size(size):
|
||||||
|
raise InvalidArgument("size must be a power of 2 between 16 and 4096")
|
||||||
|
if format not in VALID_ICON_FORMATS:
|
||||||
|
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
||||||
|
|
||||||
|
if self.banner is None:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
return 'https://cdn.discordapp.com/banners/{0.id}/{0.banner}.{1}?size={2}'.format(self, format, size)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def splash_url(self):
|
def splash_url(self):
|
||||||
"""Returns the URL version of the guild's invite splash. Returns an empty string if it has no splash."""
|
"""Returns the URL version of the guild's invite splash. Returns an empty string if it has no splash."""
|
||||||
@ -156,7 +175,7 @@ class PartialInviteGuild(namedtuple('PartialInviteGuild', 'features icon id name
|
|||||||
def splash_url_as(self, *, format='webp', size=2048):
|
def splash_url_as(self, *, format='webp', size=2048):
|
||||||
""":class:`str`: The same operation as :meth:`Guild.splash_url_as`."""
|
""":class:`str`: The same operation as :meth:`Guild.splash_url_as`."""
|
||||||
if not valid_icon_size(size):
|
if not valid_icon_size(size):
|
||||||
raise InvalidArgument("size must be a power of 2 between 16 and 2048")
|
raise InvalidArgument("size must be a power of 2 between 16 and 4096")
|
||||||
if format not in VALID_ICON_FORMATS:
|
if format not in VALID_ICON_FORMATS:
|
||||||
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
raise InvalidArgument("format must be one of {}".format(VALID_ICON_FORMATS))
|
||||||
|
|
||||||
@ -257,6 +276,7 @@ class Invite(Hashable):
|
|||||||
name=guild_data['name'],
|
name=guild_data['name'],
|
||||||
features=guild_data.get('features', []),
|
features=guild_data.get('features', []),
|
||||||
icon=guild_data.get('icon'),
|
icon=guild_data.get('icon'),
|
||||||
|
banner=guild_data.get('banner'),
|
||||||
splash=guild_data.get('splash'),
|
splash=guild_data.get('splash'),
|
||||||
verification_level=try_enum(VerificationLevel, guild_data.get('verification_level')))
|
verification_level=try_enum(VerificationLevel, guild_data.get('verification_level')))
|
||||||
data['guild'] = guild
|
data['guild'] = guild
|
||||||
|
@ -294,8 +294,8 @@ async def sane_wait_for(futures, *, timeout, loop):
|
|||||||
raise asyncio.TimeoutError()
|
raise asyncio.TimeoutError()
|
||||||
|
|
||||||
def valid_icon_size(size):
|
def valid_icon_size(size):
|
||||||
"""Icons must be power of 2 within [16, 2048]."""
|
"""Icons must be power of 2 within [16, 4096]."""
|
||||||
return not size & (size - 1) and size in range(16, 2049)
|
return not size & (size - 1) and size in range(16, 4097)
|
||||||
|
|
||||||
class SnowflakeList(array.array):
|
class SnowflakeList(array.array):
|
||||||
"""Internal data storage class to efficiently store a list of snowflakes.
|
"""Internal data storage class to efficiently store a list of snowflakes.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user