Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ebd3d50
fix: outdated use of bridge methods
Middledot Aug 24, 2022
b719e96
feat: allow BridgeCommand classes to be invokable
Middledot Aug 24, 2022
8ea3dae
feat: globally usable wrap for guild_only
Middledot Aug 24, 2022
a7e2420
Revert "fix: outdated use of bridge methods"
Middledot Sep 16, 2022
ff542e8
feat: actual invoke
Middledot Sep 16, 2022
1ccb346
Merge branch 'Pycord-Development:master' into ext-bridge-dev
Middledot Sep 16, 2022
433101d
fix: it's raining the same validation errors
Middledot Sep 17, 2022
deb6ec0
refactor: cleanup
Middledot Sep 17, 2022
77eb294
fix: only run on slash groups
Middledot Sep 21, 2022
e230f7f
feat: implement bridge.has_permissions
Middledot Sep 21, 2022
ebe95d2
refactor: shortcuts
Middledot Sep 21, 2022
d665aab
chore: docs
Middledot Sep 21, 2022
8f54782
fix: invoke bug
Middledot Sep 21, 2022
cb674d9
refactor: remove comment
Middledot Sep 21, 2022
ba8c89a
Update discord/ext/bridge/core.py
Lulalaby Sep 26, 2022
9a806d9
Merge branch 'master' into ext-bridge-dev
BobDotCom Sep 30, 2022
963674d
feat: add more extensive usage
Middledot Oct 1, 2022
a58d8b0
Merge branch 'master' into ext-bridge-dev
Middledot Oct 1, 2022
a01444a
fix: var assignment error
Middledot Oct 1, 2022
79e4412
Merge branch 'ext-bridge-dev' of https://github.com/Middledot/pycord …
Middledot Oct 1, 2022
5642146
Merge branch 'master' into ext-bridge-dev
Lulalaby Oct 1, 2022
9f7683b
Merge branch 'master' into ext-bridge-dev
BobDotCom Oct 2, 2022
b287741
Update CHANGELOG.md
BobDotCom Oct 2, 2022
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#1655](https://github.com/Pycord-Development/pycord/pull/1655))
- `delete_message_seconds` parameter in ban methods. ([#1557](https://github.com/Pycord-Development/pycord/pull/1557))
- New `View.get_item()` method. ([#1659](https://github.com/Pycord-Development/pycord/pull/1659))
- Permissions support for bridge commands. ([#1642](https://github.com/Pycord-Development/pycord/pull/1642))
- New `BridgeCommand.invoke()` method. ([#1642](https://github.com/Pycord-Development/pycord/pull/1642))

### Deprecated
- The `delete_message_days` parameter in ban methods is now deprecated. Please use `delete_message_seconds` instead.
Expand Down
18 changes: 14 additions & 4 deletions discord/cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ def __new__(cls: Type[CogMeta], *args: Any, **kwargs: Any) -> CogMeta:
raise TypeError(no_bot_cog.format(base, elem))

commands[f"ext_{elem}"] = value.ext_variant
commands[f"application_{elem}"] = value.slash_variant
commands[f"app_{elem}"] = value.slash_variant
for cmd in getattr(value, "subcommands", []):
commands[f"ext_{cmd.ext_variant.qualified_name}"] = cmd.ext_variant

if inspect.iscoroutinefunction(value):
try:
Expand Down Expand Up @@ -229,19 +231,27 @@ def __new__(cls: Type[CogMeta], *args: Any, **kwargs: Any) -> CogMeta:
# r.e type ignore, type-checker complains about overriding a ClassVar
new_cls.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in new_cls.__cog_commands__) # type: ignore

lookup = {cmd.qualified_name: cmd for cmd in new_cls.__cog_commands__}
name_filter = lambda c: 'app' if isinstance(c, ApplicationCommand) else 'ext'

lookup = {f"{name_filter(cmd)}_{cmd.qualified_name}": cmd for cmd in new_cls.__cog_commands__}

# Update the Command instances dynamically as well
for command in new_cls.__cog_commands__:
if isinstance(command, ApplicationCommand) and not command.guild_ids and new_cls.__cog_guild_ids__:
command.guild_ids = new_cls.__cog_guild_ids__

if not isinstance(command, SlashCommandGroup):
setattr(new_cls, command.callback.__name__, command)
# ignore bridge commands
cmd = getattr(new_cls, command.callback.__name__, None)
if hasattr(cmd, "add_to"):
setattr(cmd, f"{name_filter(command).replace('app', 'slash')}_variant", command)
else:
setattr(new_cls, command.callback.__name__, command)

parent = command.parent
if parent is not None:
# Get the latest parent reference
parent = lookup[parent.qualified_name] # type: ignore
parent = lookup[f"{name_filter(command)}_{parent.qualified_name}"] # type: ignore

# Update our parent's reference to our self
parent.remove_command(command.name) # type: ignore
Expand Down
1 change: 1 addition & 0 deletions discord/commands/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def inner(command: Callable):
command.guild_only = True
else:
command.__guild_only__ = True

return command

return inner
12 changes: 11 additions & 1 deletion discord/ext/bridge/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any, Optional, Union
from typing import TYPE_CHECKING, Any, overload, Optional, Union

from discord.commands import ApplicationContext
from discord.interactions import Interaction, InteractionMessage
Expand All @@ -32,6 +34,10 @@

from ..commands import Context

if TYPE_CHECKING:
from .core import BridgeSlashCommand, BridgeExtCommand


__all__ = ("BridgeContext", "BridgeExtContext", "BridgeApplicationContext")


Expand Down Expand Up @@ -73,6 +79,10 @@ async def _defer(self, *args, **kwargs) -> None:
async def _edit(self, *args, **kwargs) -> Union[InteractionMessage, Message]:
...

@overload
async def invoke(self, command: Union[BridgeSlashCommand, BridgeExtCommand], *args, **kwargs) -> None:
...

async def respond(
self, *args, **kwargs
) -> Union[Union[Interaction, WebhookMessage], Message]:
Expand Down
75 changes: 71 additions & 4 deletions discord/ext/bridge/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,21 @@
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from __future__ import annotations

import inspect
from typing import Any, List, Union, Optional
from typing import TYPE_CHECKING, Any, List, Union, Optional, Callable, Dict

import discord.commands.options
from discord import SlashCommandOptionType, Attachment, Option, SlashCommand, SlashCommandGroup
from .context import BridgeApplicationContext
from discord import (
ApplicationCommand,
SlashCommand,
SlashCommandGroup,
Permissions,
SlashCommandOptionType,
Attachment,
Option,
)
from ..commands.converter import _convert_to_bool, run_converters
from ..commands import (
Command,
Expand All @@ -43,6 +51,9 @@
)
from ...utils import get, filter_params, find

if TYPE_CHECKING:
from .context import BridgeApplicationContext, BridgeExtContext


__all__ = (
"BridgeCommand",
Expand All @@ -54,6 +65,8 @@
"BridgeExtGroup",
"BridgeSlashGroup",
"map_to",
"guild_only",
"has_permissions",
)


Expand Down Expand Up @@ -183,6 +196,11 @@ def add_to(self, bot: ExtBot) -> None:
bot.add_application_command(self.slash_variant)
bot.add_command(self.ext_variant)

async def invoke(self, ctx: Union[BridgeExtContext, BridgeApplicationContext], /, *args, **kwargs):
if ctx.is_app:
return await self.slash_variant.invoke(ctx)
return await self.ext_variant.invoke(ctx)

def error(self, coro):
"""A decorator that registers a coroutine as a local error handler.

Expand Down Expand Up @@ -329,7 +347,7 @@ def bridge_group(**kwargs):
Parameters
----------
kwargs: Optional[Dict[:class:`str`, Any]]
Keyword arguments that are directly passed to the respective command constructors. (:class:`.SlashCommandGroup` and :class:`.ext.commands.Group`)
Keyword arguments that are directly passed to the respective command constructors (:class:`.SlashCommandGroup` and :class:`.ext.commands.Group`).
"""
def decorator(callback):
return BridgeCommandGroup(callback, **kwargs)
Expand Down Expand Up @@ -376,6 +394,54 @@ def decorator(callback):
return decorator


def guild_only():
"""Intended to work with :class:`.ApplicationCommand` and :class:`BridgeCommand`, adds a :func:`~ext.commands.check`
that locks the command to only run in guilds, and also registers the command as guild only client-side (on discord).

Basically a utility function that wraps both :func:`discord.ext.commands.guild_only` and :func:`discord.commands.guild_only`.
"""
def predicate(func: Union[Callable, ApplicationCommand]):
if isinstance(func, ApplicationCommand):
func.guild_only = True
else:
func.__guild_only__ = True

from ..commands import guild_only

return guild_only()(func)

return predicate


def has_permissions(**perms: Dict[str, bool]):
"""Intended to work with :class:`.SlashCommand` and :class:`BridgeCommand`, adds a
:func:`~ext.commands.check` that locks the command to be run by people with certain
permissions inside guilds, and also registers the command as locked behind said permissions.

Basically a utility function that wraps both :func:`discord.ext.commands.has_permissions`
and :func:`discord.commands.default_permissions`.

Parameters
----------
\*\*perms: Dict[:class:`str`, :class:`bool`]
An argument list of permissions to check for.
"""

def predicate(func: Union[Callable, ApplicationCommand]):
from ..commands import has_permissions

func = has_permissions(**perms)(func)
_perms = Permissions(**perms)
if isinstance(func, ApplicationCommand):
func.default_member_permissions = perms
else:
func.__default_member_permissions__ = perms

return perms

return predicate


class MentionableConverter(Converter):
"""A converter that can convert a mention to a user or a role."""

Expand All @@ -385,6 +451,7 @@ async def convert(self, ctx, argument):
except BadArgument:
return await UserConverter().convert(ctx, argument)


class AttachmentConverter(Converter):
async def convert(self, ctx: Context, arg: str):
try:
Expand Down
2 changes: 1 addition & 1 deletion discord/ext/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2096,7 +2096,7 @@ def has_permissions(**perms: bool) -> Callable[[T], T]:

Parameters
------------
perms
\*\*perms: Dict[:class:`str`, :class:`bool`]
An argument list of permissions to check for.

Example
Expand Down
14 changes: 11 additions & 3 deletions docs/ext/bridge/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ BridgeCommand
.. autoclass:: discord.ext.bridge.BridgeCommand
:members:

.. automethod:: discord.ext.bridge.bridge_command()
:decorator:

BridgeCommandGroup
~~~~~~~~~~~~~~~~~~~

Expand All @@ -62,12 +59,23 @@ BridgeCommandGroup
.. autoclass:: discord.ext.bridge.BridgeCommandGroup
:members:

Decorators
~~~~~~~~~~~
.. automethod:: discord.ext.bridge.bridge_command()
:decorator:

.. automethod:: discord.ext.bridge.bridge_group()
:decorator:

.. automethod:: discord.ext.bridge.map_to()
:decorator:

.. automethod:: discord.ext.bridge.guild_only()
:decorator:

.. automethod:: discord.ext.bridge.has_permissions()
:decorator:

Command Subclasses
~~~~~~~~~~~~~~~~~~~

Expand Down