Skip to content

feat: fully update http.py routes and related methods #53

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,13 @@ async def _edit(self, options: dict[str, Any], reason: str | None) -> ChannelPay
default_reaction_emoji._to_forum_reaction_payload() if default_reaction_emoji else None
)

try:
icon = options["icon"]
except KeyError:
pass
else:
options["icon"] = icon and utils._bytes_to_base64_data(icon)

if options:
return await self._state.http.edit_channel(self.id, reason=reason, **options)

Expand Down
42 changes: 42 additions & 0 deletions discord/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3215,6 +3215,48 @@ async def leave(self) -> None:

await self._state.http.leave_group(self.id)

@overload
async def edit(
self,
*,
name: str = ...,
icon: bytes | None = ...,
) -> GroupChannel: ...

@overload
async def edit(self) -> GroupChannel: ...

async def edit(self, *, reason=None, **options):
"""|coro|

Edits this group DM channel.

.. versionadded:: 3.0

Parameters
----------
name: :class:`str`
The new channel name.
icon: :class:`bytes`
A :term:`py:bytes-like object` representing the icon. Only PNG/JPEG is supported.
Could be ``None`` to denote removal of the icon.

Returns
-------
:class:`.GroupChannel`
The newly edited text channel.

Raises
------
Forbidden
You do not have permissions to edit the channel.
HTTPException
Editing the channel failed.
"""
payload = await self._edit(options, reason=reason)
if payload is not None:
return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore


class PartialMessageable(discord.abc.Messageable, Hashable):
"""Represents a partial messageable to aid with working messageable channels when
Expand Down
49 changes: 0 additions & 49 deletions discord/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1587,55 +1587,6 @@ async def fetch_guild(self, guild_id: int, /, *, with_counts=True) -> Guild:
data = await self.http.get_guild(guild_id, with_counts=with_counts)
return Guild(data=data, state=self._connection)

async def create_guild(
self,
*,
name: str,
icon: bytes | utils.Undefined = MISSING,
code: str | utils.Undefined = MISSING,
) -> Guild:
"""|coro|

Creates a :class:`.Guild`.

Bot accounts in more than 10 guilds are not allowed to create guilds.

Parameters
----------
name: :class:`str`
The name of the guild.
icon: Optional[:class:`bytes`]
The :term:`py:bytes-like object` representing the icon. See :meth:`.ClientUser.edit`
for more details on what is expected.
code: :class:`str`
The code for a template to create the guild with.

.. versionadded:: 1.4

Returns
-------
:class:`.Guild`
The guild created. This is not the same guild that is
added to cache.

Raises
------
:exc:`HTTPException`
Guild creation failed.
:exc:`InvalidArgument`
Invalid icon image format given. Must be PNG or JPG.
"""
if icon is not MISSING:
icon_base64 = utils._bytes_to_base64_data(icon)
else:
icon_base64 = None

if code:
data = await self.http.create_from_template(code, name, icon_base64)
else:
data = await self.http.create_guild(name, icon_base64)
return Guild(data=data, state=self._connection)

async def fetch_stage_instance(self, channel_id: int, /) -> StageInstance:
"""|coro|

Expand Down
41 changes: 0 additions & 41 deletions discord/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -1538,21 +1538,6 @@ async def leave(self) -> None:
"""
await self._state.http.leave_guild(self.id)

async def delete(self) -> None:
"""|coro|

Deletes the guild. You must be the guild owner to delete the
guild.

Raises
------
HTTPException
Deleting the guild failed.
Forbidden
You do not have permissions to delete the guild.
"""
await self._state.http.delete_guild(self.id)

async def set_mfa_required(self, required: bool, *, reason: str = None) -> None:
"""|coro|

Expand Down Expand Up @@ -2348,32 +2333,6 @@ async def create_template(self, *, name: str, description: str | utils.Undefined

return Template(state=self._state, data=data)

async def create_integration(self, *, type: str, id: int) -> None:
"""|coro|

Attaches an integration to the guild.

You must have the :attr:`~Permissions.manage_guild` permission to
do this.

.. versionadded:: 1.4

Parameters
----------
type: :class:`str`
The integration type (e.g. Twitch).
id: :class:`int`
The integration ID.

Raises
------
Forbidden
You do not have permission to create the integration.
HTTPException
The account could not be found.
"""
await self._state.http.create_integration(self.id, type, id)

async def integrations(self) -> list[Integration]:
"""|coro|

Expand Down
95 changes: 11 additions & 84 deletions discord/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,13 +420,6 @@ def logout(self) -> Response[None]:

# Group functionality

def start_group(self, user_id: Snowflake, recipients: list[int]) -> Response[channel.GroupDMChannel]:
payload = {
"recipients": recipients,
}

return self.request(Route("POST", "/users/{user_id}/channels", user_id=user_id), json=payload)

def leave_group(self, channel_id) -> Response[None]:
return self.request(Route("DELETE", "/channels/{channel_id}", channel_id=channel_id))

Expand Down Expand Up @@ -952,19 +945,6 @@ def guild_voice_state(
def edit_profile(self, payload: dict[str, Any]) -> Response[user.User]:
return self.request(Route("PATCH", "/users/@me"), json=payload)

def change_my_nickname(
self,
guild_id: Snowflake,
nickname: str,
*,
reason: str | None = None,
) -> Response[member.Nickname]:
r = Route("PATCH", "/guilds/{guild_id}/members/@me", guild_id=guild_id)
payload = {
"nick": nickname,
}
return self.request(r, json=payload, reason=reason)

def change_nickname(
self,
guild_id: Snowflake,
Expand Down Expand Up @@ -997,6 +977,16 @@ def edit_voice_state(self, guild_id: Snowflake, user_id: Snowflake, payload: dic
)
return self.request(r, json=payload)

def edit_current_member(
self,
guild_id: Snowflake,
*,
reason: str | None = None,
**fields: Any,
) -> Response[member.Member]:
r = Route("PATCH", "/guilds/{guild_id}/members/@me", guild_id=guild_id)
return self.request(r, json=fields, reason=reason)

def edit_member(
self,
guild_id: Snowflake,
Expand Down Expand Up @@ -1025,6 +1015,7 @@ def edit_channel(
r = Route("PATCH", "/channels/{channel_id}", channel_id=channel_id)
valid_keys = (
"name",
"icon",
"parent_id",
"topic",
"bitrate",
Expand Down Expand Up @@ -1405,18 +1396,6 @@ def get_guild(self, guild_id: Snowflake, *, with_counts=True) -> Response[guild.
params = {"with_counts": int(with_counts)}
return self.request(Route("GET", "/guilds/{guild_id}", guild_id=guild_id), params=params)

def delete_guild(self, guild_id: Snowflake) -> Response[None]:
return self.request(Route("DELETE", "/guilds/{guild_id}", guild_id=guild_id))

def create_guild(self, name: str, icon: str | None) -> Response[guild.Guild]:
payload = {
"name": name,
}
if icon:
payload["icon"] = icon

return self.request(Route("POST", "/guilds"), json=payload)

def edit_guild(self, guild_id: Snowflake, *, reason: str | None = None, **fields: Any) -> Response[guild.Guild]:
valid_keys = (
"name",
Expand Down Expand Up @@ -1505,15 +1484,6 @@ def delete_template(self, guild_id: Snowflake, code: str) -> Response[None]:
)
)

def create_from_template(self, code: str, name: str, icon: str | None) -> Response[guild.Guild]:
payload = {
"name": name,
}
if icon:
payload["icon"] = icon

return self.request(Route("POST", "/guilds/templates/{code}", code=code), json=payload)

def get_bans(
self,
guild_id: Snowflake,
Expand Down Expand Up @@ -1843,15 +1813,6 @@ def get_all_integrations(self, guild_id: Snowflake) -> Response[list[integration

return self.request(r)

def create_integration(self, guild_id: Snowflake, type: integration.IntegrationType, id: int) -> Response[None]:
payload = {
"type": type,
"id": id,
}

r = Route("POST", "/guilds/{guild_id}/integrations", guild_id=guild_id)
return self.request(r, json=payload)

def edit_integration(self, guild_id: Snowflake, integration_id: Snowflake, **payload: Any) -> Response[None]:
r = Route(
"PATCH",
Expand Down Expand Up @@ -2027,16 +1988,6 @@ def delete_role(self, guild_id: Snowflake, role_id: Snowflake, *, reason: str |
)
return self.request(r, reason=reason)

def replace_roles(
self,
user_id: Snowflake,
guild_id: Snowflake,
role_ids: list[int],
*,
reason: str | None = None,
) -> Response[member.MemberWithUser]:
return self.edit_member(guild_id=guild_id, user_id=user_id, roles=role_ids, reason=reason)

def create_role(self, guild_id: Snowflake, *, reason: str | None = None, **fields: Any) -> Response[role.Role]:
r = Route("POST", "/guilds/{guild_id}/roles", guild_id=guild_id)
return self.request(r, json=fields, reason=reason)
Expand Down Expand Up @@ -2141,16 +2092,6 @@ def edit_welcome_screen(

# Voice management

def move_member(
self,
user_id: Snowflake,
guild_id: Snowflake,
channel_id: Snowflake,
*,
reason: str | None = None,
) -> Response[member.MemberWithUser]:
return self.edit_member(guild_id=guild_id, user_id=user_id, channel_id=channel_id, reason=reason)

def set_voice_channel_status(
self, channel_id: Snowflake, status: str | None, *, reason: str | None = None
) -> Response[None]:
Expand Down Expand Up @@ -2777,20 +2718,6 @@ def edit_application_command_permissions(
)
return self.request(r, json=payload)

def bulk_edit_guild_application_command_permissions(
self,
application_id: Snowflake,
guild_id: Snowflake,
payload: list[interactions.PartialGuildApplicationCommandPermissions],
) -> Response[None]:
r = Route(
"PUT",
"/applications/{application_id}/guilds/{guild_id}/commands/permissions",
application_id=application_id,
guild_id=guild_id,
)
return self.request(r, json=payload)

# Application Role Connections

def get_application_role_connection_metadata_records(
Expand Down
2 changes: 1 addition & 1 deletion discord/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ async def edit(
if nick is not MISSING:
nick = nick or ""
if me:
await http.change_my_nickname(guild_id, nick, reason=reason)
await http.edit_current_member(guild_id, reason=reason, nick=nick)
else:
payload["nick"] = nick

Expand Down
34 changes: 0 additions & 34 deletions discord/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,40 +166,6 @@ def __repr__(self) -> str:
f" creator={self.creator!r} source_guild={self.source_guild!r} is_dirty={self.is_dirty}>"
)

async def create_guild(self, name: str, icon: Any = None) -> Guild:
"""|coro|

Creates a :class:`.Guild` using the template.

Bot accounts in more than 10 guilds are not allowed to create guilds.

Parameters
----------
name: :class:`str`
The name of the guild.
icon: :class:`bytes`
The :term:`py:bytes-like object` representing the icon. See :meth:`.ClientUser.edit`
for more details on what is expected.

Returns
-------
:class:`.Guild`
The guild created. This is not the same guild that is
added to cache.

Raises
------
HTTPException
Guild creation failed.
InvalidArgument
Invalid icon image format given. Must be PNG or JPG.
"""
if icon is not None:
icon = _bytes_to_base64_data(icon)

data = await self._state.http.create_from_template(self.code, name, icon)
return Guild(data=data, state=self._state)

async def sync(self) -> Template:
"""|coro|

Expand Down