From 363f27fac06975a9886c91ff7d734fe3b3e2f9df Mon Sep 17 00:00:00 2001 From: Shell1010 Date: Fri, 6 Dec 2024 00:12:56 +0000 Subject: [PATCH] Utils function for snowflake worker and process ids, with increment --- discord/abc.py | 15 +++++++++++++ discord/application.py | 30 +++++++++++++++++++++++++ discord/audit_logs.py | 15 +++++++++++++ discord/channel.py | 45 ++++++++++++++++++++++++++++++++++++++ discord/guild.py | 15 +++++++++++++ discord/invite.py | 33 +++++++++++++++++++++++++++- discord/message.py | 31 ++++++++++++++++++++++++++ discord/object.py | 16 +++++++++++++- discord/partial_emoji.py | 18 +++++++++++++++ discord/profile.py | 15 +++++++++++++ discord/role.py | 17 ++++++++++++++- discord/sticker.py | 17 ++++++++++++++- discord/threads.py | 17 ++++++++++++++- discord/user.py | 17 ++++++++++++++- discord/utils.py | 46 +++++++++++++++++++++++++++++++++++++++ discord/webhook/async_.py | 15 +++++++++++++ discord/widget.py | 33 +++++++++++++++++++++++++++- 17 files changed, 388 insertions(+), 7 deletions(-) diff --git a/discord/abc.py b/discord/abc.py index 02ad626fca29..06b6f23e3178 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -837,6 +837,21 @@ def created_at(self) -> datetime: """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the channel's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the channel's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the channel's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def jump_url(self) -> str: """:class:`str`: Returns a URL that allows the client to jump to the channel. diff --git a/discord/application.py b/discord/application.py index 54a01cb11f65..c8fbbd541c16 100644 --- a/discord/application.py +++ b/discord/application.py @@ -1987,6 +1987,21 @@ def created_at(self) -> datetime: """ return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the application's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the application's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the application's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def icon(self) -> Optional[Asset]: """Optional[:class:`Asset`]: Retrieves the application's icon asset, if any.""" @@ -3755,6 +3770,21 @@ def created_at(self) -> datetime: """ return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the application's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the application's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the application's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def icon(self) -> Optional[Asset]: """Optional[:class:`Asset`]: Retrieves the application's icon asset, if any.""" diff --git a/discord/audit_logs.py b/discord/audit_logs.py index 4726d1131ed2..006b6eeffb30 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -715,6 +715,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the entry's creation time in UTC.""" return utils.snowflake_time(self.id) + @utils.cached_property + def worker_id(self) -> int: + """:class:`int`: Returns the entry's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @utils.cached_property + def process_id(self) -> int: + """:class:`int`: Returns the entry's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @utils.cached_property + def increment(self) -> int: + """:class:`int`: Returns the entry's snowflake increment.""" + return utils.snowflake_increment(self.id) + @utils.cached_property def target(self) -> TargetType: if self.action.target_type is None: diff --git a/discord/channel.py b/discord/channel.py index 25b408c157a4..13fa0cf21414 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -3639,6 +3639,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the direct message channel's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the direct message channel's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the direct message channel's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the direct message channel's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def guild(self) -> Optional[Guild]: """Optional[:class:`Guild`]: The guild this DM channel belongs to. Always ``None``. @@ -4115,6 +4130,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the channel's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the channel's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the channel's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def jump_url(self) -> str: """:class:`str`: Returns a URL that allows the client to jump to the channel. @@ -4564,6 +4594,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the channel's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the channel's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the channel's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def read_state(self) -> ReadState: """:class:`ReadState`: Returns the read state for this channel. diff --git a/discord/guild.py b/discord/guild.py index b9554aad6a41..4d219cefb6d1 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -1363,6 +1363,21 @@ def created_at(self) -> datetime: """:class:`datetime.datetime`: Returns the guild's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the guild's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the guild's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the guild's snowflake increment.""" + return utils.snowflake_increment(self.id) + def get_member_named(self, name: str, /) -> Optional[Member]: """Returns the first member found that matches the name provided. diff --git a/discord/invite.py b/discord/invite.py index 50e65339686c..f0fd3da8f21e 100644 --- a/discord/invite.py +++ b/discord/invite.py @@ -33,7 +33,7 @@ from .object import Object from .scheduled_event import ScheduledEvent from .stage_instance import StageInstance -from .utils import MISSING, _generate_session_id, _get_as_snowflake, parse_time, snowflake_time +from .utils import MISSING, _generate_session_id, _get_as_snowflake, parse_time, snowflake_time, snowflake_process_id, snowflake_increment, snowflake_worker_id from .welcome_screen import WelcomeScreen __all__ = ( @@ -152,6 +152,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the channel's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the channel's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the channel's snowflake increment.""" + return snowflake_increment(self.id) + @property def icon(self) -> Optional[Asset]: """Optional[:class:`Asset`]: Returns the channel's icon asset if available. @@ -258,6 +273,22 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the guild's creation time in UTC.""" return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the guild's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the guild's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the guild's snowflake increment.""" + return snowflake_increment(self.id) + + @property def vanity_url(self) -> Optional[str]: """Optional[:class:`str`]: The Discord vanity invite URL for this partial guild, if available. diff --git a/discord/message.py b/discord/message.py index 63855743b774..d116883108e2 100644 --- a/discord/message.py +++ b/discord/message.py @@ -951,6 +951,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: The partial message's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the message's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the message's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the message's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def jump_url(self) -> str: """:class:`str`: Returns a URL that allows the client to jump to this message.""" @@ -2408,6 +2423,22 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: The message's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the message's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the message's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the message's snowflake increment.""" + return utils.snowflake_increment(self.id) + + @property def edited_at(self) -> Optional[datetime.datetime]: """Optional[:class:`datetime.datetime`]: An aware UTC datetime object containing the edited time of the message.""" diff --git a/discord/object.py b/discord/object.py index 8930f5897d2a..76678caf4a8c 100644 --- a/discord/object.py +++ b/discord/object.py @@ -25,7 +25,7 @@ from __future__ import annotations from .mixins import Hashable -from .utils import snowflake_time, MISSING +from .utils import snowflake_time, MISSING, snowflake_worker_id, snowflake_increment, snowflake_process_id from typing import ( SupportsInt, @@ -113,5 +113,19 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the snowflake's creation time in UTC.""" return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the object's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the object's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the object's snowflake increment.""" + return snowflake_increment(self.id) OLDEST_OBJECT = Object(id=0) diff --git a/discord/partial_emoji.py b/discord/partial_emoji.py index 5c72c56e6ec7..cbe4126a8f84 100644 --- a/discord/partial_emoji.py +++ b/discord/partial_emoji.py @@ -240,6 +240,24 @@ def created_at(self) -> Optional[datetime]: return utils.snowflake_time(self.id) + @property + def worker_id(self) -> Optional[int]: + """:class:`int`: Returns the emoji's snowflake worker ID.""" + if self.id: + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> Optional[int]: + """:class:`int`: Returns the emoji's snowflake process ID.""" + if self.id: + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> Optional[int]: + """:class:`int`: Returns the emoji's snowflake increment.""" + if self.id: + return utils.snowflake_increment(self.id) + @property def url(self) -> str: """:class:`str`: Returns the URL of the emoji, if it is custom. diff --git a/discord/profile.py b/discord/profile.py index f78b5fce7689..08f4c70d41ab 100644 --- a/discord/profile.py +++ b/discord/profile.py @@ -319,6 +319,21 @@ def created_at(self) -> datetime: """ return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the application's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the application's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the application's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def flags(self) -> ApplicationFlags: """:class:`ApplicationFlags`: The flags of this application.""" diff --git a/discord/role.py b/discord/role.py index 229e0cf94212..a949963908c3 100644 --- a/discord/role.py +++ b/discord/role.py @@ -31,7 +31,7 @@ from .flags import RoleFlags from .mixins import Hashable from .permissions import Permissions -from .utils import MISSING, _bytes_to_base64_data, _get_as_snowflake, snowflake_time +from .utils import MISSING, _bytes_to_base64_data, _get_as_snowflake, snowflake_time, snowflake_increment, snowflake_worker_id, snowflake_process_id __all__ = ( 'RoleTags', @@ -367,6 +367,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the role's creation time in UTC.""" return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the role's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the role's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the role's snowflake increment.""" + return snowflake_increment(self.id) + @property def mention(self) -> str: """:class:`str`: Returns a string that allows you to mention a role.""" diff --git a/discord/sticker.py b/discord/sticker.py index c7fc953104c0..87a9401732b1 100644 --- a/discord/sticker.py +++ b/discord/sticker.py @@ -28,7 +28,7 @@ from .mixins import Hashable from .asset import Asset, AssetMixin -from .utils import cached_slot_property, find, snowflake_time, get, MISSING, _get_as_snowflake +from .utils import cached_slot_property, find, snowflake_time, get, MISSING, _get_as_snowflake, snowflake_process_id, snowflake_increment, snowflake_worker_id from .errors import InvalidData from .enums import StickerType, StickerFormatType, try_enum @@ -316,6 +316,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the sticker's creation time in UTC.""" return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the sticker's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the sticker's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the sticker's snowflake increment.""" + return snowflake_increment(self.id) + class StandardSticker(Sticker): """Represents a sticker that is found in a standard sticker pack. diff --git a/discord/threads.py b/discord/threads.py index c723e2db573a..33cab665e0c2 100644 --- a/discord/threads.py +++ b/discord/threads.py @@ -35,7 +35,7 @@ from .errors import ClientException, InvalidData from .flags import ChannelFlags from .permissions import Permissions -from .utils import MISSING, parse_time, snowflake_time, _get_as_snowflake, _unique +from .utils import MISSING, parse_time, snowflake_time, _get_as_snowflake, _unique, snowflake_worker_id, snowflake_increment, snowflake_process_id __all__ = ( 'Thread', @@ -265,6 +265,21 @@ def created_at(self) -> datetime: """ return self._created_at or snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the thread's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the thread's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the thread's snowflake increment.""" + return snowflake_increment(self.id) + @property def jump_url(self) -> str: """:class:`str`: Returns a URL that allows the client to jump to the thread.""" diff --git a/discord/user.py b/discord/user.py index 26a4e8bc5b6a..f2d0e468d9ac 100644 --- a/discord/user.py +++ b/discord/user.py @@ -40,7 +40,7 @@ from .errors import ClientException, NotFound from .flags import PublicUserFlags, PrivateUserFlags, PremiumUsageFlags, PurchasedFlags from .relationship import Relationship -from .utils import _bytes_to_base64_data, _get_as_snowflake, cached_slot_property, copy_doc, snowflake_time, MISSING +from .utils import _bytes_to_base64_data, _get_as_snowflake, cached_slot_property, copy_doc, snowflake_time, MISSING, snowflake_process_id, snowflake_increment, snowflake_worker_id from .voice_client import VoiceClient if TYPE_CHECKING: @@ -515,6 +515,21 @@ def created_at(self) -> datetime: """ return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the user's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the user's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the user's snowflake increment.""" + return snowflake_increment(self.id) + @property def display_name(self) -> str: """:class:`str`: Returns the user's display name. diff --git a/discord/utils.py b/discord/utils.py index 1ad21648c2cb..7fa828b5d7e9 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -438,6 +438,52 @@ def oauth_url( url += f'&{urlencode({"state": state})}' return url +def snowflake_worker_id(id: int, /) -> int: + """Returns the worker id of the given snowflake + + Paramaters + ----------- + id: :class:`int` + The snowflake ID. + + Returns + -------- + :class:`int` + The worker ID used to generate the snowflake. + """ + return (id >> 17) & 0x1F + +def snowflake_process_id(id: int, /) -> int: + """Returns the process id of the given snowflake + + Paramaters + ----------- + id: :class:`int` + The snowflake ID. + + Returns + -------- + :class:`int` + The process ID used to generate the snowflake. + """ + return (id >> 12) & 0x1F + +def snowflake_increment(id: int, /) -> int: + """Returns the increment of the given snowflake. + For every generated ID on that process, this number is incremented. + + Paramaters + ----------- + id: :class:`int` + The snowflake ID. + + Returns + -------- + :class:`int` + The increment of current snowflake. + """ + return id & 0xFFF + def snowflake_time(id: int, /) -> datetime.datetime: """Returns the creation time of the given snowflake. diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index ce4873fbf418..6bcf66928a21 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -812,6 +812,21 @@ def created_at(self) -> datetime: """:class:`datetime.datetime`: Returns the webhook's creation time in UTC.""" return utils.snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the webhook's snowflake worker ID.""" + return utils.snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the webhook's snowflake process ID.""" + return utils.snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the webhook's snowflake increment.""" + return utils.snowflake_increment(self.id) + @property def avatar(self) -> Optional[Asset]: """Optional[:class:`Asset`]: Returns an :class:`Asset` for the avatar the webhook has. diff --git a/discord/widget.py b/discord/widget.py index 1793618fafe4..53b8bb0b30f8 100644 --- a/discord/widget.py +++ b/discord/widget.py @@ -26,7 +26,7 @@ from typing import List, Optional, TYPE_CHECKING, Union -from .utils import snowflake_time, _get_as_snowflake, resolve_invite +from .utils import snowflake_time, _get_as_snowflake, resolve_invite, snowflake_worker_id, snowflake_increment, snowflake_process_id from .user import BaseUser from .activity import BaseActivity, Spotify, create_activity from .invite import Invite @@ -101,6 +101,22 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the widget channel's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the widget channel's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the widget channel's snowflake increment.""" + return snowflake_increment(self.id) + + class WidgetMember(BaseUser): """Represents a "partial" member of the widget's guild. @@ -289,6 +305,21 @@ def created_at(self) -> datetime.datetime: """:class:`datetime.datetime`: Returns the member's creation time in UTC.""" return snowflake_time(self.id) + @property + def worker_id(self) -> int: + """:class:`int`: Returns the member's snowflake worker ID.""" + return snowflake_worker_id(self.id) + + @property + def process_id(self) -> int: + """:class:`int`: Returns the member's snowflake process ID.""" + return snowflake_process_id(self.id) + + @property + def increment(self) -> int: + """:class:`int`: Returns the member's snowflake increment.""" + return snowflake_increment(self.id) + @property def json_url(self) -> str: """:class:`str`: The JSON URL of the widget."""