Skip to content

Commit e0a4745

Browse files
committed
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord into get_or_fetch
2 parents ea555a1 + 6c6e33a commit e0a4745

File tree

19 files changed

+398
-24
lines changed

19 files changed

+398
-24
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ These changes are available on the `master` branch, but have not yet been releas
6565
([#2801](https://github.com/Pycord-Development/pycord/pull/2801))
6666
- Added `Guild.get_or_fetch()` and `Client.get_or_fetch()` shortcut methods.
6767
([#2776](https://github.com/Pycord-Development/pycord/pull/2776))
68+
- Added `User.nameplate` property.
69+
([#2817](https://github.com/Pycord-Development/pycord/pull/2817))
70+
- Added role gradients support with `Role.colours` and the `RoleColours` class.
71+
([#2818](https://github.com/Pycord-Development/pycord/pull/2818))
6872

6973
### Fixed
7074

@@ -121,6 +125,9 @@ These changes are available on the `master` branch, but have not yet been releas
121125
([#2761](https://github.com/Pycord-Development/pycord/pull/2761))
122126
- Updated `valid_locales` to support `in` and `es-419`.
123127
([#2767](https://github.com/Pycord-Development/pycord/pull/2767))
128+
- Added support for emoji aliases like `:smile:` in PartialEmoji.from_str. Also applied
129+
the same logic in PartialEmojiConverter.
130+
([#2815](https://github.com/Pycord-Development/pycord/pull/2815))
124131
- Fixed `Webhook.edit` not working with `attachments=[]`.
125132
([#2779](https://github.com/Pycord-Development/pycord/pull/2779))
126133
- Fixed GIF-based `Sticker` returning the wrong `url`.

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ include LICENSE
33
include requirements.txt
44
include discord/bin/*.dll
55
include discord/py.typed
6+
include discord/emojis.json
67

78
prune .github
89
prune docs

discord/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from .channel import *
3636
from .client import *
3737
from .cog import *
38+
from .collectibles import *
3839
from .colour import *
3940
from .commands import *
4041
from .components import *

discord/client.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
Generator,
4040
Sequence,
4141
TypeVar,
42-
overload,
43-
Literal,
4442
)
4543

4644
import aiohttp
@@ -249,9 +247,9 @@ def __init__(
249247
self.loop: asyncio.AbstractEventLoop = (
250248
asyncio.get_event_loop() if loop is None else loop
251249
)
252-
self._listeners: dict[
253-
str, list[tuple[asyncio.Future, Callable[..., bool]]]
254-
] = {}
250+
self._listeners: dict[str, list[tuple[asyncio.Future, Callable[..., bool]]]] = (
251+
{}
252+
)
255253
self.shard_id: int | None = options.get("shard_id")
256254
self.shard_count: int | None = options.get("shard_count")
257255

discord/collectibles.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2021-present Pycord Development
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a
7+
copy of this software and associated documentation files (the "Software"),
8+
to deal in the Software without restriction, including without limitation
9+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
10+
and/or sell copies of the Software, and to permit persons to whom the
11+
Software is furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22+
DEALINGS IN THE SOFTWARE.
23+
"""
24+
25+
from typing import TYPE_CHECKING
26+
27+
if TYPE_CHECKING:
28+
from .state import ConnectionState
29+
30+
from .asset import Asset
31+
from .types.collectibles import Nameplate as NameplatePayload
32+
33+
34+
class Nameplate:
35+
"""
36+
Represents a Discord Nameplate.
37+
38+
.. versionadded:: 2.7
39+
40+
Attributes
41+
----------
42+
sku_id: int
43+
The SKU ID of the nameplate.
44+
palette: str
45+
The color palette of the nameplate.
46+
"""
47+
48+
def __init__(self, data: NameplatePayload, state: "ConnectionState") -> None:
49+
self.sku_id: int = data["sku_id"]
50+
self.palette: str = data["palette"]
51+
self._label: str = data["label"]
52+
self._asset: str = data["asset"]
53+
self._state: "ConnectionState" = state
54+
55+
def __repr__(self) -> str:
56+
return f"<Nameplate sku_id={self.sku_id} palette={self.palette}>"
57+
58+
def get_asset(self, animated: bool = False) -> Asset:
59+
"""Returns the asset of the nameplate.
60+
61+
Parameters
62+
----------
63+
animated: :class:`bool`
64+
Whether to return the animated version of the asset, in webm version. Defaults to ``False``.
65+
"""
66+
fn = "static.png" if not animated else "asset.webm"
67+
return Asset(
68+
state=self._state,
69+
url=f"{Asset.BASE}/assets/collectibles/{self._asset}{fn}",
70+
key=self._asset.split("/")[-1],
71+
animated=animated,
72+
)
73+
74+
75+
__all__ = ("Nameplate",)

discord/components.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,18 +670,36 @@ class UnfurledMediaItem(AssetMixin):
670670
def __init__(self, url: str):
671671
self._state = None
672672
self._url: str = url
673+
self._static_url: str | None = (
674+
url if url and url.startswith("attachment://") else None
675+
)
673676
self.proxy_url: str | None = None
674677
self.height: int | None = None
675678
self.width: int | None = None
676679
self.content_type: str | None = None
677680
self.flags: AttachmentFlags | None = None
678681
self.attachment_id: int | None = None
679682

683+
def __repr__(self) -> str:
684+
return (
685+
f"<UnfurledMediaItem url={self.url!r} attachment_id={self.attachment_id}>"
686+
)
687+
688+
def __str__(self) -> str:
689+
return self.url or self.__repr__()
690+
680691
@property
681692
def url(self) -> str:
682693
"""Returns this media item's url."""
683694
return self._url
684695

696+
@url.setter
697+
def url(self, value: str) -> None:
698+
self._url = value
699+
self._static_url = (
700+
value if value and value.startswith("attachment://") else None
701+
)
702+
685703
@classmethod
686704
def from_dict(cls, data: UnfurledMediaItemPayload, state=None) -> UnfurledMediaItem:
687705

@@ -696,7 +714,7 @@ def from_dict(cls, data: UnfurledMediaItemPayload, state=None) -> UnfurledMediaI
696714
return r
697715

698716
def to_dict(self) -> dict[str, str]:
699-
return {"url": self.url}
717+
return {"url": self._static_url or self.url}
700718

701719

702720
class Thumbnail(Component):

discord/emojis.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

discord/ext/commands/converter.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
)
4242

4343
import discord
44+
from discord.utils import UNICODE_EMOJIS
4445

4546
from .errors import *
4647

@@ -851,7 +852,8 @@ async def convert(self, ctx: Context, argument: str) -> discord.GuildEmoji:
851852
class PartialEmojiConverter(Converter[discord.PartialEmoji]):
852853
"""Converts to a :class:`~discord.PartialEmoji`.
853854
854-
This is done by extracting the animated flag, name and ID from the emoji.
855+
This is done by extracting the animated flag, name, and ID for custom emojis,
856+
or by using the standard Unicode emojis supported by Discord.
855857
856858
.. versionchanged:: 1.5
857859
Raise :exc:`.PartialEmojiConversionFailure` instead of generic :exc:`.BadArgument`
@@ -872,6 +874,14 @@ async def convert(self, ctx: Context, argument: str) -> discord.PartialEmoji:
872874
id=emoji_id,
873875
)
874876

877+
if argument in UNICODE_EMOJIS:
878+
return discord.PartialEmoji.with_state(
879+
ctx.bot._connection,
880+
animated=False,
881+
name=argument,
882+
id=None,
883+
)
884+
875885
raise PartialEmojiConversionFailure(argument)
876886

877887

@@ -1094,7 +1104,11 @@ def get_converter(param: inspect.Parameter) -> Any:
10941104

10951105

10961106
def is_generic_type(tp: Any, *, _GenericAlias: type = _GenericAlias) -> bool:
1097-
return isinstance(tp, type) and issubclass(tp, Generic) or isinstance(tp, _GenericAlias) # type: ignore
1107+
return (
1108+
isinstance(tp, type)
1109+
and issubclass(tp, Generic)
1110+
or isinstance(tp, _GenericAlias)
1111+
) # type: ignore
10981112

10991113

11001114
CONVERTER_MAPPING: dict[type[Any], Any] = {

discord/guild.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
Tuple,
3939
Union,
4040
overload,
41-
Literal,
4241
)
4342

4443
from . import abc, utils
@@ -80,7 +79,7 @@
8079
from .monetization import Entitlement
8180
from .onboarding import Onboarding
8281
from .permissions import PermissionOverwrite
83-
from .role import Role
82+
from .role import Role, RoleColours
8483
from .scheduled_events import ScheduledEvent, ScheduledEventLocation
8584
from .stage_instance import StageInstance
8685
from .sticker import GuildSticker
@@ -2981,6 +2980,8 @@ async def create_role(
29812980
name: str = ...,
29822981
permissions: Permissions = ...,
29832982
colour: Colour | int = ...,
2983+
colours: RoleColours = ...,
2984+
holographic: bool = ...,
29842985
hoist: bool = ...,
29852986
mentionable: bool = ...,
29862987
icon: bytes | None = MISSING,
@@ -2995,6 +2996,8 @@ async def create_role(
29952996
name: str = ...,
29962997
permissions: Permissions = ...,
29972998
color: Colour | int = ...,
2999+
colors: RoleColours = ...,
3000+
holographic: bool = ...,
29983001
hoist: bool = ...,
29993002
mentionable: bool = ...,
30003003
icon: bytes | None = ...,
@@ -3008,6 +3011,9 @@ async def create_role(
30083011
permissions: Permissions = MISSING,
30093012
color: Colour | int = MISSING,
30103013
colour: Colour | int = MISSING,
3014+
colors: RoleColours = MISSING,
3015+
colours: RoleColours = MISSING,
3016+
holographic: bool = MISSING,
30113017
hoist: bool = MISSING,
30123018
mentionable: bool = MISSING,
30133019
reason: str | None = None,
@@ -3071,11 +3077,30 @@ async def create_role(
30713077
else:
30723078
fields["permissions"] = "0"
30733079

3074-
actual_colour = colour or color or Colour.default()
3080+
actual_colour = colour if colour not in (MISSING, None) else color
3081+
30753082
if isinstance(actual_colour, int):
3076-
fields["color"] = actual_colour
3083+
actual_colour = Colour(actual_colour)
3084+
3085+
if actual_colour not in (MISSING, None):
3086+
utils.warn_deprecated("colour", "colours", "2.7")
3087+
actual_colours = RoleColours(primary=actual_colour)
3088+
elif holographic:
3089+
actual_colours = RoleColours.holographic()
3090+
else:
3091+
actual_colours = colours or colors or RoleColours.default()
3092+
3093+
if isinstance(actual_colours, RoleColours):
3094+
if "ENHANCED_ROLE_COLORS" not in self.features:
3095+
actual_colours.secondary = None
3096+
actual_colours.tertiary = None
3097+
fields["colors"] = actual_colours._to_dict()
30773098
else:
3078-
fields["color"] = actual_colour.value
3099+
raise InvalidArgument(
3100+
"colours parameter must be of type RoleColours, not {0.__class__.__name__}".format(
3101+
actual_colours
3102+
)
3103+
)
30793104

30803105
if hoist is not MISSING:
30813106
fields["hoist"] = hoist

discord/http.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,6 +2163,7 @@ def edit_role(
21632163
"name",
21642164
"permissions",
21652165
"color",
2166+
"colors",
21662167
"hoist",
21672168
"mentionable",
21682169
"icon",

0 commit comments

Comments
 (0)