diff --git a/changelog/1095.feature.rst b/changelog/1095.feature.rst new file mode 100644 index 0000000000..f2f16f46c5 --- /dev/null +++ b/changelog/1095.feature.rst @@ -0,0 +1 @@ +Add ``created_at`` property to :attr:`AutoModRule `, :attr:`ForumTag `, :attr:`Integration `, :attr:`StageInstance `, and :attr:`Team `. diff --git a/disnake/automod.py b/disnake/automod.py index 170987364e..f07fe6f95c 100644 --- a/disnake/automod.py +++ b/disnake/automod.py @@ -2,7 +2,7 @@ from __future__ import annotations -from datetime import timedelta +import datetime from typing import ( TYPE_CHECKING, Dict, @@ -25,7 +25,7 @@ try_enum_to_int, ) from .flags import AutoModKeywordPresets -from .utils import MISSING, _get_as_snowflake +from .utils import MISSING, _get_as_snowflake, snowflake_time if TYPE_CHECKING: from typing_extensions import Self @@ -207,10 +207,10 @@ class AutoModTimeoutAction(AutoModAction): _metadata: AutoModTimeoutActionMetadata - def __init__(self, duration: Union[int, timedelta]) -> None: + def __init__(self, duration: Union[int, datetime.timedelta]) -> None: super().__init__(type=AutoModActionType.timeout) - if isinstance(duration, timedelta): + if isinstance(duration, datetime.timedelta): duration = int(duration.total_seconds()) self._metadata["duration_seconds"] = duration @@ -492,6 +492,14 @@ def __init__(self, *, data: AutoModRulePayload, guild: Guild) -> None: else frozenset() ) + @property + def created_at(self) -> datetime.datetime: + """:class:`datetime.datetime`: Returns the rule's creation time in UTC. + + .. versionadded:: 2.10 + """ + return snowflake_time(self.id) + @property def actions(self) -> List[AutoModAction]: """List[Union[:class:`AutoModBlockMessageAction`, :class:`AutoModSendAlertAction`, :class:`AutoModTimeoutAction`, :class:`AutoModAction`]]: diff --git a/disnake/integrations.py b/disnake/integrations.py index e66b7d7162..526da5d49f 100644 --- a/disnake/integrations.py +++ b/disnake/integrations.py @@ -7,7 +7,14 @@ from .enums import ExpireBehaviour, try_enum from .user import User -from .utils import MISSING, _get_as_snowflake, deprecated, parse_time, warn_deprecated +from .utils import ( + MISSING, + _get_as_snowflake, + deprecated, + parse_time, + snowflake_time, + warn_deprecated, +) __all__ = ( "IntegrationAccount", @@ -99,6 +106,15 @@ def _from_data(self, data: PartialIntegrationPayload) -> None: self.account: IntegrationAccount = IntegrationAccount(data["account"]) self.application_id: Optional[int] = _get_as_snowflake(data, "application_id") + @property + def created_at(self) -> datetime.datetime: + """:class:`datetime.datetime`: Returns the integration's + (*not* the associated application's) creation time in UTC. + + .. versionadded:: 2.10 + """ + return snowflake_time(self.id) + class Integration(PartialIntegration): """Represents a guild integration. diff --git a/disnake/stage_instance.py b/disnake/stage_instance.py index 9b861d4a84..08f50dc3e1 100644 --- a/disnake/stage_instance.py +++ b/disnake/stage_instance.py @@ -2,11 +2,12 @@ from __future__ import annotations +import datetime from typing import TYPE_CHECKING, Optional from .enums import StagePrivacyLevel, try_enum from .mixins import Hashable -from .utils import MISSING, _get_as_snowflake, cached_slot_property, warn_deprecated +from .utils import MISSING, _get_as_snowflake, cached_slot_property, snowflake_time, warn_deprecated __all__ = ("StageInstance",) @@ -84,6 +85,14 @@ def _update(self, data: StageInstancePayload) -> None: def __repr__(self) -> str: return f"" + @property + def created_at(self) -> datetime.datetime: + """:class:`datetime.datetime`: Returns the stage instance's creation time in UTC. + + .. versionadded:: 2.10 + """ + return snowflake_time(self.id) + @cached_slot_property("_cs_channel") def channel(self) -> Optional[StageChannel]: """Optional[:class:`StageChannel`]: The channel that stage instance is running in.""" diff --git a/disnake/team.py b/disnake/team.py index 6465128ffe..1034904cd9 100644 --- a/disnake/team.py +++ b/disnake/team.py @@ -2,6 +2,7 @@ from __future__ import annotations +import datetime from typing import TYPE_CHECKING, List, Optional from . import utils @@ -52,6 +53,14 @@ def __init__(self, state: ConnectionState, data: TeamPayload) -> None: def __repr__(self) -> str: return f"<{self.__class__.__name__} id={self.id} name={self.name}>" + @property + def created_at(self) -> datetime.datetime: + """:class:`datetime.datetime`: Returns the team's creation time in UTC. + + .. versionadded:: 2.10 + """ + return utils.snowflake_time(self.id) + @property def icon(self) -> Optional[Asset]: """Optional[:class:`.Asset`]: Retrieves the team's icon asset, if any.""" diff --git a/disnake/threads.py b/disnake/threads.py index 2126e85605..2457c5a879 100644 --- a/disnake/threads.py +++ b/disnake/threads.py @@ -332,7 +332,7 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the thread's creation time in UTC. .. versionchanged:: 2.4 - If create_timestamp is provided by discord, that will be used instead of the time in the ID. + If ``create_timestamp`` is provided by Discord, that will be used instead of the time in the ID. """ return self.create_timestamp or snowflake_time(self.id) @@ -1183,6 +1183,14 @@ def __repr__(self) -> str: f" moderated={self.moderated!r} emoji={self.emoji!r}>" ) + @property + def created_at(self) -> datetime.datetime: + """:class:`datetime.datetime`: Returns the tag's creation time in UTC. + + .. versionadded:: 2.10 + """ + return snowflake_time(self.id) + def to_dict(self) -> PartialForumTagPayload: emoji_name, emoji_id = PartialEmoji._emoji_to_name_id(self.emoji) data: PartialForumTagPayload = {