You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
632 lines
22 KiB
632 lines
22 KiB
"""
|
|
The MIT License (MIT)
|
|
|
|
Copyright (c) 2021-present Dolfies
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the "Software"),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
DEALINGS IN THE SOFTWARE.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Any, List, Optional
|
|
|
|
from .enums import EntitlementType, GiftStyle, PremiumType, try_enum
|
|
from .flags import GiftFlags
|
|
from .mixins import Hashable
|
|
from .payments import EntitlementPayment
|
|
from .promotions import Promotion
|
|
from .store import SKU, StoreListing, SubscriptionPlan
|
|
from .subscriptions import Subscription, SubscriptionTrial
|
|
from .utils import _get_as_snowflake, parse_time, utcnow
|
|
|
|
if TYPE_CHECKING:
|
|
from datetime import datetime
|
|
|
|
from .abc import Snowflake
|
|
from .guild import Guild
|
|
from .state import ConnectionState
|
|
from .types.entitlements import (
|
|
Entitlement as EntitlementPayload,
|
|
Gift as GiftPayload,
|
|
GiftBatch as GiftBatchPayload,
|
|
)
|
|
from .user import User
|
|
|
|
__all__ = (
|
|
'Entitlement',
|
|
'Gift',
|
|
'GiftBatch',
|
|
)
|
|
|
|
|
|
class Entitlement(Hashable):
|
|
"""Represents a Discord entitlement.
|
|
|
|
.. container:: operations
|
|
|
|
.. describe:: x == y
|
|
|
|
Checks if two entitlements are equal.
|
|
|
|
.. describe:: x != y
|
|
|
|
Checks if two entitlements are not equal.
|
|
|
|
.. describe:: hash(x)
|
|
|
|
Returns the entitlement's hash.
|
|
|
|
.. describe:: bool(x)
|
|
|
|
Checks if the entitlement is active.
|
|
|
|
.. versionadded:: 2.0
|
|
|
|
Attributes
|
|
----------
|
|
id: :class:`int`
|
|
The ID of the entitlement.
|
|
type: :class:`EntitlementType`
|
|
The type of entitlement.
|
|
user_id: :class:`int`
|
|
The ID of the user the entitlement is for.
|
|
sku_id: :class:`int`
|
|
The ID of the SKU the entitlement grants.
|
|
application_id: :class:`int`
|
|
The ID of the application that owns the SKU the entitlement grants.
|
|
promotion_id: Optional[:class:`int`]
|
|
The ID of the promotion the entitlement is from.
|
|
parent_id: Optional[:class:`int`]
|
|
The ID of the entitlement's parent.
|
|
guild_id: Optional[:class:`int`]
|
|
The ID of the guild the entitlement is for.
|
|
branches: List[:class:`int`]
|
|
The IDs of the branches the entitlement grants.
|
|
gifter_id: Optional[:class:`int`]
|
|
The ID of the user that gifted the entitlement.
|
|
gift_style: Optional[:class:`GiftStyle`]
|
|
The style of the gift attached to this entitlement.
|
|
gift_batch_id: Optional[:class:`int`]
|
|
The ID of the batch the gift attached to this entitlement is from.
|
|
deleted: :class:`bool`
|
|
Whether the entitlement is deleted.
|
|
consumed: :class:`bool`
|
|
Whether the entitlement is consumed.
|
|
starts_at: Optional[:class:`datetime.datetime`]
|
|
When the entitlement period starts.
|
|
ends_at: Optional[:class:`datetime.datetime`]
|
|
When the entitlement period ends.
|
|
subscription_id: Optional[:class:`int`]
|
|
The ID of the subscription the entitlement is from.
|
|
subscription_plan: Optional[:class:`SubscriptionPlan`]
|
|
The subscription plan the entitlement is for.
|
|
|
|
.. note::
|
|
|
|
This is a partial object without price information.
|
|
sku: Optional[:class:`SKU`]
|
|
The SKU the entitlement grants.
|
|
payment: Optional[:class:`EntitlementPayment`]
|
|
The payment made for the entitlement.
|
|
Not available in some contexts.
|
|
"""
|
|
|
|
__slots__ = (
|
|
'id',
|
|
'type',
|
|
'user_id',
|
|
'sku_id',
|
|
'application_id',
|
|
'promotion_id',
|
|
'parent_id',
|
|
'guild_id',
|
|
'branches',
|
|
'gifter_id',
|
|
'gift_style',
|
|
'gift_batch_id',
|
|
'_gift_flags',
|
|
'deleted',
|
|
'consumed',
|
|
'starts_at',
|
|
'ends_at',
|
|
'subscription_id',
|
|
'subscription_plan',
|
|
'sku',
|
|
'payment',
|
|
'_state',
|
|
)
|
|
|
|
def __init__(self, *, data: EntitlementPayload, state: ConnectionState):
|
|
self._state = state
|
|
self._update(data)
|
|
|
|
def _update(self, data: EntitlementPayload):
|
|
state = self._state
|
|
|
|
self.id: int = int(data['id'])
|
|
self.type: EntitlementType = try_enum(EntitlementType, data['type'])
|
|
self.user_id: int = int(data.get('user_id') or state.self_id) # type: ignore
|
|
self.sku_id: int = int(data['sku_id'])
|
|
self.application_id: int = int(data['application_id'])
|
|
self.promotion_id: Optional[int] = _get_as_snowflake(data, 'promotion_id')
|
|
self.parent_id: Optional[int] = _get_as_snowflake(data, 'parent_id')
|
|
self.guild_id: Optional[int] = _get_as_snowflake(data, 'guild_id')
|
|
self.branches: List[int] = [int(branch) for branch in data.get('branches', [])]
|
|
self.gifter_id: Optional[int] = _get_as_snowflake(data, 'gifter_user_id')
|
|
self.gift_style: Optional[GiftStyle] = try_enum(GiftStyle, data.get('gift_style'))
|
|
self.gift_batch_id: Optional[int] = _get_as_snowflake(data, 'gift_code_batch_id')
|
|
self._gift_flags: int = data.get('gift_code_flags', 0)
|
|
|
|
self.deleted: bool = data.get('deleted', False)
|
|
self.consumed: bool = data.get('consumed', False)
|
|
self.starts_at: Optional[datetime] = parse_time(data.get('starts_at'))
|
|
self.ends_at: Optional[datetime] = parse_time(data.get('ends_at'))
|
|
|
|
self.subscription_id: Optional[int] = _get_as_snowflake(data, 'subscription_id')
|
|
self.subscription_plan: Optional[SubscriptionPlan] = (
|
|
SubscriptionPlan(data=data['subscription_plan'], state=state) if 'subscription_plan' in data else None
|
|
)
|
|
self.sku: Optional[SKU] = SKU(data=data['sku'], state=state) if 'sku' in data else None
|
|
self.payment: Optional[EntitlementPayment] = (
|
|
EntitlementPayment(data=data['payment'], entitlement=self) if 'payment' in data else None
|
|
)
|
|
|
|
def __repr__(self) -> str:
|
|
return f'<Entitlement id={self.id} type={self.type!r} sku_id={self.sku_id} application_id={self.application_id}>'
|
|
|
|
def __bool__(self) -> bool:
|
|
return self.is_active()
|
|
|
|
@property
|
|
def guild(self) -> Optional[Guild]:
|
|
""":class:`Guild`: Returns the guild the entitlement is for, if accessible."""
|
|
return self._state._get_guild(self.guild_id)
|
|
|
|
@property
|
|
def premium_type(self) -> Optional[PremiumType]:
|
|
"""Optional[:class:`PremiumType`]: The premium type this entitlement grants, if it is for a premium subscription."""
|
|
return PremiumType.from_sku_id(self.sku_id)
|
|
|
|
@property
|
|
def gift_flags(self) -> GiftFlags:
|
|
""":class:`GiftFlags`: Returns the flags for the gift this entitlement is attached to."""
|
|
return GiftFlags._from_value(self._gift_flags)
|
|
|
|
def is_giftable(self) -> bool:
|
|
""":class:`bool`: Whether the entitlement is giftable."""
|
|
return self.type == EntitlementType.user_gift and not self.gifter_id
|
|
|
|
def is_active(self) -> bool:
|
|
""":class:`bool`: Whether the entitlement is active and offering perks."""
|
|
# This is a copy of the logic used in the client
|
|
|
|
if self.is_giftable() or self.deleted:
|
|
return False # Giftable entitlements have not yet been gifted therefore are not active
|
|
if self.starts_at and self.starts_at > utcnow():
|
|
return False # Entitlement has not started yet
|
|
if self.ends_at and self.ends_at < utcnow():
|
|
return False # Entitlement has ended
|
|
|
|
if self.type == EntitlementType.premium_subscription:
|
|
# Premium subscription entitlements are only active
|
|
# if the SKU is offered for free to premium subscribers
|
|
# and the user is a premium subscriber
|
|
sku = self.sku
|
|
if sku and not sku.premium:
|
|
return False
|
|
if self._state.user and not self._state.user.premium_type == PremiumType.nitro:
|
|
return False
|
|
|
|
return True
|
|
|
|
async def subscription(self) -> Optional[Subscription]:
|
|
"""|coro|
|
|
|
|
Retrieves the subscription this entitlement is attached to, if applicable.
|
|
|
|
Raises
|
|
------
|
|
NotFound
|
|
You cannot access this subscription.
|
|
HTTPException
|
|
Fetching the subscription failed.
|
|
|
|
Returns
|
|
-------
|
|
Optional[:class:`Subscription`]
|
|
The retrieved subscription, if applicable.
|
|
"""
|
|
if not self.subscription_id:
|
|
return
|
|
|
|
data = await self._state.http.get_subscription(self.subscription_id)
|
|
return Subscription(data=data, state=self._state)
|
|
|
|
async def consume(self) -> None:
|
|
"""|coro|
|
|
|
|
Consumes the entitlement. This marks a given user entitlement as expended,
|
|
and removes the entitlement from the user's active entitlements.
|
|
|
|
This should be called after the user has received the relevant item,
|
|
and only works on entitlements for SKUs of type :attr:`SKUType.consumable`.
|
|
|
|
Raises
|
|
------
|
|
Forbidden
|
|
You do not have permissions to access this application.
|
|
HTTPException
|
|
Consuming the entitlement failed.
|
|
"""
|
|
await self._state.http.consume_app_entitlement(self.application_id, self.id)
|
|
|
|
async def delete(self) -> None:
|
|
"""|coro|
|
|
|
|
Deletes the entitlement. This removes the entitlement from the user's
|
|
entitlements, and is irreversible.
|
|
|
|
This is only useable on entitlements of type :attr:`EntitlementType.test_mode_purchase`.
|
|
|
|
Raises
|
|
------
|
|
Forbidden
|
|
You do not have permissions to access this application.
|
|
HTTPException
|
|
Deleting the entitlement failed.
|
|
"""
|
|
await self._state.http.delete_app_entitlement(self.application_id, self.id)
|
|
|
|
|
|
class Gift:
|
|
"""Represents a Discord gift.
|
|
|
|
.. container:: operations
|
|
|
|
.. describe:: x == y
|
|
|
|
Checks if two gifts are equal.
|
|
|
|
.. describe:: x != y
|
|
|
|
Checks if two gifts are not equal.
|
|
|
|
.. describe:: hash(x)
|
|
|
|
Returns the gift's hash.
|
|
|
|
.. versionadded:: 2.0
|
|
|
|
Attributes
|
|
----------
|
|
code: :class:`str`
|
|
The gift's code.
|
|
expires_at: Optional[:class:`datetime.datetime`]
|
|
When the gift expires.
|
|
application_id: Optional[:class:`int`]
|
|
The ID of the application that owns the SKU the gift is for.
|
|
Not available in all contexts.
|
|
batch_id: Optional[:class:`int`]
|
|
The ID of the batch the gift is from.
|
|
sku_id: :class:`int`
|
|
The ID of the SKU the gift is for.
|
|
entitlement_branches: List[:class:`int`]
|
|
A list of entitlements the gift is for.
|
|
gift_style: Optional[:class:`GiftStyle`]
|
|
The style of the gift.
|
|
max_uses: :class:`int`
|
|
The maximum number of times the gift can be used.
|
|
uses: :class:`int`
|
|
The number of times the gift has been used.
|
|
redeemed: :class:`bool`
|
|
Whether the user has redeemed the gift.
|
|
revoked: :class:`bool`
|
|
Whether the gift has been revoked.
|
|
guild_id: Optional[:class:`int`]
|
|
The ID of the guild the gift was redeemed in.
|
|
Not available in all contexts.
|
|
channel_id: Optional[:class:`int`]
|
|
The ID of the channel the gift was redeemed in.
|
|
Not available in all contexts.
|
|
store_listing: Optional[:class:`StoreListing`]
|
|
The store listing for the SKU the gift is for.
|
|
Not available in all contexts.
|
|
promotion: Optional[:class:`Promotion`]
|
|
The promotion the gift is a part of, if any.
|
|
subscription_trial: Optional[:class:`SubscriptionTrial`]
|
|
The subscription trial the gift is a part of, if any.
|
|
subscription_plan_id: Optional[:class:`int`]
|
|
The ID of the subscription plan the gift is for, if any.
|
|
subscription_plan: Optional[:class:`SubscriptionPlan`]
|
|
The subscription plan the gift is for, if any.
|
|
user: Optional[:class:`User`]
|
|
The user who created the gift, if applicable.
|
|
"""
|
|
|
|
__slots__ = (
|
|
'code',
|
|
'expires_at',
|
|
'application_id',
|
|
'batch_id',
|
|
'sku_id',
|
|
'entitlement_branches',
|
|
'gift_style',
|
|
'_flags',
|
|
'max_uses',
|
|
'uses',
|
|
'redeemed',
|
|
'revoked',
|
|
'guild_id',
|
|
'channel_id',
|
|
'store_listing',
|
|
'promotion',
|
|
'subscription_trial',
|
|
'subscription_plan_id',
|
|
'subscription_plan',
|
|
'user',
|
|
'_state',
|
|
)
|
|
|
|
def __init__(self, *, data: GiftPayload, state: ConnectionState) -> None:
|
|
self._state = state
|
|
self._update(data)
|
|
|
|
def _update(self, data: GiftPayload) -> None:
|
|
state = self._state
|
|
|
|
self.code: str = data['code']
|
|
self.expires_at: Optional[datetime] = parse_time(data.get('expires_at'))
|
|
self.application_id: Optional[int] = _get_as_snowflake(data, 'application_id')
|
|
self.batch_id: Optional[int] = _get_as_snowflake(data, 'batch_id')
|
|
self.subscription_plan_id: Optional[int] = _get_as_snowflake(data, 'subscription_plan_id')
|
|
self.sku_id: int = int(data['sku_id'])
|
|
self.entitlement_branches: List[int] = [int(x) for x in data.get('entitlement_branches', [])]
|
|
self.gift_style: Optional[GiftStyle] = try_enum(GiftStyle, data['gift_style']) if data.get('gift_style') else None # type: ignore
|
|
self._flags: int = data.get('flags', 0)
|
|
|
|
self.max_uses: int = data.get('max_uses', 0)
|
|
self.uses: int = data.get('uses', 0)
|
|
self.redeemed: bool = data.get('redeemed', False)
|
|
self.revoked: bool = data.get('revoked', False)
|
|
|
|
self.guild_id: Optional[int] = _get_as_snowflake(data, 'guild_id')
|
|
self.channel_id: Optional[int] = _get_as_snowflake(data, 'channel_id')
|
|
|
|
self.store_listing: Optional[StoreListing] = (
|
|
StoreListing(data=data['store_listing'], state=state) if 'store_listing' in data else None
|
|
)
|
|
self.promotion: Optional[Promotion] = Promotion(data=data['promotion'], state=state) if 'promotion' in data else None
|
|
self.subscription_trial: Optional[SubscriptionTrial] = (
|
|
SubscriptionTrial(data['subscription_trial']) if 'subscription_trial' in data else None
|
|
)
|
|
self.subscription_plan: Optional[SubscriptionPlan] = (
|
|
SubscriptionPlan(data=data['subscription_plan'], state=state) if 'subscription_plan' in data else None
|
|
)
|
|
self.user: Optional[User] = self._state.create_user(data['user']) if 'user' in data else None
|
|
|
|
def __repr__(self) -> str:
|
|
return f'<Gift code={self.code!r} sku_id={self.sku_id} uses={self.uses} max_uses={self.max_uses} redeemed={self.redeemed}>'
|
|
|
|
def __eq__(self, other: Any) -> bool:
|
|
return isinstance(other, Gift) and other.code == self.code
|
|
|
|
def __ne__(self, other: Any) -> bool:
|
|
if isinstance(other, Gift):
|
|
return other.code != self.code
|
|
return True
|
|
|
|
def __hash__(self) -> int:
|
|
return hash(self.code)
|
|
|
|
@property
|
|
def id(self) -> str:
|
|
""":class:`str`: Returns the code portion of the gift."""
|
|
return self.code
|
|
|
|
@property
|
|
def url(self) -> str:
|
|
""":class:`str`: Returns the gift's URL."""
|
|
return f'https://discord.gift/{self.code}'
|
|
|
|
@property
|
|
def remaining_uses(self) -> int:
|
|
""":class:`int`: Returns the number of remaining uses for the gift."""
|
|
return self.max_uses - self.uses
|
|
|
|
@property
|
|
def flags(self) -> GiftFlags:
|
|
""":class:`GiftFlags`: Returns the gift's flags."""
|
|
return GiftFlags._from_value(self._flags)
|
|
|
|
@property
|
|
def premium_type(self) -> Optional[PremiumType]:
|
|
"""Optional[:class:`PremiumType`]: The premium type this gift grants, if it is for a premium subscription."""
|
|
return PremiumType.from_sku_id(self.sku_id) if self.is_subscription() else None
|
|
|
|
def is_claimed(self) -> bool:
|
|
""":class:`bool`: Checks if the gift has been used up."""
|
|
return self.uses >= self.max_uses if self.max_uses else False
|
|
|
|
def is_expired(self) -> bool:
|
|
""":class:`bool`: Checks if the gift has expired."""
|
|
return self.expires_at < utcnow() if self.expires_at else False
|
|
|
|
def is_subscription(self) -> bool:
|
|
""":class:`bool`: Checks if the gift is for a subscription."""
|
|
return self.subscription_plan_id is not None
|
|
|
|
def is_premium_subscription(self) -> bool:
|
|
""":class:`bool`: Checks if the gift is for a premium subscription."""
|
|
return self.is_subscription() and self.application_id == self._state.premium_subscriptions_application.id
|
|
|
|
async def redeem(
|
|
self,
|
|
payment_source: Optional[Snowflake] = None,
|
|
*,
|
|
channel: Optional[Snowflake] = None,
|
|
gateway_checkout_context: Optional[str] = None,
|
|
) -> Entitlement:
|
|
"""|coro|
|
|
|
|
Redeems the gift.
|
|
|
|
Parameters
|
|
----------
|
|
payment_source: Optional[:class:`PaymentSource`]
|
|
The payment source to use for the redemption.
|
|
Only required if the gift's :attr:`flags` have :attr:`GiftFlags.payment_source_required` set to ``True``.
|
|
channel: Optional[Union[:class:`TextChannel`, :class:`VoiceChannel`, :class:`StageChannel`, :class:`Thread`, :class:`DMChannel`, :class:`GroupChannel`]]
|
|
The channel to redeem the gift in. This is usually the channel the gift was sent in.
|
|
While this is optional, it is recommended to pass this in.
|
|
gateway_checkout_context: Optional[:class:`str`]
|
|
The current checkout context.
|
|
|
|
Raises
|
|
------
|
|
HTTPException
|
|
The gift failed to redeem.
|
|
|
|
Returns
|
|
-------
|
|
:class:`Entitlement`
|
|
The entitlement that was created from redeeming the gift.
|
|
"""
|
|
data = await self._state.http.redeem_gift(
|
|
self.code,
|
|
payment_source.id if payment_source else None,
|
|
channel.id if channel else None,
|
|
gateway_checkout_context,
|
|
)
|
|
return Entitlement(data=data, state=self._state)
|
|
|
|
async def delete(self) -> None:
|
|
"""|coro|
|
|
|
|
Revokes the gift.
|
|
|
|
This is only possible for gifts the current account has created.
|
|
|
|
Raises
|
|
------
|
|
NotFound
|
|
The owned gift was not found.
|
|
HTTPException
|
|
The gift failed to delete.
|
|
"""
|
|
await self._state.http.delete_gift(self.code)
|
|
|
|
|
|
class GiftBatch(Hashable):
|
|
"""Represents a batch of gifts for an SKU.
|
|
|
|
.. container:: operations
|
|
|
|
.. describe:: x == y
|
|
|
|
Checks if two gift batches are equal.
|
|
|
|
.. describe:: x != y
|
|
|
|
Checks if two gift batches are not equal.
|
|
|
|
.. describe:: hash(x)
|
|
|
|
Returns the gift batch's hash.
|
|
|
|
.. describe:: str(x)
|
|
|
|
Returns the gift batch's description.
|
|
|
|
.. versionadded:: 2.0
|
|
|
|
Attributes
|
|
-----------
|
|
id: :class:`int`
|
|
The ID of the gift batch.
|
|
application_id: :class:`int`
|
|
The ID of the application the gift batch is for.
|
|
sku_id: :class:`int`
|
|
The ID of the SKU the gift batch is for.
|
|
amount: :class:`int`
|
|
The amount of gifts in the batch.
|
|
description: :class:`str`
|
|
The description of the gift batch.
|
|
entitlement_branches: List[:class:`int`]
|
|
The entitlement branches the gift batch is for.
|
|
entitlement_starts_at: Optional[:class:`datetime.datetime`]
|
|
When the entitlement is valid from.
|
|
entitlement_ends_at: Optional[:class:`datetime.datetime`]
|
|
When the entitlement is valid until.
|
|
"""
|
|
|
|
__slots__ = (
|
|
'id',
|
|
'application_id',
|
|
'sku_id',
|
|
'amount',
|
|
'description',
|
|
'entitlement_branches',
|
|
'entitlement_starts_at',
|
|
'entitlement_ends_at',
|
|
'_state',
|
|
)
|
|
|
|
def __init__(self, *, data: GiftBatchPayload, state: ConnectionState, application_id: int) -> None:
|
|
self._state: ConnectionState = state
|
|
self.id: int = int(data['id'])
|
|
self.application_id = application_id
|
|
self.sku_id: int = int(data['sku_id'])
|
|
self.amount: int = data['amount']
|
|
self.description: str = data.get('description', '')
|
|
self.entitlement_branches: List[int] = [int(branch) for branch in data.get('entitlement_branches', [])]
|
|
self.entitlement_starts_at: Optional[datetime] = parse_time(data.get('entitlement_starts_at'))
|
|
self.entitlement_ends_at: Optional[datetime] = parse_time(data.get('entitlement_ends_at'))
|
|
|
|
def __repr__(self) -> str:
|
|
return f'<GiftBatch id={self.id} sku_id={self.sku_id} amount={self.amount} description={self.description!r}>'
|
|
|
|
def __str__(self) -> str:
|
|
return self.description
|
|
|
|
def is_valid(self) -> bool:
|
|
""":class:`bool`: Checks if the gift batch is valid."""
|
|
if self.entitlement_starts_at and self.entitlement_starts_at > utcnow():
|
|
return False
|
|
if self.entitlement_ends_at and self.entitlement_ends_at < utcnow():
|
|
return False
|
|
return True
|
|
|
|
async def download(self) -> bytes:
|
|
"""|coro|
|
|
|
|
Returns the gifts in the gift batch in CSV format.
|
|
|
|
Raises
|
|
-------
|
|
Forbidden
|
|
You do not have permissions to download the batch.
|
|
HTTPException
|
|
Downloading the batch failed.
|
|
|
|
Returns
|
|
-------
|
|
:class:`bytes`
|
|
The report content.
|
|
"""
|
|
return await self._state.http.get_gift_batch_csv(self.application_id, self.id)
|
|
|