Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(guild, channel): implement new helper methods #600

Merged
merged 20 commits into from Mar 20, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion interactions/api/http.py
Expand Up @@ -1500,7 +1500,7 @@ async def get_channel_invites(self, channel_id: int) -> List[Invite]:

async def create_channel_invite(
self, channel_id: int, data: dict, reason: Optional[str] = None
) -> Invite:
) -> dict:
"""
Creates an invite for the given channel.

Expand Down
104 changes: 104 additions & 0 deletions interactions/api/models/channel.py
Expand Up @@ -846,6 +846,110 @@ async def create_thread(

return Channel(**res, _client=self._client)

@classmethod
async def get(
cls,
channel: Union[int, str],
client: "HTTPClient", # noqa
) -> "Channel":
"""
Gets a channel based of its URL or its id.

:param channel: The URL to the channel or the id of the channel
:type channel: Union[int, str]
:param client: The HTTPClient of your bot. Set as ``bot._http``
:type client: HTTPClient
"""

channel_id = channel if isinstance(channel, int) else int(channel.split(sep="/")[-1])

res = await client.get_channel(channel_id)
return cls(**res, _client=client)

@property
def url(self) -> str:
guild_id = "@me" if not isinstance(self.guild_id, int) else self.guild_id
return f"https://discord.com/channels/{guild_id}/{self.id}"

async def create_invite(
self,
max_age: Optional[int] = 86400,
max_uses: Optional[int] = 0,
temporary: Optional[bool] = False,
unique: Optional[bool] = False,
target_type: Optional["InviteTargetType"] = MISSING, # noqa
target_user_id: Optional[int] = MISSING,
target_application_id: Optional[int] = MISSING,
reason: Optional[str] = None,
) -> "Invite": # noqa
"""
Creates an invite for the channel

:param max_age?: Duration of invite in seconds before expiry, or 0 for never. between 0 and 604800 (7 days). Default 86400 (24h)
:type max_age: Optional[int]
:param max_uses?: Max number of uses or 0 for unlimited. between 0 and 100. Default 0
:type max_uses: Optional[int]
:param temporary?: Whether this invite only grants temporary membership. Default False
:type temporary: Optional[bool]
:param unique?: If true, don't try to reuse a similar invite (useful for creating many unique one time use invites). Default False
:type unique: Optional[bool]
:param target_type?: The type of target for this voice channel invite
:type target_type: Optional["InviteTargetType"]
:param target_user_id?: The id of the user whose stream to display for this invite, required if target_type is STREAM, the user must be streaming in the channel
:type target_user_id: Optional[int]
:param target_application_id?: The id of the embedded application to open for this invite, required if target_type is EMBEDDED_APPLICATION, the application must have the EMBEDDED flag
:type target_application_id: Optional[int]
:param reason?: The reason for the creation of the invite
:type reason: Optional[str]
"""

if not self._client:
raise AttributeError("HTTPClient not found!")

payload = {
"max_age": max_age,
"max_uses": max_uses,
"temporary": temporary,
"unique": unique,
}

if (target_user_id is not MISSING and target_user_id) and (
target_application_id is not MISSING and target_application_id
):
raise ValueError(
"target user id and target application are mutually exclusive!"
) # TODO: move to custom error formatter

elif (
(target_user_id is not MISSING and target_user_id)
or (target_application_id is not MISSING and target_application_id)
) and not target_type:
raise ValueError(
"you have to specify a target_type if you specify target_user-/target_application_id"
)

if target_user_id is not MISSING:
payload["target_type"] = (
target_type if isinstance(target_type, int) else target_type.value
)
payload["target_user_id"] = target_user_id

if target_application_id is not MISSING:
payload["target_type"] = (
target_type if isinstance(target_type, int) else target_type.value
)
payload["target_application_id"] = target_application_id

res = await self._client.create_channel_invite(
channel_id=int(self.id),
data=payload,
reason=reason,
)

from .guild import Invite

return Invite(**res, _client=self._client)


class Thread(Channel):
"""An object representing a thread.
Expand Down
19 changes: 19 additions & 0 deletions interactions/api/models/channel.pyi
Expand Up @@ -2,6 +2,7 @@ from datetime import datetime
from enum import IntEnum
from typing import List, Optional, Union, Callable

from .guild import Invite, InviteTargetType
from .message import Message, Embed, MessageInteraction
from ...models.component import ActionRow, Button, SelectMenu
from .misc import DictSerializerMixin, Overwrite, Snowflake, MISSING
Expand Down Expand Up @@ -189,5 +190,23 @@ class Channel(DictSerializerMixin):
message_id: Optional[int] = MISSING,
reason: Optional[str] = None,
) -> "Channel": ...
@classmethod
async def get(
cls,
channel: Union[int, str],
client: HTTPClient,
) -> "Channel": ...
@property
def url(self) -> str: ...
async def create_invite(
self,
max_age: int = 86400,
max_uses: int = 0,
temporary: bool = False,
unique: bool = False,
target_type: InviteTargetType = MISSING,
target_user_id: int = MISSING,
target_application_id: int = MISSING,
) -> Invite: ...

class Thread(Channel): ...
33 changes: 33 additions & 0 deletions interactions/api/models/guild.py
Expand Up @@ -54,6 +54,13 @@ class EventStatus(IntEnum):
CANCELED = 4


class InviteTargetType(IntEnum):
"""An enumerable object representing the different invite target types"""

STREAM = 1
EMBEDDED_APPLICATION = 2


class WelcomeChannels(DictSerializerMixin):
"""
A class object representing a welcome channel on the welcome screen.
Expand Down Expand Up @@ -1480,6 +1487,24 @@ async def get_bans(self) -> List[dict]:
ban["user"] = User(**ban["user"])
return res

@classmethod
async def get(
cls,
guild_id: int,
client: "HTTPClient", # noqa
) -> "Guild":
"""
Gets a guild.

:param guild_id: The id of the guild to get
:type guild_id: int
:param client: The HTTPClient of your bot. Equals to ``bot._http``
:type client: HTTPClient
"""

guild = await client.get_guild(guild_id=guild_id)
return cls(**guild, _client=client)

async def get_emoji(
self,
emoji_id: int,
Expand Down Expand Up @@ -1694,6 +1719,14 @@ def __init__(self, **kwargs):
else None
)

async def delete(self) -> None:
"""Deletes the invite"""

if not self._client:
raise AttributeError("HTTPClient not found!")

await self._client.delete_invite(self.code)


class GuildTemplate(DictSerializerMixin):
"""
Expand Down
11 changes: 11 additions & 0 deletions interactions/api/models/guild.pyi
Expand Up @@ -38,6 +38,10 @@ class EventStatus(IntEnum):
COMPLETED: int
CANCELED: int

class InviteTargetType(IntEnum):
STREAM: int
EMBEDDED_APPLICATION: int

class WelcomeChannels(DictSerializerMixin):
_json: dict
channel_id: int
Expand Down Expand Up @@ -384,6 +388,12 @@ class Guild(DictSerializerMixin):
reason: Optional[str] = None,
) -> List[Role]: ...
async def get_bans(self) -> List[dict]: ...
@classmethod
async def get(
cls,
guild_id: int,
client: "HTTPClient", # noqa
) -> "Guild": ...
async def get_emoji(
self,
emoji_id: int
Expand Down Expand Up @@ -422,6 +432,7 @@ class Invite(DictSerializerMixin):
temporary: bool
created_at: datetime
def __init__(self, **kwargs): ...
async def delete(self) -> None: ...

class GuildTemplate(DictSerializerMixin):
_json: dict
Expand Down