Skip to content

Commit a28e826

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 4fc23a0 commit a28e826

File tree

13 files changed

+100
-45
lines changed

13 files changed

+100
-45
lines changed

discord/components.py

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

183+
async def serialise(self, ctx) -> ComponentPayload:
184+
return self.to_dict()
185+
183186

184187
class BaseOption:
185188
"""Represents a base option for components that have options.

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
@@ -597,16 +597,8 @@ def _from_data(self, guild: GuildPayload) -> None:
597597
role = Role(guild=self, data=r, state=state)
598598
self._roles[role.id] = role
599599

600-
self.emojis: Tuple[Emoji, ...] = (
601-
tuple(map(lambda d: state.store_emoji(self, d), guild.get('emojis', [])))
602-
if state.cache_guild_expressions
603-
else ()
604-
)
605-
self.stickers: Tuple[GuildSticker, ...] = (
606-
tuple(map(lambda d: state.store_sticker(self, d), guild.get('stickers', [])))
607-
if state.cache_guild_expressions
608-
else ()
609-
)
600+
self.emojis: Tuple[Emoji, ...] = tuple(map(lambda d: state.store_emoji(self, d), guild.get('emojis', [])))
601+
self.stickers: Tuple[GuildSticker, ...] = ()
610602
self.features: List[GuildFeature] = guild.get('features', [])
611603
self._splash: Optional[str] = guild.get('splash')
612604
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
@@ -1444,6 +1444,46 @@ def follow_webhook(
14441444
Route('POST', '/channels/{channel_id}/followers', channel_id=channel_id), json=payload, reason=reason
14451445
)
14461446

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

14491489
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
@@ -272,7 +272,7 @@ def add_item(self, item: Item[Any]) -> Self:
272272
if self._view:
273273
self._view._add_count(1)
274274

275-
item._update_view(self.view)
275+
# item._update_view(self.view)
276276
item._parent = self
277277
self._weight += 1
278278
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,
@@ -233,6 +234,10 @@ def _total_count(self) -> int:
233234
def _is_v2(self) -> bool:
234235
return True
235236

237+
async def serialise(self, ctx) -> Dict[str, Any]:
238+
components = await asyncio.gather(*[child.serialise(ctx) for child in self._children])
239+
return self._to_component_dict(components)
240+
236241
def to_components(self) -> List[Dict[str, Any]]:
237242
components = []
238243
for i in self._children:
@@ -241,7 +246,9 @@ def to_components(self) -> List[Dict[str, Any]]:
241246

242247
def to_component_dict(self) -> Dict[str, Any]:
243248
components = self.to_components()
249+
return self._to_component_dict(components)
244250

251+
def _to_component_dict(self, components: List[Dict[str, Any]]):
245252
colour = None
246253
if self._colour:
247254
colour = self._colour if isinstance(self._colour, int) else self._colour.value
@@ -306,14 +313,14 @@ def add_item(self, item: Item[Any]) -> Self:
306313
ValueError
307314
Maximum number of children has been exceeded (40) for the entire view.
308315
"""
309-
if not isinstance(item, Item):
310-
raise TypeError(f'expected Item not {item.__class__.__name__}')
316+
# if not isinstance(item, Item):
317+
# raise TypeError(f'expected Item not {item.__class__.__name__}')
311318

312319
if self._view:
313320
self._view._add_count(item._total_count)
314321

315322
self._children.append(item)
316-
item._update_view(self.view)
323+
# item._update_view(self.view)
317324
item._parent = self
318325
return self
319326

0 commit comments

Comments
 (0)