Skip to content

Commit 46e7a98

Browse files
feat: Implement created_at property for models (#1190)
* feat: Implement `created_at` property for models * Update message.py * Update channel.py * ci: correct from checks. * fix: id of tag is not Snowflake object * docs: make id as Snowflake Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a9e97ca commit 46e7a98

File tree

8 files changed

+149
-45
lines changed

8 files changed

+149
-45
lines changed

interactions/api/models/channel.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,20 +308,29 @@ class Tags(ClientSerializerMixin): # helpers, hehe :D
308308
If the emoji is custom, it won't have name information.
309309
310310
:ivar str name: Name of the tag. The limit is up to 20 characters.
311-
:ivar int id: ID of the tag. Can also be 0 if manually created.
311+
:ivar Snowflake id: ID of the tag. Can also be 0 if manually created.
312312
:ivar bool moderated: A boolean denoting whether this tag can be removed/added by moderators with the :attr:`.Permissions.MANAGE_THREADS` permission.
313313
:ivar Optional[Emoji] emoji: The emoji to represent the tag, if any.
314314
315315
"""
316316

317317
# TODO: Rename these to discord-docs
318318
name: str = field()
319-
id: int = field()
319+
id: Snowflake = field(converter=Snowflake)
320320
moderated: bool = field()
321321
emoji: Optional[Emoji] = field(converter=Emoji, default=None)
322322

323323
# Maybe on post_attrs_init replace emoji object with one from cache for name population?
324324

325+
@property
326+
def created_at(self) -> datetime:
327+
"""
328+
.. versionadded:: 4.4.0
329+
330+
Returns when the tag was created.
331+
"""
332+
return self.id.timestamp
333+
325334
async def delete(
326335
self, channel_id: Union[int, str, Snowflake, "Channel"] # discord, why :hollow:
327336
) -> None:
@@ -577,6 +586,15 @@ def voice_states(self) -> List["VoiceState"]:
577586
states.extend(state for state in data if state.channel_id == self.id)
578587
return states
579588

589+
@property
590+
def created_at(self) -> datetime:
591+
"""
592+
.. versionadded:: 4.4.0
593+
594+
Returns when the channel was created.
595+
"""
596+
return self.id.timestamp
597+
580598
def history(
581599
self,
582600
start_at: Optional[Union[int, str, Snowflake, "Message"]] = MISSING,

interactions/api/models/emoji.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
from typing import TYPE_CHECKING, List, Optional, Union
23

34
from ...utils.attrs_utils import ClientSerializerMixin, convert_list, define, field
@@ -53,6 +54,15 @@ def format(self) -> str:
5354
else self.name
5455
)
5556

57+
@property
58+
def created_at(self) -> datetime:
59+
"""
60+
.. versionadded:: 4.4.0
61+
62+
Returns when the emoji was created.
63+
"""
64+
return self.id.timestamp
65+
5666
@classmethod
5767
async def get(
5868
cls,

interactions/api/models/guild.py

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,53 @@ def __attrs_post_init__(self): # sourcery skip: last-if-guard
495495
):
496496
member._extras["guild_id"] = self.id
497497

498+
@property
499+
def voice_states(self) -> List["VoiceState"]:
500+
"""
501+
.. versionadded:: 4.4.0
502+
503+
Gets all voice states of the guild.
504+
505+
:rtype: List[VoiceState]
506+
"""
507+
508+
if not self._client:
509+
raise LibraryException(code=13)
510+
511+
from .gw import VoiceState
512+
513+
states: List[VoiceState] = []
514+
515+
data = self._client.cache[VoiceState].values.values()
516+
states.extend(state for state in data if state.guild_id == self.id)
517+
return states
518+
519+
@property
520+
def mapped_voice_states(self) -> Dict[int, List["VoiceState"]]:
521+
"""
522+
.. versionadded:: 4.4.0
523+
524+
Returns all the voice states mapped after their channel id.
525+
526+
:rtype: Dict[int, List[VoiceState]]
527+
"""
528+
states = self.voice_states
529+
_states: Dict[int, List[VoiceState]] = {int(state.channel_id): [] for state in states}
530+
531+
for state in states:
532+
_states[int(state.channel_id)].append(state)
533+
534+
return _states
535+
536+
@property
537+
def created_at(self) -> datetime:
538+
"""
539+
.. versionadded:: 4.4.0
540+
541+
Returns when the guild was created.
542+
"""
543+
return self.id.timestamp
544+
498545
async def ban(
499546
self,
500547
member_id: Union[int, Member, Snowflake],
@@ -550,44 +597,6 @@ async def ban(
550597
if int(member.id) == _member_id:
551598
return self.members.remove(member)
552599

553-
@property
554-
def voice_states(self) -> List["VoiceState"]:
555-
"""
556-
.. versionadded:: 4.4.0
557-
558-
Gets all voice states of the guild.
559-
560-
:rtype: List[VoiceState]
561-
"""
562-
563-
if not self._client:
564-
raise LibraryException(code=13)
565-
566-
from .gw import VoiceState
567-
568-
states: List[VoiceState] = []
569-
570-
data = self._client.cache[VoiceState].values.values()
571-
states.extend(state for state in data if state.guild_id == self.id)
572-
return states
573-
574-
@property
575-
def mapped_voice_states(self) -> Dict[int, List["VoiceState"]]:
576-
"""
577-
.. versionadded:: 4.4.0
578-
579-
Returns all the voice states mapped after their channel id.
580-
581-
:rtype: Dict[int, List[VoiceState]]
582-
"""
583-
states = self.voice_states
584-
_states: Dict[int, List[VoiceState]] = {int(state.channel_id): [] for state in states}
585-
586-
for state in states:
587-
_states[int(state.channel_id)].append(state)
588-
589-
return _states
590-
591600
async def remove_ban(
592601
self,
593602
user_id: Union[int, Snowflake], # only support ID since there's no member on the guild

interactions/api/models/message.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,15 @@ class PartialSticker(DictSerializerMixin, IDMixin):
589589
name: str = field()
590590
format_type: int = field()
591591

592+
@property
593+
def created_at(self) -> datetime:
594+
"""
595+
.. versionadded:: 4.4.0
596+
597+
Returns when the sticker was created.
598+
"""
599+
return self.id.timestamp
600+
592601

593602
@define()
594603
class Sticker(PartialSticker, IDMixin):
@@ -645,6 +654,15 @@ class StickerPack(DictSerializerMixin, IDMixin):
645654
description: str = field()
646655
banned_asset_id: Optional[Snowflake] = field(converter=Snowflake, default=None)
647656

657+
@property
658+
def created_at(self) -> datetime:
659+
"""
660+
.. versionadded:: 4.4.0
661+
662+
Returns when the sticker pack was created.
663+
"""
664+
return self.id.timestamp
665+
648666

649667
@define()
650668
class ReactionObject(DictSerializerMixin):
@@ -746,6 +764,13 @@ class Message(ClientSerializerMixin, IDMixin):
746764
) # deprecated
747765
position: Optional[int] = field(default=None, repr=False)
748766

767+
def __attrs_post_init__(self):
768+
if self.member and self.guild_id:
769+
self.member._extras["guild_id"] = self.guild_id
770+
771+
if self.author and self.member:
772+
self.member.user = self.author
773+
749774
@property
750775
def deletable(self) -> bool:
751776
"""
@@ -755,12 +780,14 @@ def deletable(self) -> bool:
755780
"""
756781
return self.type not in self.type.not_deletable()
757782

758-
def __attrs_post_init__(self):
759-
if self.member and self.guild_id:
760-
self.member._extras["guild_id"] = self.guild_id
783+
@property
784+
def created_at(self) -> datetime:
785+
"""
786+
.. versionadded:: 4.4.0
761787
762-
if self.author and self.member:
763-
self.member.user = self.author
788+
Returns when the message was created.
789+
"""
790+
return self.id.timestamp
764791

765792
async def get_channel(self) -> Channel:
766793
"""

interactions/api/models/role.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
from typing import TYPE_CHECKING, List, Optional, Union
23

34
from ...utils.attrs_utils import ClientSerializerMixin, DictSerializerMixin, define, field
@@ -81,6 +82,15 @@ def mention(self) -> str:
8182
"""
8283
return f"<@&{self.id}>"
8384

85+
@property
86+
def created_at(self) -> datetime:
87+
"""
88+
.. versionadded:: 4.4.0
89+
90+
Returns when the role was created.
91+
"""
92+
return self.id.timestamp
93+
8494
async def delete(
8595
self,
8696
guild_id: Union[int, Snowflake, "Guild"],

interactions/api/models/team.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
from typing import Any, List, Optional
23

34
from ...utils.attrs_utils import ClientSerializerMixin, convert_list, define, field
@@ -117,3 +118,12 @@ def icon_url(self) -> Optional[str]:
117118
else:
118119
url = None
119120
return url
121+
122+
@property
123+
def created_at(self) -> datetime:
124+
"""
125+
.. versionadded:: 4.4.0
126+
127+
Returns when the application was created.
128+
"""
129+
return self.id.timestamp

interactions/api/models/user.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
from typing import TYPE_CHECKING, List, Optional, Union
23

34
from ...utils.attrs_utils import ClientSerializerMixin, define, field
@@ -127,6 +128,15 @@ def presence(self) -> Optional["Presence"]:
127128

128129
return self._client.cache[Presence].get(self.id)
129130

131+
@property
132+
def created_at(self) -> datetime:
133+
"""
134+
.. versionadded:: 4.4.0
135+
136+
Returns when the user was created.
137+
"""
138+
return self.id.timestamp
139+
130140
async def send(
131141
self,
132142
content: Optional[str] = MISSING,

interactions/api/models/webhook.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# versionadded is specified in docs gen file
22

3+
from datetime import datetime
34
from enum import IntEnum
45
from typing import TYPE_CHECKING, List, Optional, Union
56

@@ -72,6 +73,15 @@ def __attrs_post_init__(self):
7273
Channel(**self.source_channel, _client=self._client) if self.source_channel else None
7374
)
7475

76+
@property
77+
def created_at(self) -> datetime:
78+
"""
79+
.. versionadded:: 4.4.0
80+
81+
Returns when the webhook was created.
82+
"""
83+
return self.id.timestamp
84+
7585
@classmethod
7686
async def create(
7787
cls,

0 commit comments

Comments
 (0)