Skip to content

Commit d8ea995

Browse files
committed
NQN specific changes
Compute send message permissions in threads properly Flags should be optional Allow various cv2 components to be used with nqn_common components Add `serialise` to base components, and remove fields on media items that are receive only
1 parent bd329b1 commit d8ea995

File tree

12 files changed

+93
-44
lines changed

12 files changed

+93
-44
lines changed

discord/components.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ def _raw_construct(cls, **kwargs) -> Self:
165165
def to_dict(self) -> ComponentPayload:
166166
raise NotImplementedError
167167

168+
async def serialise(self, ctx) -> ComponentPayload:
169+
return self.to_dict()
170+
168171

169172
class ActionRow(Component):
170173
"""Represents a Discord Bot UI Kit Action Row.

discord/emoji.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def __init__(self, *, guild: Snowflake, state: ConnectionState, data: EmojiPaylo
120120
self._from_data(data)
121121

122122
def _from_data(self, emoji: EmojiPayload) -> None:
123-
self.require_colons: bool = emoji.get('require_colons', False)
123+
self.require_colons: bool = emoji.get('require_colons', True)
124124
self.managed: bool = emoji.get('managed', False)
125125
self.id: int = int(emoji['id']) # type: ignore # This won't be None for full emoji objects.
126126
self.name: str = emoji['name'] # type: ignore # This won't be None for full emoji objects.

discord/guild.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -598,16 +598,8 @@ def _from_data(self, guild: GuildPayload) -> None:
598598
role = Role(guild=self, data=r, state=state)
599599
self._roles[role.id] = role
600600

601-
self.emojis: Tuple[Emoji, ...] = (
602-
tuple(map(lambda d: state.store_emoji(self, d), guild.get('emojis', [])))
603-
if state.cache_guild_expressions
604-
else ()
605-
)
606-
self.stickers: Tuple[GuildSticker, ...] = (
607-
tuple(map(lambda d: state.store_sticker(self, d), guild.get('stickers', [])))
608-
if state.cache_guild_expressions
609-
else ()
610-
)
601+
self.emojis: Tuple[Emoji, ...] = tuple(map(lambda d: state.store_emoji(self, d), guild.get('emojis', [])))
602+
self.stickers: Tuple[GuildSticker, ...] = ()
611603
self.features: List[GuildFeature] = guild.get('features', [])
612604
self._splash: Optional[str] = guild.get('splash')
613605
self._system_channel_id: Optional[int] = utils._get_as_snowflake(guild, 'system_channel_id')

discord/http.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,46 @@ def follow_webhook(
14471447
Route('POST', '/channels/{channel_id}/followers', channel_id=channel_id), json=payload, reason=reason
14481448
)
14491449

1450+
def edit_webhook_message(self, webhook_id, webhook_token, message_id, thread_id=None, **fields):
1451+
if thread_id is None:
1452+
r = Route(
1453+
'PATCH',
1454+
'/webhooks/{webhook_id}/{webhook_token}/messages/{message_id}',
1455+
webhook_id=webhook_id,
1456+
webhook_token=webhook_token,
1457+
message_id=message_id
1458+
)
1459+
else:
1460+
r = Route(
1461+
'PATCH',
1462+
'/webhooks/{webhook_id}/{webhook_token}/messages/{message_id}?thread_id={thread_id}',
1463+
webhook_id=webhook_id,
1464+
webhook_token=webhook_token,
1465+
message_id=message_id,
1466+
thread_id=thread_id
1467+
)
1468+
return self.request(r, json=fields)
1469+
1470+
def delete_webhook_message(self, webhook_id, webhook_token, message_id, thread_id=None):
1471+
if thread_id is None:
1472+
r = Route(
1473+
'DELETE',
1474+
'/webhooks/{webhook_id}/{webhook_token}/messages/{message_id}',
1475+
webhook_id=webhook_id,
1476+
webhook_token=webhook_token,
1477+
message_id=message_id
1478+
)
1479+
else:
1480+
r = Route(
1481+
'DELETE',
1482+
'/webhooks/{webhook_id}/{webhook_token}/messages/{message_id}?thread_id={thread_id}',
1483+
webhook_id=webhook_id,
1484+
webhook_token=webhook_token,
1485+
message_id=message_id,
1486+
thread_id=thread_id
1487+
)
1488+
return self.request(r)
1489+
14501490
# Guild management
14511491

14521492
def get_guilds(

discord/member.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ def __init__(self, *, data: MemberWithUserPayload, guild: Guild, state: Connecti
328328
self._avatar: Optional[str] = data.get('avatar')
329329
self._banner: Optional[str] = data.get('banner')
330330
self._permissions: Optional[int]
331-
self._flags: int = data['flags']
331+
self._flags: int = data.get('flags', 0)
332332
self._avatar_decoration_data: Optional[AvatarDecorationData] = data.get('avatar_decoration_data')
333333
try:
334334
self._permissions = int(data['permissions']) # pyright: ignore[reportTypedDictNotRequiredAccess]

discord/message.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
from .mixins import Hashable
6464
from .sticker import StickerItem, GuildSticker
6565
from .threads import Thread
66+
from .user import User
6667
from .channel import PartialMessageable
6768
from .poll import Poll
6869

@@ -2452,11 +2453,7 @@ def _handle_nonce(self, value: Union[str, int]) -> None:
24522453
self.nonce = value
24532454

24542455
def _handle_author(self, author: UserPayload) -> None:
2455-
self.author = self._state.store_user(author, cache=self.webhook_id is None)
2456-
if isinstance(self.guild, Guild):
2457-
found = self.guild.get_member(self.author.id)
2458-
if found is not None:
2459-
self.author = found
2456+
self.author = User(state=self._state, data=author)
24602457

24612458
def _handle_member(self, member: MemberPayload) -> None:
24622459
# The gateway now gives us full Member objects sometimes with the following keys
@@ -2497,7 +2494,7 @@ def _handle_mention_roles(self, role_mentions: List[int]) -> None:
24972494
if role is not None:
24982495
self.role_mentions.append(role)
24992496

2500-
def _handle_components(self, data: List[ComponentPayload]) -> None:
2497+
def _handle_components(self, data: List[ComponentPayload]):
25012498
self.components = []
25022499

25032500
for component_data in data:

discord/state.py

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -381,16 +381,10 @@ def _update_references(self, ws: DiscordWebSocket) -> None:
381381
for vc in self.voice_clients:
382382
vc.main_ws = ws # type: ignore # Silencing the unknown attribute (ok at runtime).
383383

384-
def store_user(self, data: Union[UserPayload, PartialUserPayload], *, cache: bool = True) -> User:
385-
# this way is 300% faster than `dict.setdefault`.
386-
user_id = int(data['id'])
387-
try:
388-
return self._users[user_id]
389-
except KeyError:
390-
user = User(state=self, data=data)
391-
if cache:
392-
self._users[user_id] = user
393-
return user
384+
def store_user(self, data: UserPayload) -> User:
385+
if isinstance(data, User):
386+
return data
387+
return User(state=self, data=data)
394388

395389
def store_user_no_intents(self, data: Union[UserPayload, PartialUserPayload], *, cache: bool = True) -> User:
396390
return User(state=self, data=data)
@@ -402,20 +396,13 @@ def get_user(self, id: int) -> Optional[User]:
402396
return self._users.get(id)
403397

404398
def store_emoji(self, guild: Guild, data: EmojiPayload) -> Emoji:
405-
# the id will be present here
406-
emoji_id = int(data['id']) # type: ignore
407-
self._emojis[emoji_id] = emoji = Emoji(guild=guild, state=self, data=data)
408-
return emoji
399+
return Emoji(guild=guild, state=self, data=data)
409400

410401
def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker:
411-
sticker_id = int(data['id'])
412-
self._stickers[sticker_id] = sticker = GuildSticker(state=self, data=data)
413-
return sticker
402+
pass
414403

415404
def store_view(self, view: BaseView, message_id: Optional[int] = None, interaction_id: Optional[int] = None) -> None:
416-
if interaction_id is not None:
417-
self._view_store.remove_interaction_mapping(interaction_id)
418-
self._view_store.add_view(view, message_id)
405+
pass
419406

420407
def prevent_view_updates_for(self, message_id: int) -> Optional[BaseView]:
421408
return self._view_store.remove_message_tracking(message_id)

discord/threads.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,19 @@ def _update(self, data: ThreadPayload) -> None:
228228
except KeyError:
229229
pass
230230

231+
def overwrites_for(self, obj, /) -> PermissionOverwrite:
232+
parent = self.parent
233+
if parent is None:
234+
raise ClientException('Parent channel not found')
235+
return parent.overwrites_for(obj)
236+
237+
@property
238+
def _overwrites(self):
239+
parent = self.parent
240+
if parent is None:
241+
raise ClientException('Parent channel not found')
242+
return parent._overwrites
243+
231244
@property
232245
def type(self) -> ThreadChannelType:
233246
""":class:`ChannelType`: The channel's Discord type."""

discord/ui/action_row.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ def add_item(self, item: Item[Any]) -> Self:
267267
if self._view:
268268
self._view._add_count(1)
269269

270-
item._update_view(self.view)
270+
# item._update_view(self.view)
271271
item._parent = self
272272
self._weight += 1
273273
self._children.append(item)

discord/ui/container.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
from __future__ import annotations
2626

27+
import asyncio
2728
import copy
2829
from typing import (
2930
TYPE_CHECKING,
@@ -242,6 +243,10 @@ def _total_count(self) -> int:
242243
def _is_v2(self) -> bool:
243244
return True
244245

246+
async def serialise(self, ctx) -> Dict[str, Any]:
247+
components = await asyncio.gather(*[child.serialise(ctx) for child in self._children])
248+
return self._to_component_dict(components)
249+
245250
def to_components(self) -> List[Dict[str, Any]]:
246251
components = []
247252
for i in self._children:
@@ -250,7 +255,9 @@ def to_components(self) -> List[Dict[str, Any]]:
250255

251256
def to_component_dict(self) -> Dict[str, Any]:
252257
components = self.to_components()
258+
return self._to_component_dict(components)
253259

260+
def _to_component_dict(self, components: List[Dict[str, Any]]):
254261
colour = None
255262
if self._colour:
256263
colour = self._colour if isinstance(self._colour, int) else self._colour.value
@@ -315,14 +322,14 @@ def add_item(self, item: Item[Any]) -> Self:
315322
ValueError
316323
Maximum number of children has been exceeded (40) for the entire view.
317324
"""
318-
if not isinstance(item, Item):
319-
raise TypeError(f'expected Item not {item.__class__.__name__}')
325+
# if not isinstance(item, Item):
326+
# raise TypeError(f'expected Item not {item.__class__.__name__}')
320327

321328
if self._view:
322329
self._view._add_count(item._total_count)
323330

324331
self._children.append(item)
325-
item._update_view(self.view)
332+
# item._update_view(self.view)
326333
item._parent = self
327334
return self
328335

0 commit comments

Comments
 (0)