feat(rest): bulk overwrite global application commands method

This commit is contained in:
grey-cat-1908 2022-07-30 19:15:49 +03:00
parent b6bf4dc1a8
commit 65663e0eb9
4 changed files with 140 additions and 18 deletions

View file

@ -6,7 +6,7 @@ from __future__ import annotations
import asyncio
import logging
from urllib.parse import quote
from typing import Dict, Optional, Any
from typing import Dict, Optional, Any, Union, List
from aiohttp import ClientSession, ClientResponse
@ -165,7 +165,9 @@ class HTTPClient:
return await self.__send(method, endpoint, _ttl=_ttl - 1, **kwargs)
async def get(self, route: str, *, params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
async def get(
self, route: str, *, params: Optional[Dict[str, Any]] = None
) -> Optional[Dict[str, Any]]:
"""|coro|
Sends a GET request to a Discord REST API endpoint.
@ -212,7 +214,9 @@ class HTTPClient:
"""
return await self.__send("POST", route, json=json, data=data, headers=headers)
async def delete(self, route: str, *, headers: Dict[str, Any] = None) -> Optional[Dict[str, Any]]:
async def delete(
self, route: str, *, headers: Dict[str, Any] = None
) -> Optional[Dict[str, Any]]:
"""|coro|
Sends a DELETE request to a Discord REST API endpoint.
@ -260,7 +264,12 @@ class HTTPClient:
return await self.__send("PATCH", route, json=json, data=data, headers=headers)
async def put(
self, route: str, *, headers: Dict[str, Any] = None, data: Optional[Dict[str, Any]] = None
self,
route: str,
*,
headers: Dict[str, Any] = None,
json: Optional[Union[List[Any], Dict[str, Any]]] = None,
data: Optional[Dict[str, Any]] = None,
) -> Optional[Dict[str, Any]]:
"""|coro|
Sends a PUT request to a Discord REST API endpoint.
@ -271,6 +280,8 @@ class HTTPClient:
The endpoint to send the request to.
data : Dict
Data to post
json: Dict
Json data to post
headers : :class:`dict`
Custom request headers
@ -279,4 +290,4 @@ class HTTPClient:
Optional[:class:`Dict`]
JSON response from the Discord API.
"""
return await self.__send("PUT", route, json=data, headers=headers)
return await self.__send("PUT", route, json=json, data=data, headers=headers)

View file

@ -155,6 +155,7 @@ class SlashCommand(PartialApplicationCommand):
"""
description: LocalizedField = None
options: List[SlashCommandOption] = None
@classmethod
def from_dict(cls, data: Dict[str, Any]):
@ -314,7 +315,7 @@ class SlashCommandOptionChoice(APIModelBase):
name_localizations = data.get("name_localizations")
self.name = LocalizedField(name, name_localizations)
self.value = data.get("value")
return self
@ -374,13 +375,15 @@ class SlashCommandInteractionDataOption(APIModelBase):
# noinspection PyTypeChecker
command_types_for_converting: Dict[ApplicationCommandType, PartialApplicationCommand] = {
ApplicationCommandType.CHAT_INPUT: SlashCommand
}
command_types_for_converting: Dict[
ApplicationCommandType, PartialApplicationCommand
] = {ApplicationCommandType.CHAT_INPUT: SlashCommand}
def _choose_command_type(data):
data.update({"type": ApplicationCommandType(data.pop("type"))})
command_cls = command_types_for_converting.get(data["type"], PartialApplicationCommand)
command_cls = command_types_for_converting.get(
data["type"], PartialApplicationCommand
)
return command_cls.from_dict(data)

View file

@ -3,7 +3,7 @@
from __future__ import annotations
from typing import Dict
from typing import Dict, Optional
class LocalizedField:
@ -18,7 +18,6 @@ class LocalizedField:
Localization dictionary for the name field.
Values follow the same restrictions as name
"""
original: str
@ -44,7 +43,10 @@ class LocalizedField:
return f"<LocalizedField original={self.original} localizations={self.localizations}>"
def __eq__(self, other):
return self.original == other.original and self.localizations == other.localizations
return (
self.original == other.original
and self.localizations == other.localizations
)
def __hash__(self):
return hash((self.original, self.localizations))

View file

@ -7,8 +7,12 @@ from typing import Union, Optional, List, Dict, Any, AsyncIterator
from aiohttp import FormData
from .models.interactions import ApplicationCommandType
from .models.interactions.commands import SlashCommandOption, SlashCommand, PartialApplicationCommand, \
_choose_command_type
from .models.interactions.commands import (
SlashCommandOption,
SlashCommand,
PartialApplicationCommand,
_choose_command_type,
)
from .models.interactions.i18n import LocalizedField
from .models.message import Embed, File, AllowedMentions, Message
from .exceptions import EmbedFieldError
@ -943,13 +947,15 @@ class RESTApp:
data = {
"name": name.original,
"description": description.original,
"type": int(command_type),
}
if name.localizations is not None:
data["name_localizations"] = name.localizations
if description.original is not None:
data["description"] = description.original
if description.localizations is not None:
data["description_localizations"] = description.localizations
@ -966,7 +972,9 @@ class RESTApp:
if option.name.localizations is not None:
option_data["name_localizations"] = option.name.localizations
if option.description.localizations is not None:
option_data["description_localizations"] = option.description.localizations
option_data[
"description_localizations"
] = option.description.localizations
if dm_permission is not None:
data["dm_permission"] = dm_permission
@ -1081,8 +1089,23 @@ class RESTApp:
if default_member_permissions is not None:
data["default_member_permissions"] = default_member_permissions
data["options"] = []
if options is not None:
data["options"] = [x.to_dict() for x in options]
for option in options:
option_data = option.to_dict()
option_data["name"] = option.name.original
option_data["description"] = option.description.original
if option.name.localizations is not None:
option_data["name_localizations"] = option.name.localizations
if option.description.localizations is not None:
option_data[
"description_localizations"
] = option.description.localizations
data["options"].append(option_data)
if dm_permission is not None:
data["dm_permission"] = dm_permission
@ -1126,6 +1149,89 @@ class RESTApp:
return None
async def bulk_overwrite_global_application_commands(
self,
application_id: Union[int, str, Snowflake],
commands: List[Union[SlashCommand, PartialApplicationCommand]],
) -> List[Union[SlashCommand, PartialApplicationCommand]]:
"""|coro|
[**REST API**] Overwrites all existing global commands.
Parameters
----------
application_id: :class:`~melisa.utils.snowflake.Snowflake`
ID of the parent application
commands: List[Union[:class:`~melisa.models.interactions.commands.SlashCommand`,
:class:`~melisa.models.interactions.commands.PartialApplicationCommand`]]
Raises
-------
HTTPException
The request to perform the action failed with other http exception.
ForbiddenError
You do not have proper permissions to do the actions required.
BadRequestError
You provided a wrong arguments
"""
better_commands = []
for command in commands:
command_data = {
"name": command.name.original,
"type": int(command.type),
}
if command.name.localizations is not None:
command_data["name_localizations"] = command.name.localizations
if command.default_member_permissions is not None:
command_data[
"default_member_permissions"
] = command.default_member_permissions
if command.dm_permission is not None:
command_data["dm_permission"] = command.dm_permission
if isinstance(command, SlashCommand):
if command.description is not None:
command_data["description"] = command.description.original
if command.description.localizations is not None:
command_data[
"description_localizations"
] = command.description.localizations
command_data["options"] = []
if command.options is not None:
for option in command.options:
option_data = option.to_dict()
option_data["name"] = option.name.original
option_data["description"] = option.description.original
if option.name.localizations is not None:
option_data[
"name_localizations"
] = option.name.localizations
if option.description.localizations is not None:
option_data[
"description_localizations"
] = option.description.localizations
command_data["options"].append(option_data)
better_commands.append(command_data)
return [
_choose_command_type(x)
for x in await self._http.put(
f"/applications/{application_id}/commands", json=better_commands
)
]
class CDNBuilder:
"""Can be used to build images