Skip to content

Commit

Permalink
Add initial entitlements
Browse files Browse the repository at this point in the history
  • Loading branch information
4Kaylum committed Jul 22, 2024
1 parent ac69e0f commit b4ed2d9
Show file tree
Hide file tree
Showing 19 changed files with 566 additions and 13 deletions.
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ repos:
entry: isort
language: python
types: [python]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
Expand Down
2 changes: 2 additions & 0 deletions docs/api/enums.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ Enums
.. autoclass:: VerificationLevel
.. autoclass:: Status
.. autoclass:: ActivityType
.. autoclass:: SKUType
.. autoclass:: EntitlementType
6 changes: 6 additions & 0 deletions docs/api/flags.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,9 @@ Flags
.. py:attribute:: auto_moderation_block_message
.. py:attribute:: auto_moderation_flag_to_channel
.. py:attribute:: auto_moderation_user_communication_disabled
.. class:: SKUFlags

.. py:attribute:: available
.. py:attribute:: guild_subscription
.. py:attribute:: user_subscription
8 changes: 8 additions & 0 deletions docs/api/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,11 @@ Models that relate to interactions.
:inherited-members:
:no-special-members:
.. .. autoclass:: InteractionWebhook
.. autoclass:: Entitlement
:members:
:inherited-members:
:no-special-members:
.. autoclass:: SKU
:members:
:inherited-members:
:no-special-members:
5 changes: 5 additions & 0 deletions novus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
'ContextComandData',
'Embed',
'Emoji',
'Entitlement',
'EntitlementType',
'EventEntityType',
'EventPrivacyLevel',
'EventStatus',
Expand Down Expand Up @@ -132,6 +134,9 @@
'Reaction',
'Role',
'RoleSelectMenu',
'SKU',
'SKUFlags',
'SKUType',
'ScheduledEvent',
'SelectOption',
'StageInstance',
Expand Down
6 changes: 6 additions & 0 deletions novus/api/_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ def __repr__(self) -> str:
def do_nothing(instance: Any, *items: Any) -> None:
pass

@property
def application_id(self) -> int | None:
if self.application:
return self.application.id
return None

def add_guilds(self, *items: Guild) -> None:
for i in items:
self.guild_ids.add(i.id)
Expand Down
9 changes: 9 additions & 0 deletions novus/api/_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from .guild_template import GuildTemplateHTTPConnection
from .interaction import InteractionHTTPConnection
from .invite import InviteHTTPConnection
from .monetization import MonetizationHTTPConnection
from .oauth2 import Oauth2HTTPConnection
from .stage_instance import StageHTTPConnection
from .sticker import StickerHTTPConnection
Expand Down Expand Up @@ -127,12 +128,15 @@ class HTTPConnection:
guild_template : GuildTemplateHTTPConnection
interaction : InteractionHTTPConnection
invite : InviteHTTPConnection
monetization : MonetizationHTTPConnection
oauth2 : Oauth2HTTPConnection
stage_instance : StageHTTPConnection
sticker : StickerHTTPConnection
user : UserHTTPConnection
voice : VoiceHTTPConnection
webhook : WebhookHTTPConnection
application_id : int
The ID of the associated application.
"""

AUTH_PREFIX: str = "Bot"
Expand Down Expand Up @@ -167,6 +171,7 @@ def __init__(
self.guild_template = GuildTemplateHTTPConnection(self)
self.interaction = InteractionHTTPConnection(self)
self.invite = InviteHTTPConnection(self)
self.monetization = MonetizationHTTPConnection(self)
self.oauth2 = Oauth2HTTPConnection(self)
self.stage_instance = StageHTTPConnection(self)
self.sticker = StickerHTTPConnection(self)
Expand Down Expand Up @@ -195,6 +200,10 @@ async def __aexit__(self, *_args: Any) -> None:
if self._session:
await self._session.close()

@property
def application_id(self) -> int:
return self.cache.application_id

def request_params(
self,
*,
Expand Down
92 changes: 92 additions & 0 deletions novus/api/monetization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"""
Copyright (c) Kae Bartlett
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
any later version.
This program is dis2tributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from ._route import Route
from ..models import Entitlement, SKU

if TYPE_CHECKING:
from ._http import HTTPConnection
from .. import payloads

__all__ = (
'MonetizationHTTPConnection',
)


class MonetizationHTTPConnection:

def __init__(self, parent: HTTPConnection):
self.parent = parent

async def list_skus(
self,
application_id: int) -> list[SKU]:
"""List all SKUs associated with the given application ID."""

route = Route(
"GET",
"/applications/{application_id}/skus",
application_id=application_id,
)
data: list[payloads.SKU] = await self.parent.request(
route,
)
return [
SKU(state=self.parent, data=d)
for d in data
]

async def list_entitlements(
self,
application_id: int) -> list[Entitlement]:
"""List all entitlements associated with the given application ID."""

route = Route(
"GET",
"/applications/{application_id}/commands",
application_id=application_id,
)
data: list[payloads.ApplicationCommand] = await self.parent.request(
route,
)
return [
Entitlement(state=self.parent, data=d)
for d in data
]

async def consume_entitlement(
self,
application_id: int,
entitlement_id: int) -> list[Entitlement]:
"""List all entitlements associated with the given application ID."""

route = Route(
"GET",
"/applications/{application_id}/commands",
application_id=application_id,
)
data: list[payloads.ApplicationCommand] = await self.parent.request(
route,
)
return [
Entitlement(state=self.parent, data=d)
for d in data
]
3 changes: 3 additions & 0 deletions novus/enums/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from .guild import *
from .interaction import *
from .message import *
from .monetization import *
from .presence import *
from .scheduled_event import *
from .sticker import *
Expand All @@ -43,6 +44,7 @@
'ChannelType',
'ComponentType',
'ContentFilterLevel',
'EntitlementType',
'EventEntityType',
'EventPrivacyLevel',
'EventStatus',
Expand All @@ -57,6 +59,7 @@
'NotificationLevel',
'PermissionOverwriteType',
'PremiumTier',
'SKUType',
'Status',
'StickerFormat',
'StickerType',
Expand Down
43 changes: 43 additions & 0 deletions novus/enums/monetization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Copyright (c) Kae Bartlett
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""

from __future__ import annotations

from .utils import Enum

__all__ = (
'SKUType',
'EntitlementType',
)


class SKUType(Enum):
DURABLE = 2
CONSUMABLE = 3
SUBSCRIPTION = 5
SUBSCRIPTION_GROUP = 6


class EntitlementType(Enum):
PURCHASE = 1
PREMIUM_SUBSCRIPTION = 2
DEVELOPER_GIFT = 3
TEST_MODE_PURCHASE = 4
FREE_PURCHASE = 5
USER_GIFT = 6
PREMIUM_PURCHASE = 7
APPLICATION_SUBSCRIPTION = 8
32 changes: 24 additions & 8 deletions novus/ext/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,29 @@ async def _handle_command_sync(
log.info("Editing app command %s %s in guild %s", id, comm, guild_id)
await edit_(id, **comm.application_command._to_data())

async def fetch_application_id(self) -> int:
"""
Fetch and cache the application ID for the given token.
Returns
-------
int
The ID of the application
"""

aid: int | None = self.state.application_id
if aid is None:
app = self.state.cache.application
if app is None:
app = await self.state.oauth2.get_current_bot_information()
self.state.cache.application = app
aid = app.id
return aid

@property
def application_id(self) -> int:
return self.state.application_id

async def sync_commands(
self,
*,
Expand All @@ -642,14 +665,7 @@ async def sync_commands(
log.info(f"Syncing {len(command_length)} commands")

# Get application ID
aid: int | None = self.state.cache.application_id
if aid is None:
app = self.state.cache.application
if app is None:
app = await self.state.oauth2.get_current_bot_information()
self.state.cache.application = app
aid = app.id
assert aid
aid = await self.fetch_application_id()

# Group our commands by guild ID
commands_by_guild: dict[int | None, dict[str, Command]]
Expand Down
2 changes: 2 additions & 0 deletions novus/flags/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .gateway import *
from .guild import *
from .message import *
from .monetization import *
from .permissions import *
from .user import *

Expand All @@ -30,5 +31,6 @@
'MessageFlags',
'Permissions',
'SystemChannelFlags',
'SKUFlags',
'UserFlags',
)
41 changes: 41 additions & 0 deletions novus/flags/monetization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Copyright (c) Kae Bartlett
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from vfflags import Flags

__all__ = (
'SKUFlags',
)


class SKUFlags(Flags):
"""Flags associated with SKUs."""

if TYPE_CHECKING:
available: bool
guild_subscription: bool
user_subscription: bool

CREATE_FLAGS = {
"available": 1 << 2,
"guild_subscription": 1 << 7,
"user_subscription": 1 << 8,
}
3 changes: 3 additions & 0 deletions novus/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .file import *
from .guild import *
from .guild_member import *
from .monetization import *
from .interaction import *
from .invite import *
from .message import *
Expand Down Expand Up @@ -68,6 +69,7 @@
'ContextComandData',
'Embed',
'Emoji',
'Entitlement',
'File',
'ForumTag',
'Guild',
Expand Down Expand Up @@ -98,6 +100,7 @@
'Reaction',
'Role',
'RoleSelectMenu',
'SKU',
'ScheduledEvent',
'SelectOption',
'StageInstance',
Expand Down
Loading

0 comments on commit b4ed2d9

Please sign in to comment.