From c80dbe2aef5796ceded741b044abe0aaf0611f96 Mon Sep 17 00:00:00 2001 From: shiftinv Date: Sun, 29 Oct 2023 12:42:22 +0100 Subject: [PATCH] revert: remove sku/entitlement http methods, endpoints scheduled for removal --- changelog/1113.feature.rst | 3 +- disnake/client.py | 136 +------------------------------------ disnake/entitlement.py | 27 +------- disnake/http.py | 76 --------------------- disnake/iterators.py | 118 -------------------------------- docs/api/events.rst | 3 +- 6 files changed, 7 insertions(+), 356 deletions(-) diff --git a/changelog/1113.feature.rst b/changelog/1113.feature.rst index 80634d2e29..ff8560e980 100644 --- a/changelog/1113.feature.rst +++ b/changelog/1113.feature.rst @@ -1,5 +1,4 @@ Support application subscriptions (see the :ddocs:`official docs ` for more info). -- New types: :class:`SKU`, :class:`Entitlement` +- New types: :class:`SKU`, :class:`Entitlement`. - New :attr:`Interaction.entitlements` attribute, and :meth:`InteractionResponse.require_premium` response type. - New events: :func:`on_entitlement_create`, :func:`on_entitlement_update`, :func:`on_entitlement_delete`. -- New :class:`Client` methods: :meth:`~Client.skus`, :meth:`~Client.entitlements`, :meth:`~Client.create_entitlement`. diff --git a/disnake/client.py b/disnake/client.py index 9f4f6cc240..f71842c7b3 100644 --- a/disnake/client.py +++ b/disnake/client.py @@ -32,7 +32,7 @@ import aiohttp -from . import abc, utils +from . import utils from .activity import ActivityTypes, BaseActivity, create_activity from .app_commands import ( APIMessageCommand, @@ -46,7 +46,6 @@ from .backoff import ExponentialBackoff from .channel import PartialMessageable, _threaded_channel_factory from .emoji import Emoji -from .entitlement import Entitlement from .enums import ApplicationCommandType, ChannelType, Event, Status from .errors import ( ConnectionClosed, @@ -63,10 +62,9 @@ from .http import HTTPClient from .i18n import LocalizationProtocol, LocalizationStore from .invite import Invite -from .iterators import EntitlementIterator, GuildIterator +from .iterators import GuildIterator from .mentions import AllowedMentions from .object import Object -from .sku import SKU from .stage_instance import StageInstance from .state import ConnectionState from .sticker import GuildSticker, StandardSticker, StickerPack, _sticker_factory @@ -2975,133 +2973,3 @@ async def edit_role_connection_metadata( self.application_id, payload ) return [ApplicationRoleConnectionMetadata._from_data(record) for record in data] - - async def skus(self) -> List[SKU]: - """|coro| - - Retrieves the :class:`.SKU`\\s for the application. - - To manage application subscription entitlements, you should use the SKU - with :attr:`.SKUType.subscription`. - - .. versionadded:: 2.10 - - Raises - ------ - HTTPException - Retrieving the SKUs failed. - - Returns - ------- - List[:class:`.SKU`] - The list of SKUs. - """ - data = await self.http.get_skus(self.application_id) - return [SKU(data=d) for d in data] - - def entitlements( - self, - *, - limit: Optional[int] = 100, - before: Optional[SnowflakeTime] = None, - after: Optional[SnowflakeTime] = None, - user: Optional[Snowflake] = None, - guild: Optional[Snowflake] = None, - skus: Optional[Sequence[Snowflake]] = None, - exclude_ended: bool = False, - oldest_first: bool = False, - ) -> EntitlementIterator: - """Retrieves an :class:`.AsyncIterator` that enables receiving entitlements for the application. - - .. note:: - - This method is an API call. To get the entitlements of the invoking user/guild - in interactions, consider using :attr:`.Interaction.entitlements`. - - Entries are returned in order from newest to oldest by default; - pass ``oldest_first=True`` to reverse the iteration order. - - All parameters are optional. - - .. versionadded:: 2.10 - - Parameters - ---------- - limit: Optional[:class:`int`] - The number of entitlements to retrieve. - If ``None``, retrieves every entitlement. - Note, however, that this would make it a slow operation. - Defaults to ``100``. - before: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`] - Retrieves entitlements created before this date or object. - If a datetime is provided, it is recommended to use a UTC aware datetime. - If the datetime is naive, it is assumed to be local time. - after: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`] - Retrieve entitlements created after this date or object. - If a datetime is provided, it is recommended to use a UTC aware datetime. - If the datetime is naive, it is assumed to be local time. - user: Optional[:class:`.abc.Snowflake`] - The user to retrieve entitlements for. - guild: Optional[:class:`.abc.Snowflake`] - The guild to retrieve entitlements for. - skus: Optional[Sequence[:class:`.abc.Snowflake`]] - The SKUs for which entitlements are retrieved. - exclude_ended: :class:`bool` - Whether to exclude ended/expired entitlements. Defaults to ``False``. - oldest_first: :class:`bool` - If set to ``True``, return entries in oldest->newest order. Defaults to ``False``. - - Raises - ------ - HTTPException - Retrieving the entitlements failed. - - Yields - ------ - :class:`.Entitlement` - The entitlements for the given parameters. - """ - return EntitlementIterator( - self.application_id, - state=self._connection, - limit=limit, - before=before, - after=after, - user_id=user.id if user is not None else None, - guild_id=guild.id if guild is not None else None, - sku_ids=[sku.id for sku in skus] if skus else None, - exclude_ended=exclude_ended, - oldest_first=oldest_first, - ) - - async def create_entitlement( - self, sku: Snowflake, owner: Union[abc.User, Guild] - ) -> Entitlement: - """|coro| - - Creates a new test :class:`.Entitlement` for the given user or guild, with no expiry. - - Parameters - ---------- - sku: :class:`.abc.Snowflake` - The :class:`.SKU` to grant the entitlement for. - owner: Union[:class:`.abc.User`, :class:`.Guild`] - The user or guild to grant the entitlement to. - - Raises - ------ - HTTPException - Creating the entitlement failed. - - Returns - ------- - :class:`.Entitlement` - The newly created entitlement. - """ - data = await self.http.create_test_entitlement( - self.application_id, - sku_id=sku.id, - owner_id=owner.id, - owner_type=2 if isinstance(owner, abc.User) else 1, - ) - return Entitlement(data=data, state=self._connection) diff --git a/disnake/entitlement.py b/disnake/entitlement.py index 3e2d20bed1..ec5b2c2770 100644 --- a/disnake/entitlement.py +++ b/disnake/entitlement.py @@ -22,15 +22,11 @@ class Entitlement(Hashable): """Represents an entitlement. - This is usually retrieved using :meth:`Client.entitlements`, from - :attr:`Interaction.entitlements` when using interactions, or provided by - events (e.g. :func:`on_entitlement_create`). + This is usually retrieved from :attr:`Interaction.entitlements` when using interactions, + or provided by events (e.g. :func:`on_entitlement_create`). Note that some entitlements may have ended already; consider using - :meth:`is_active` to check whether a given entitlement is considered active at the current time, - or use ``exclude_ended=True`` when fetching entitlements using :meth:`Client.entitlements`. - - You may create new entitlements for testing purposes using :meth:`Client.create_entitlement`. + :meth:`is_active` to check whether a given entitlement is considered active at the current time. .. container:: operations @@ -149,20 +145,3 @@ def is_active(self) -> bool: return False return True - - async def delete(self) -> None: - """|coro| - - Deletes the entitlement. - - This is only valid for test entitlements; you cannot use this to - delete entitlements that users purchased. - - Raises - ------ - NotFound - The entitlement does not exist. - HTTPException - Deleting the entitlement failed. - """ - await self._state.http.delete_test_entitlement(self.application_id, self.id) diff --git a/disnake/http.py b/disnake/http.py index deb8dca54e..f8c4b44694 100644 --- a/disnake/http.py +++ b/disnake/http.py @@ -60,7 +60,6 @@ components, embed, emoji, - entitlement, gateway, guild, guild_scheduled_event, @@ -71,7 +70,6 @@ message, onboarding, role, - sku, sticker, template, threads, @@ -2276,80 +2274,6 @@ def delete_auto_moderation_rule( def get_guild_onboarding(self, guild_id: Snowflake) -> Response[onboarding.Onboarding]: return self.request(Route("GET", "/guilds/{guild_id}/onboarding", guild_id=guild_id)) - # SKUs/Entitlements - - def get_skus(self, application_id: Snowflake) -> Response[List[sku.SKU]]: - return self.request( - Route("GET", "/applications/{application_id}/skus", application_id=application_id) - ) - - def get_entitlements( - self, - application_id: Snowflake, - *, - # if both are specified, `after` takes priority and `before` gets ignored - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - limit: int = 100, - user_id: Optional[Snowflake] = None, - guild_id: Optional[Snowflake] = None, - sku_ids: Optional[SnowflakeList] = None, - exclude_ended: bool = False, - ) -> Response[List[entitlement.Entitlement]]: - params: Dict[str, Any] = { - "limit": limit, - "exclude_ended": int(exclude_ended), - } - if before is not None: - params["before"] = before - if after is not None: - params["after"] = after - if user_id is not None: - params["user_id"] = user_id - if guild_id is not None: - params["guild_id"] = guild_id - if sku_ids: - params["sku_ids"] = ",".join(map(str, sku_ids)) - - r = Route( - "GET", "/applications/{application_id}/entitlements", application_id=application_id - ) - return self.request(r, params=params) - - def create_test_entitlement( - self, - application_id: Snowflake, - sku_id: Snowflake, - owner_id: Snowflake, - *, - owner_type: Literal[1, 2], # 1: guild, 2: user - ) -> Response[entitlement.Entitlement]: - payload: Dict[str, Any] = { - "sku_id": sku_id, - "owner_id": owner_id, - "owner_type": owner_type, - } - return self.request( - Route( - "POST", "/applications/{application_id}/entitlements", application_id=application_id - ), - json=payload, - ) - - def delete_test_entitlement( - self, - application_id: Snowflake, - entitlement_id: Snowflake, - ) -> Response[None]: - return self.request( - Route( - "DELETE", - "/applications/{application_id}/entitlements/{entitlement_id}", - application_id=application_id, - entitlement_id=entitlement_id, - ) - ) - # Application commands (global) def get_global_commands( diff --git a/disnake/iterators.py b/disnake/iterators.py index 3a4f5526ed..fe21659704 100644 --- a/disnake/iterators.py +++ b/disnake/iterators.py @@ -22,7 +22,6 @@ from .audit_logs import AuditLogEntry from .automod import AutoModRule from .bans import BanEntry -from .entitlement import Entitlement from .errors import NoMoreItems from .guild_scheduled_event import GuildScheduledEvent from .integrations import PartialIntegration @@ -38,7 +37,6 @@ "GuildIterator", "MemberIterator", "GuildScheduledEventUserIterator", - "EntitlementIterator", ) if TYPE_CHECKING: @@ -53,7 +51,6 @@ AuditLogEntry as AuditLogEntryPayload, AuditLogEvent, ) - from .types.entitlement import Entitlement as EntitlementPayload from .types.guild import Ban as BanPayload, Guild as GuildPayload from .types.guild_scheduled_event import ( GuildScheduledEventUser as GuildScheduledEventUserPayload, @@ -1025,118 +1022,3 @@ async def _after_strategy(self, retrieve: int) -> List[GuildScheduledEventUserPa self.limit -= retrieve self.after = Object(id=int(data[-1]["user"]["id"])) return data - - -# The endpoint for this paginates like audit logs, -# i.e. descending when no parameter or `before` is given, -# and ascending when `after` is given. -class EntitlementIterator(_AsyncIterator["Entitlement"]): - def __init__( - self, - application_id: int, - *, - state: ConnectionState, - limit: Optional[int], - user_id: Optional[int] = None, - guild_id: Optional[int] = None, - sku_ids: Optional[List[int]] = None, - before: Optional[Union[Snowflake, datetime.datetime]] = None, - after: Optional[Union[Snowflake, datetime.datetime]] = None, - exclude_ended: bool = False, - oldest_first: bool = False, - ) -> None: - if isinstance(before, datetime.datetime): - before = Object(id=time_snowflake(before, high=False)) - if isinstance(after, datetime.datetime): - after = Object(id=time_snowflake(after, high=True)) - - self.application_id: int = application_id - self.limit: Optional[int] = limit - self.before: Optional[Snowflake] = before - self.after: Snowflake = after or OLDEST_OBJECT - self.user_id: Optional[int] = user_id - self.guild_id: Optional[int] = guild_id - self.sku_ids: Optional[List[int]] = sku_ids - self.exclude_ended: bool = exclude_ended - - self.state: ConnectionState = state - self.request = state.http.get_entitlements - - self.entitlements: asyncio.Queue[Entitlement] = asyncio.Queue() - - self._filter: Optional[Callable[[EntitlementPayload], bool]] = None - if oldest_first: - self._strategy = self._after_strategy - if self.before: - self._filter = lambda m: int(m["id"]) < self.before.id # type: ignore - else: - self._strategy = self._before_strategy - if self.after and self.after != OLDEST_OBJECT: - self._filter = lambda m: int(m["id"]) > self.after.id - - async def next(self) -> Entitlement: - if self.entitlements.empty(): - await self._fill() - - try: - return self.entitlements.get_nowait() - except asyncio.QueueEmpty: - raise NoMoreItems from None - - def _get_retrieve(self) -> bool: - limit = self.limit - if limit is None or limit > 100: - retrieve = 100 - else: - retrieve = limit - self.retrieve: int = retrieve - return retrieve > 0 - - async def _fill(self) -> None: - if not self._get_retrieve(): - return - - data = await self._strategy(self.retrieve) - if len(data) < 100: - self.limit = 0 # terminate loop - - if self._filter: - data = filter(self._filter, data) - - for entitlement in data: - await self.entitlements.put(Entitlement(data=entitlement, state=self.state)) - - async def _before_strategy(self, retrieve: int) -> List[EntitlementPayload]: - before = self.before.id if self.before else None - data = await self.request( - self.application_id, - before=before, - limit=retrieve, - user_id=self.user_id, - guild_id=self.guild_id, - exclude_ended=self.exclude_ended, - ) - - if len(data): - if self.limit is not None: - self.limit -= retrieve - self.before = Object(id=int(data[-1]["id"])) - return data - - async def _after_strategy(self, retrieve: int) -> List[EntitlementPayload]: - after = self.after.id - data = await self.request( - self.application_id, - after=after, - limit=retrieve, - user_id=self.user_id, - guild_id=self.guild_id, - exclude_ended=self.exclude_ended, - ) - - if len(data): - if self.limit is not None: - self.limit -= retrieve - # endpoint returns items in ascending order when `after` is used - self.after = Object(id=int(data[-1]["id"])) - return data diff --git a/docs/api/events.rst b/docs/api/events.rst index 168151bbee..4491ac58ae 100644 --- a/docs/api/events.rst +++ b/docs/api/events.rst @@ -1451,8 +1451,7 @@ This section documents events related to entitlements, which are used for applic Called when an entitlement is created. - This is usually caused by a user subscribing to an SKU, - or when a new test entitlement is created (see :meth:`Client.create_entitlement`). + This is usually caused by a user subscribing to an SKU. .. versionadded:: 2.10