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 asyncio
import logging import logging
from urllib.parse import quote from urllib.parse import quote
from typing import Dict, Optional, Any from typing import Dict, Optional, Any, Union, List
from aiohttp import ClientSession, ClientResponse from aiohttp import ClientSession, ClientResponse
@ -165,7 +165,9 @@ class HTTPClient:
return await self.__send(method, endpoint, _ttl=_ttl - 1, **kwargs) 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| """|coro|
Sends a GET request to a Discord REST API endpoint. 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) 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| """|coro|
Sends a DELETE request to a Discord REST API endpoint. 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) return await self.__send("PATCH", route, json=json, data=data, headers=headers)
async def put( 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]]: ) -> Optional[Dict[str, Any]]:
"""|coro| """|coro|
Sends a PUT request to a Discord REST API endpoint. Sends a PUT request to a Discord REST API endpoint.
@ -271,6 +280,8 @@ class HTTPClient:
The endpoint to send the request to. The endpoint to send the request to.
data : Dict data : Dict
Data to post Data to post
json: Dict
Json data to post
headers : :class:`dict` headers : :class:`dict`
Custom request headers Custom request headers
@ -279,4 +290,4 @@ class HTTPClient:
Optional[:class:`Dict`] Optional[:class:`Dict`]
JSON response from the Discord API. 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 description: LocalizedField = None
options: List[SlashCommandOption] = None
@classmethod @classmethod
def from_dict(cls, data: Dict[str, Any]): def from_dict(cls, data: Dict[str, Any]):
@ -314,7 +315,7 @@ class SlashCommandOptionChoice(APIModelBase):
name_localizations = data.get("name_localizations") name_localizations = data.get("name_localizations")
self.name = LocalizedField(name, name_localizations) self.name = LocalizedField(name, name_localizations)
self.value = data.get("value") self.value = data.get("value")
return self return self
@ -374,13 +375,15 @@ class SlashCommandInteractionDataOption(APIModelBase):
# noinspection PyTypeChecker # noinspection PyTypeChecker
command_types_for_converting: Dict[ApplicationCommandType, PartialApplicationCommand] = { command_types_for_converting: Dict[
ApplicationCommandType.CHAT_INPUT: SlashCommand ApplicationCommandType, PartialApplicationCommand
} ] = {ApplicationCommandType.CHAT_INPUT: SlashCommand}
def _choose_command_type(data): def _choose_command_type(data):
data.update({"type": ApplicationCommandType(data.pop("type"))}) 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) return command_cls.from_dict(data)

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Dict from typing import Dict, Optional
class LocalizedField: class LocalizedField:
@ -18,7 +18,6 @@ class LocalizedField:
Localization dictionary for the name field. Localization dictionary for the name field.
Values follow the same restrictions as name Values follow the same restrictions as name
""" """
original: str original: str
@ -44,7 +43,10 @@ class LocalizedField:
return f"<LocalizedField original={self.original} localizations={self.localizations}>" return f"<LocalizedField original={self.original} localizations={self.localizations}>"
def __eq__(self, other): 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): def __hash__(self):
return hash((self.original, self.localizations)) 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 aiohttp import FormData
from .models.interactions import ApplicationCommandType from .models.interactions import ApplicationCommandType
from .models.interactions.commands import SlashCommandOption, SlashCommand, PartialApplicationCommand, \ from .models.interactions.commands import (
_choose_command_type SlashCommandOption,
SlashCommand,
PartialApplicationCommand,
_choose_command_type,
)
from .models.interactions.i18n import LocalizedField from .models.interactions.i18n import LocalizedField
from .models.message import Embed, File, AllowedMentions, Message from .models.message import Embed, File, AllowedMentions, Message
from .exceptions import EmbedFieldError from .exceptions import EmbedFieldError
@ -943,13 +947,15 @@ class RESTApp:
data = { data = {
"name": name.original, "name": name.original,
"description": description.original,
"type": int(command_type), "type": int(command_type),
} }
if name.localizations is not None: if name.localizations is not None:
data["name_localizations"] = name.localizations data["name_localizations"] = name.localizations
if description.original is not None:
data["description"] = description.original
if description.localizations is not None: if description.localizations is not None:
data["description_localizations"] = description.localizations data["description_localizations"] = description.localizations
@ -966,7 +972,9 @@ class RESTApp:
if option.name.localizations is not None: if option.name.localizations is not None:
option_data["name_localizations"] = option.name.localizations option_data["name_localizations"] = option.name.localizations
if option.description.localizations is not None: 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: if dm_permission is not None:
data["dm_permission"] = dm_permission data["dm_permission"] = dm_permission
@ -1081,8 +1089,23 @@ class RESTApp:
if default_member_permissions is not None: if default_member_permissions is not None:
data["default_member_permissions"] = default_member_permissions data["default_member_permissions"] = default_member_permissions
data["options"] = []
if options is not None: 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: if dm_permission is not None:
data["dm_permission"] = dm_permission data["dm_permission"] = dm_permission
@ -1126,6 +1149,89 @@ class RESTApp:
return None 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: class CDNBuilder:
"""Can be used to build images """Can be used to build images