hikari-arc 1.3.4__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arc/__init__.py +80 -83
- arc/abc/__init__.py +14 -14
- arc/abc/client.py +114 -147
- arc/abc/command.py +54 -11
- arc/abc/option.py +11 -8
- arc/abc/plugin.py +84 -14
- arc/client.py +45 -17
- arc/command/__init__.py +29 -25
- arc/command/message.py +11 -6
- arc/command/option/__init__.py +28 -17
- arc/command/option/custom/__init__.py +11 -1
- arc/command/option/custom/emoji.py +96 -0
- arc/command/option/float.py +1 -1
- arc/command/option/int.py +1 -1
- arc/command/option/str.py +1 -1
- arc/command/slash.py +23 -15
- arc/command/user.py +11 -6
- arc/context/__init__.py +1 -1
- arc/context/autocomplete.py +19 -5
- arc/context/base.py +72 -15
- arc/internal/__init__.py +1 -10
- arc/internal/about.py +1 -6
- arc/internal/options.py +1 -0
- arc/internal/sigparse.py +4 -0
- arc/internal/sync.py +6 -3
- arc/internal/version.py +1 -1
- arc/locale.py +3 -3
- arc/plugin.py +15 -7
- arc/utils/__init__.py +19 -19
- arc/utils/concurrency_limiter.py +7 -7
- arc/utils/hooks/__init__.py +8 -8
- arc/utils/hooks/basic.py +1 -1
- arc/utils/hooks/limiters.py +3 -3
- arc/utils/loops.py +2 -2
- arc/utils/ratelimiter.py +1 -1
- {hikari_arc-1.3.4.dist-info → hikari_arc-2.0.0.dist-info}/METADATA +32 -35
- hikari_arc-2.0.0.dist-info/RECORD +59 -0
- {hikari_arc-1.3.4.dist-info → hikari_arc-2.0.0.dist-info}/WHEEL +1 -2
- hikari_arc-1.3.4.dist-info/RECORD +0 -59
- hikari_arc-1.3.4.dist-info/top_level.txt +0 -1
- {hikari_arc-1.3.4.dist-info → hikari_arc-2.0.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
import attr
|
|
6
|
+
import hikari
|
|
7
|
+
|
|
8
|
+
from arc.abc.option import ConverterOption, OptionParams, OptionType
|
|
9
|
+
from arc.errors import OptionConverterFailureError
|
|
10
|
+
from arc.internal.types import ClientT
|
|
11
|
+
|
|
12
|
+
if t.TYPE_CHECKING:
|
|
13
|
+
import typing_extensions as te
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ("EmojiOption", "EmojiParams")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@t.final
|
|
20
|
+
class EmojiParams(OptionParams[hikari.Color]):
|
|
21
|
+
"""The parameters for an emoji option.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
description : str
|
|
26
|
+
The description of the option
|
|
27
|
+
name : str
|
|
28
|
+
The name of the option. If not provided, the name of the parameter will be used.
|
|
29
|
+
name_localizations : Mapping[hikari.Locale, str] | None
|
|
30
|
+
The name of the option in different locales
|
|
31
|
+
description_localizations : Mapping[hikari.Locale, str] | None
|
|
32
|
+
The description of the option in different locales
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
__slots__ = ()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@attr.define(slots=True, kw_only=True)
|
|
39
|
+
class EmojiOption(ConverterOption[hikari.Emoji, ClientT, EmojiParams, str]):
|
|
40
|
+
"""A slash command option that represents an emoji.
|
|
41
|
+
|
|
42
|
+
??? hint
|
|
43
|
+
To add an option of this type to your command, add an argument to your command function with the following type hint:
|
|
44
|
+
```py
|
|
45
|
+
opt_name: arc.Option[hikari.Emoji, EmojiParams(...)]
|
|
46
|
+
```
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def option_type(self) -> OptionType:
|
|
51
|
+
return OptionType.EMOJI
|
|
52
|
+
|
|
53
|
+
def _convert_value(self, value: str) -> hikari.Emoji:
|
|
54
|
+
try:
|
|
55
|
+
return hikari.Emoji.parse(value)
|
|
56
|
+
except ValueError as exc:
|
|
57
|
+
raise OptionConverterFailureError(
|
|
58
|
+
self, value, f"Option '{self.name}' expected a valid color, got {value!r}."
|
|
59
|
+
) from exc
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def _from_params(
|
|
63
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: EmojiParams, **kwargs: t.Any
|
|
64
|
+
) -> te.Self:
|
|
65
|
+
return cls(
|
|
66
|
+
name=name,
|
|
67
|
+
arg_name=arg_name,
|
|
68
|
+
description=params.description,
|
|
69
|
+
is_required=is_required,
|
|
70
|
+
name_localizations=params.name_localizations,
|
|
71
|
+
description_localizations=params.description_localizations,
|
|
72
|
+
**kwargs,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# MIT License
|
|
77
|
+
#
|
|
78
|
+
# Copyright (c) 2023-present hypergonial
|
|
79
|
+
#
|
|
80
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
81
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
82
|
+
# in the Software without restriction, including without limitation the rights
|
|
83
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
84
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
85
|
+
# furnished to do so, subject to the following conditions:
|
|
86
|
+
#
|
|
87
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
88
|
+
# copies or substantial portions of the Software.
|
|
89
|
+
#
|
|
90
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
91
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
92
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
93
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
94
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
95
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
96
|
+
# SOFTWARE.
|
arc/command/option/float.py
CHANGED
|
@@ -43,7 +43,7 @@ class FloatParams(OptionWithChoicesParams[float, ClientT]):
|
|
|
43
43
|
The callback that is invoked when the user autocompletes the option
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
|
-
__slots__: t.Sequence[str] = ("
|
|
46
|
+
__slots__: t.Sequence[str] = ("_max", "_min")
|
|
47
47
|
|
|
48
48
|
def __init__(
|
|
49
49
|
self,
|
arc/command/option/int.py
CHANGED
|
@@ -43,7 +43,7 @@ class IntParams(OptionWithChoicesParams[int, ClientT]):
|
|
|
43
43
|
The callback that is invoked when the user autocompletes the option
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
|
-
__slots__: t.Sequence[str] = ("
|
|
46
|
+
__slots__: t.Sequence[str] = ("_max", "_min")
|
|
47
47
|
|
|
48
48
|
def __init__(
|
|
49
49
|
self,
|
arc/command/option/str.py
CHANGED
|
@@ -44,7 +44,7 @@ class StrParams(OptionWithChoicesParams[str, ClientT]):
|
|
|
44
44
|
The callback that is invoked when the user autocompletes the option
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
-
__slots__: t.Sequence[str] = ("
|
|
47
|
+
__slots__: t.Sequence[str] = ("_max_length", "_min_length")
|
|
48
48
|
|
|
49
49
|
def __init__(
|
|
50
50
|
self,
|
arc/command/slash.py
CHANGED
|
@@ -25,8 +25,8 @@ if t.TYPE_CHECKING:
|
|
|
25
25
|
from arc.abc.plugin import PluginBase
|
|
26
26
|
|
|
27
27
|
__all__ = (
|
|
28
|
-
"SlashCommandLike",
|
|
29
28
|
"SlashCommand",
|
|
29
|
+
"SlashCommandLike",
|
|
30
30
|
"SlashGroup",
|
|
31
31
|
"SlashSubCommand",
|
|
32
32
|
"SlashSubGroup",
|
|
@@ -108,10 +108,11 @@ class SlashCommand(CallableCommandBase[ClientT, hikari.api.SlashCommandBuilder])
|
|
|
108
108
|
id=id,
|
|
109
109
|
options=[option.to_command_option() for option in self.options.values()],
|
|
110
110
|
default_member_permissions=self.default_permissions,
|
|
111
|
-
|
|
111
|
+
integration_types=self.integration_types,
|
|
112
|
+
context_types=self.invocation_contexts,
|
|
112
113
|
is_nsfw=self.is_nsfw,
|
|
113
|
-
name_localizations=self.name_localizations,
|
|
114
|
-
description_localizations=self.description_localizations,
|
|
114
|
+
name_localizations={str(key): value for key, value in self.name_localizations.items()},
|
|
115
|
+
description_localizations={str(key): value for key, value in self.description_localizations.items()},
|
|
115
116
|
)
|
|
116
117
|
|
|
117
118
|
async def invoke(
|
|
@@ -263,10 +264,11 @@ class SlashGroup(CommandBase[ClientT, hikari.api.SlashCommandBuilder]):
|
|
|
263
264
|
id=id,
|
|
264
265
|
options=[subcmd.to_command_option() for subcmd in self.children.values()],
|
|
265
266
|
default_member_permissions=self.default_permissions,
|
|
266
|
-
|
|
267
|
+
integration_types=self.integration_types,
|
|
268
|
+
context_types=self.invocation_contexts,
|
|
267
269
|
is_nsfw=self.is_nsfw,
|
|
268
|
-
name_localizations=self.name_localizations,
|
|
269
|
-
description_localizations=self.description_localizations,
|
|
270
|
+
name_localizations={str(key): value for key, value in self.name_localizations.items()},
|
|
271
|
+
description_localizations={str(key): value for key, value in self.description_localizations.items()},
|
|
270
272
|
)
|
|
271
273
|
|
|
272
274
|
async def _invoke_subcmd(
|
|
@@ -291,7 +293,7 @@ class SlashGroup(CommandBase[ClientT, hikari.api.SlashCommandBuilder]):
|
|
|
291
293
|
async def invoke(
|
|
292
294
|
self, interaction: hikari.CommandInteraction, *args: t.Any, **kwargs: t.Any
|
|
293
295
|
) -> Future[ResponseBuilderT] | None:
|
|
294
|
-
if interaction.options
|
|
296
|
+
if not interaction.options:
|
|
295
297
|
raise CommandInvokeError("Cannot invoke slash group with empty options.")
|
|
296
298
|
|
|
297
299
|
# Get first-order subcommand
|
|
@@ -363,7 +365,7 @@ class SlashGroup(CommandBase[ClientT, hikari.api.SlashCommandBuilder]):
|
|
|
363
365
|
opt = next(o for o in subsub.options if o.name in subsubcmd.options and o.is_focused)
|
|
364
366
|
local_opt = subsubcmd.options[opt.name]
|
|
365
367
|
|
|
366
|
-
if not isinstance(local_opt, OptionWithChoices) or not local_opt.autocomplete_with:
|
|
368
|
+
if not isinstance(local_opt, OptionWithChoices) or not local_opt.autocomplete_with: # pyright: ignore reportUnknownMemberType
|
|
367
369
|
raise AutocompleteError(
|
|
368
370
|
f"Slash option got autocomplete interaction without autocomplete callback: '{local_opt.name}'."
|
|
369
371
|
)
|
|
@@ -522,7 +524,8 @@ class SlashSubGroup(SubCommandBase[ClientT, SlashGroup[ClientT]]):
|
|
|
522
524
|
autodefer=self._autodefer,
|
|
523
525
|
default_permissions=hikari.UNDEFINED,
|
|
524
526
|
is_nsfw=hikari.UNDEFINED,
|
|
525
|
-
|
|
527
|
+
integration_types=hikari.UNDEFINED,
|
|
528
|
+
invocation_contexts=hikari.UNDEFINED,
|
|
526
529
|
)
|
|
527
530
|
)
|
|
528
531
|
|
|
@@ -675,7 +678,8 @@ class SlashSubCommand(
|
|
|
675
678
|
autodefer=self._autodefer,
|
|
676
679
|
default_permissions=hikari.UNDEFINED,
|
|
677
680
|
is_nsfw=hikari.UNDEFINED,
|
|
678
|
-
|
|
681
|
+
integration_types=hikari.UNDEFINED,
|
|
682
|
+
invocation_contexts=hikari.UNDEFINED,
|
|
679
683
|
)
|
|
680
684
|
)
|
|
681
685
|
|
|
@@ -739,7 +743,8 @@ def slash_command(
|
|
|
739
743
|
description: str = "No description provided.",
|
|
740
744
|
*,
|
|
741
745
|
guilds: t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
742
|
-
|
|
746
|
+
integration_types: t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
747
|
+
invocation_contexts: t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
743
748
|
is_nsfw: bool | hikari.UndefinedType = hikari.UNDEFINED,
|
|
744
749
|
autodefer: bool | AutodeferMode | hikari.UndefinedType = hikari.UNDEFINED,
|
|
745
750
|
default_permissions: hikari.Permissions | hikari.UndefinedType = hikari.UNDEFINED,
|
|
@@ -756,8 +761,10 @@ def slash_command(
|
|
|
756
761
|
The description of the command
|
|
757
762
|
guilds : t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType
|
|
758
763
|
The guilds this command should be enabled in, if left as undefined, the command is global
|
|
759
|
-
|
|
760
|
-
|
|
764
|
+
integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
|
|
765
|
+
The integration types this command supports the installation of
|
|
766
|
+
invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
|
|
767
|
+
The context types this command can be invoked in
|
|
761
768
|
is_nsfw : bool | hikari.UndefinedType
|
|
762
769
|
If True, the command is only usable in NSFW channels
|
|
763
770
|
autodefer : bool | AutodeferMode | hikari.UndefinedType
|
|
@@ -804,7 +811,8 @@ def slash_command(
|
|
|
804
811
|
description_localizations=description_localizations or {},
|
|
805
812
|
default_permissions=default_permissions,
|
|
806
813
|
guilds=guild_ids,
|
|
807
|
-
|
|
814
|
+
integration_types=integration_types,
|
|
815
|
+
invocation_contexts=invocation_contexts,
|
|
808
816
|
is_nsfw=is_nsfw,
|
|
809
817
|
)
|
|
810
818
|
|
arc/command/user.py
CHANGED
|
@@ -46,9 +46,10 @@ class UserCommand(CallableCommandBase[ClientT, hikari.api.ContextMenuCommandBuil
|
|
|
46
46
|
type=self.command_type,
|
|
47
47
|
id=id,
|
|
48
48
|
default_member_permissions=self.default_permissions,
|
|
49
|
-
|
|
49
|
+
context_types=self.invocation_contexts,
|
|
50
|
+
integration_types=self.integration_types,
|
|
50
51
|
is_nsfw=self.is_nsfw,
|
|
51
|
-
name_localizations=self.name_localizations,
|
|
52
|
+
name_localizations={str(key): value for key, value in self.name_localizations.items()},
|
|
52
53
|
)
|
|
53
54
|
|
|
54
55
|
async def invoke(
|
|
@@ -70,7 +71,8 @@ def user_command(
|
|
|
70
71
|
name: str,
|
|
71
72
|
*,
|
|
72
73
|
guilds: t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
73
|
-
|
|
74
|
+
invocation_contexts: t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
75
|
+
integration_types: t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
74
76
|
is_nsfw: bool | hikari.UndefinedType = hikari.UNDEFINED,
|
|
75
77
|
autodefer: bool | AutodeferMode | hikari.UndefinedType = hikari.UNDEFINED,
|
|
76
78
|
default_permissions: hikari.Permissions | hikari.UndefinedType = hikari.UNDEFINED,
|
|
@@ -87,8 +89,10 @@ def user_command(
|
|
|
87
89
|
The name of the command.
|
|
88
90
|
guilds : t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType
|
|
89
91
|
The guilds this command should be enabled in, if left as undefined, the command is global
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
|
|
93
|
+
The integration types this command supports the installation of
|
|
94
|
+
invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
|
|
95
|
+
The context types this command can be invoked in
|
|
92
96
|
is_nsfw : bool | hikari.UndefinedType
|
|
93
97
|
Whether this command is NSFW.
|
|
94
98
|
autodefer : bool | AutodeferMode | hikari.UndefinedType
|
|
@@ -117,7 +121,8 @@ def user_command(
|
|
|
117
121
|
name=name,
|
|
118
122
|
autodefer=AutodeferMode(autodefer) if isinstance(autodefer, bool) else autodefer,
|
|
119
123
|
guilds=guild_ids,
|
|
120
|
-
|
|
124
|
+
invocation_contexts=invocation_contexts,
|
|
125
|
+
integration_types=integration_types,
|
|
121
126
|
is_nsfw=is_nsfw,
|
|
122
127
|
default_permissions=default_permissions,
|
|
123
128
|
name_localizations=name_localizations or {},
|
arc/context/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from .autocomplete import AutocompleteData
|
|
2
2
|
from .base import AutodeferMode, Context, InteractionResponse
|
|
3
3
|
|
|
4
|
-
__all__ = ("
|
|
4
|
+
__all__ = ("AutocompleteData", "AutodeferMode", "Context", "InteractionResponse")
|
|
5
5
|
|
|
6
6
|
# MIT License
|
|
7
7
|
#
|
arc/context/autocomplete.py
CHANGED
|
@@ -51,7 +51,7 @@ class AutocompleteData(t.Generic[ClientT, ChoiceT]):
|
|
|
51
51
|
"""
|
|
52
52
|
if self.focused_option is None:
|
|
53
53
|
return None
|
|
54
|
-
return t.cast(ChoiceT | str, self.focused_option.value)
|
|
54
|
+
return t.cast("ChoiceT | str", self.focused_option.value)
|
|
55
55
|
|
|
56
56
|
@property
|
|
57
57
|
def guild_id(self) -> hikari.Snowflake | None:
|
|
@@ -68,19 +68,33 @@ class AutocompleteData(t.Generic[ClientT, ChoiceT]):
|
|
|
68
68
|
"""The member that triggered the interaction."""
|
|
69
69
|
return self.interaction.member
|
|
70
70
|
|
|
71
|
+
@property
|
|
72
|
+
def invocation_context(self) -> hikari.ApplicationContextType:
|
|
73
|
+
"""The context in which the interaction was invoked."""
|
|
74
|
+
return self.interaction.context
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def authorizing_integration_owners(self) -> t.Mapping[hikari.ApplicationIntegrationType, hikari.Snowflake]:
|
|
78
|
+
"""Includes details about the authorizing user or server for the installation(s) relevant to the interaction.
|
|
79
|
+
|
|
80
|
+
For apps installed to a user, it can be used to tell the difference between the authorizing user
|
|
81
|
+
and the user that triggered an interaction (like a message component).
|
|
82
|
+
"""
|
|
83
|
+
return self.interaction.authorizing_integration_owners
|
|
84
|
+
|
|
71
85
|
@property
|
|
72
86
|
def user(self) -> hikari.User:
|
|
73
87
|
"""The user that triggered the interaction."""
|
|
74
88
|
return self.interaction.user
|
|
75
89
|
|
|
90
|
+
@property
|
|
91
|
+
def channel(self) -> hikari.InteractionChannel:
|
|
92
|
+
return self.interaction.channel
|
|
93
|
+
|
|
76
94
|
def get_guild(self) -> hikari.Guild | None:
|
|
77
95
|
"""Get the guild that triggered the interaction."""
|
|
78
96
|
return self.interaction.get_guild()
|
|
79
97
|
|
|
80
|
-
def get_channel(self) -> hikari.TextableGuildChannel | None:
|
|
81
|
-
"""Get the channel that triggered the interaction."""
|
|
82
|
-
return self.interaction.get_channel()
|
|
83
|
-
|
|
84
98
|
|
|
85
99
|
# MIT License
|
|
86
100
|
#
|
arc/context/base.py
CHANGED
|
@@ -11,7 +11,7 @@ import alluka
|
|
|
11
11
|
import attr
|
|
12
12
|
import hikari
|
|
13
13
|
|
|
14
|
-
from arc.abc.option import OptionType # noqa:
|
|
14
|
+
from arc.abc.option import OptionType # noqa: TC001 Needed for tests
|
|
15
15
|
from arc.errors import NoResponseIssuedError, ResponseAlreadyIssuedError
|
|
16
16
|
from arc.internal.options import OPTIONTYPE_TO_TYPE, resolve_snowflake_value
|
|
17
17
|
from arc.internal.types import ClientT, ResponseBuilderT
|
|
@@ -20,7 +20,7 @@ from arc.locale import CustomLocaleRequest
|
|
|
20
20
|
if t.TYPE_CHECKING:
|
|
21
21
|
from arc.abc.command import CallableCommandProto
|
|
22
22
|
|
|
23
|
-
__all__ = ("
|
|
23
|
+
__all__ = ("AutodeferMode", "Context", "InteractionResponse")
|
|
24
24
|
|
|
25
25
|
logger = logging.getLogger(__name__)
|
|
26
26
|
|
|
@@ -105,10 +105,10 @@ class InteractionResponse:
|
|
|
105
105
|
when a message response is issued.
|
|
106
106
|
"""
|
|
107
107
|
|
|
108
|
-
__slots__ = ("_context", "
|
|
108
|
+
__slots__ = ("_context", "_delete_after_task", "_message")
|
|
109
109
|
|
|
110
|
-
def __init__(self, context: Context[
|
|
111
|
-
self._context: Context[
|
|
110
|
+
def __init__(self, context: Context[t.Any], message: hikari.Message | None = None) -> None:
|
|
111
|
+
self._context: Context[t.Any] = context
|
|
112
112
|
self._message: hikari.Message | None = message
|
|
113
113
|
self._delete_after_task: asyncio.Task[None] | None = None
|
|
114
114
|
|
|
@@ -247,18 +247,18 @@ class Context(t.Generic[ClientT]):
|
|
|
247
247
|
"""A context object that is proxying a Discord command interaction."""
|
|
248
248
|
|
|
249
249
|
__slots__ = (
|
|
250
|
+
"_autodefer_task",
|
|
250
251
|
"_client",
|
|
251
252
|
"_command",
|
|
252
|
-
"_interaction",
|
|
253
|
-
"_responses",
|
|
254
|
-
"_resp_builder",
|
|
255
|
-
"_issued_response",
|
|
256
|
-
"_response_lock",
|
|
257
|
-
"_autodefer_task",
|
|
258
253
|
"_created_at",
|
|
259
254
|
"_has_command_failed",
|
|
260
|
-
"_options",
|
|
261
255
|
"_injection_ctx",
|
|
256
|
+
"_interaction",
|
|
257
|
+
"_issued_response",
|
|
258
|
+
"_options",
|
|
259
|
+
"_resp_builder",
|
|
260
|
+
"_response_lock",
|
|
261
|
+
"_responses",
|
|
262
262
|
)
|
|
263
263
|
|
|
264
264
|
def __init__(
|
|
@@ -341,11 +341,69 @@ class Context(t.Generic[ClientT]):
|
|
|
341
341
|
"""The ID of the channel the context represents."""
|
|
342
342
|
return self._interaction.channel_id
|
|
343
343
|
|
|
344
|
+
@property
|
|
345
|
+
def channel(self) -> hikari.InteractionChannel:
|
|
346
|
+
"""The channel the context represents."""
|
|
347
|
+
return self._interaction.channel
|
|
348
|
+
|
|
344
349
|
@property
|
|
345
350
|
def guild_id(self) -> hikari.Snowflake | None:
|
|
346
351
|
"""The ID of the guild the context represents. Will be None in DMs."""
|
|
347
352
|
return self._interaction.guild_id
|
|
348
353
|
|
|
354
|
+
@property
|
|
355
|
+
def invocation_context(self) -> hikari.ApplicationContextType:
|
|
356
|
+
"""The context in which the interaction was invoked.
|
|
357
|
+
|
|
358
|
+
This can be used to determine if the command was invoked in DMs, a guild, or a group DM.
|
|
359
|
+
"""
|
|
360
|
+
return self._interaction.context
|
|
361
|
+
|
|
362
|
+
@property
|
|
363
|
+
def authorizing_integration_owners(self) -> t.Mapping[hikari.ApplicationIntegrationType, hikari.Snowflake]:
|
|
364
|
+
"""Includes details about the authorizing user or guild for the installation(s) relevant to the interaction.
|
|
365
|
+
|
|
366
|
+
For apps installed to a user, it can be used to tell the difference between the authorizing user
|
|
367
|
+
and the user that triggered an interaction.
|
|
368
|
+
"""
|
|
369
|
+
return self._interaction.authorizing_integration_owners
|
|
370
|
+
|
|
371
|
+
@property
|
|
372
|
+
def authorizing_guild_id(self) -> hikari.Snowflake | None:
|
|
373
|
+
"""The ID of the guild that this command was installed in.
|
|
374
|
+
|
|
375
|
+
This will be `None` if the command was not installed in the guild.
|
|
376
|
+
|
|
377
|
+
This is a shorthand for
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
authorizing_integration_owners.get(hikari.ApplicationIntegrationType.GUILD_INSTALL)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
!!! note
|
|
384
|
+
It is possible for both this value and `authorizing_user_id` to not be `None`, if the command is installed
|
|
385
|
+
in both a guild and by a user.
|
|
386
|
+
"""
|
|
387
|
+
return self._interaction.authorizing_integration_owners.get(hikari.ApplicationIntegrationType.GUILD_INSTALL)
|
|
388
|
+
|
|
389
|
+
@property
|
|
390
|
+
def authorizing_user_id(self) -> hikari.Snowflake | None:
|
|
391
|
+
"""The ID of the user that installed this command.
|
|
392
|
+
|
|
393
|
+
This will be `None` if the command was not installed by a user.
|
|
394
|
+
|
|
395
|
+
This is a shorthand for
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
authorizing_integration_owners.get(hikari.ApplicationIntegrationType.USER_INSTALL)
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
!!! note
|
|
402
|
+
It is possible for both this value and `authorizing_guild_id` to not be `None`, if the command is installed
|
|
403
|
+
in both a guild and by a user.
|
|
404
|
+
"""
|
|
405
|
+
return self._interaction.authorizing_integration_owners.get(hikari.ApplicationIntegrationType.USER_INSTALL)
|
|
406
|
+
|
|
349
407
|
@property
|
|
350
408
|
def is_valid(self) -> bool:
|
|
351
409
|
"""Returns if the underlying interaction expired or not.
|
|
@@ -414,9 +472,8 @@ class Context(t.Generic[ClientT]):
|
|
|
414
472
|
"""Gets the guild this context represents, if any. Requires application cache."""
|
|
415
473
|
return self._interaction.get_guild()
|
|
416
474
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
return self._interaction.get_channel()
|
|
475
|
+
@t.overload
|
|
476
|
+
def get_option(self, name: str, opt_type: t.Literal[OptionType.EMOJI]) -> hikari.Emoji | None: ...
|
|
420
477
|
|
|
421
478
|
@t.overload
|
|
422
479
|
def get_option(self, name: str, opt_type: t.Literal[OptionType.COLOR]) -> hikari.Color | None: ...
|
arc/internal/__init__.py
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
from .about import __author__, __author_email__, __maintainer__, __version__
|
|
2
1
|
from .deprecation import warn_deprecate
|
|
3
2
|
from .version import CURRENT_VERSION, Version
|
|
4
3
|
|
|
5
|
-
__all__ = (
|
|
6
|
-
"warn_deprecate",
|
|
7
|
-
"Version",
|
|
8
|
-
"CURRENT_VERSION",
|
|
9
|
-
"__author__",
|
|
10
|
-
"__author_email__",
|
|
11
|
-
"__maintainer__",
|
|
12
|
-
"__version__",
|
|
13
|
-
)
|
|
4
|
+
__all__ = ("CURRENT_VERSION", "Version", "warn_deprecate")
|
|
14
5
|
|
|
15
6
|
# MIT License
|
|
16
7
|
#
|
arc/internal/about.py
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import typing as t
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
__author_email__: t.Final[str] = "git@hypergonial.com"
|
|
5
|
-
__maintainer__: t.Final[str] = "hypergonial"
|
|
6
|
-
__license__: t.Final[str] = "MIT"
|
|
7
|
-
__url__: t.Final[str] = "https://github.com/hypergonial/hikari-arc"
|
|
8
|
-
__version__: t.Final[str] = "1.3.4"
|
|
3
|
+
__version__: t.Final[str] = "2.0.0"
|
|
9
4
|
|
|
10
5
|
# MIT License
|
|
11
6
|
#
|
arc/internal/options.py
CHANGED
|
@@ -23,6 +23,7 @@ OPTIONTYPE_TO_TYPE: dict[OptionType, type[t.Any]] = {
|
|
|
23
23
|
OptionType.ATTACHMENT: hikari.Attachment,
|
|
24
24
|
OptionType.COLOR: hikari.Color,
|
|
25
25
|
OptionType.MEMBER: hikari.Member,
|
|
26
|
+
OptionType.EMOJI: hikari.Emoji,
|
|
26
27
|
}
|
|
27
28
|
"""Used for runtime type checking in Context.get_option, not much else at the moment."""
|
|
28
29
|
|
arc/internal/sigparse.py
CHANGED
|
@@ -17,6 +17,8 @@ from arc.command.option import (
|
|
|
17
17
|
ChannelParams,
|
|
18
18
|
ColorOption,
|
|
19
19
|
ColorParams,
|
|
20
|
+
EmojiOption,
|
|
21
|
+
EmojiParams,
|
|
20
22
|
FloatOption,
|
|
21
23
|
FloatParams,
|
|
22
24
|
IntOption,
|
|
@@ -53,6 +55,7 @@ TYPE_TO_OPTION_MAPPING: dict[type[t.Any], type[CommandOptionBase[t.Any, t.Any, t
|
|
|
53
55
|
hikari.Member: MemberOption,
|
|
54
56
|
hikari.InteractionMember: MemberOption,
|
|
55
57
|
hikari.Color: ColorOption,
|
|
58
|
+
hikari.Emoji: EmojiOption,
|
|
56
59
|
hikari.User: UserOption,
|
|
57
60
|
}
|
|
58
61
|
|
|
@@ -68,6 +71,7 @@ OPT_TO_PARAMS_MAPPING: dict[type[CommandOptionBase[t.Any, t.Any, t.Any]], type[t
|
|
|
68
71
|
AttachmentOption: AttachmentParams,
|
|
69
72
|
MemberOption: MemberParams,
|
|
70
73
|
ColorOption: ColorParams,
|
|
74
|
+
EmojiOption: EmojiParams,
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
BASE_CHANNEL_TYPE_MAP: dict[type[hikari.PartialChannel], hikari.ChannelType] = {
|
arc/internal/sync.py
CHANGED
|
@@ -50,8 +50,9 @@ def _rebuild_hikari_command(
|
|
|
50
50
|
description=command.description,
|
|
51
51
|
options=list(command.options) if command.options else [],
|
|
52
52
|
default_member_permissions=command.default_member_permissions,
|
|
53
|
-
is_dm_enabled=command.is_dm_enabled,
|
|
54
53
|
is_nsfw=command.is_nsfw,
|
|
54
|
+
integration_types=command.integration_types,
|
|
55
|
+
context_types=command.context_types,
|
|
55
56
|
name_localizations=command.name_localizations,
|
|
56
57
|
description_localizations=command.description_localizations,
|
|
57
58
|
)
|
|
@@ -61,8 +62,9 @@ def _rebuild_hikari_command(
|
|
|
61
62
|
id=command.id,
|
|
62
63
|
type=command.type,
|
|
63
64
|
default_member_permissions=command.default_member_permissions,
|
|
64
|
-
is_dm_enabled=command.is_dm_enabled,
|
|
65
65
|
is_nsfw=command.is_nsfw,
|
|
66
|
+
integration_types=command.integration_types,
|
|
67
|
+
context_types=command.context_types,
|
|
66
68
|
name_localizations=command.name_localizations,
|
|
67
69
|
)
|
|
68
70
|
else:
|
|
@@ -93,7 +95,8 @@ def _compare_commands(arc_command: CommandBase[t.Any, t.Any], hk_command: hikari
|
|
|
93
95
|
and arc_command.name == hk_command.name
|
|
94
96
|
and cmd_dict.get("description") == getattr(hk_command, "description", None)
|
|
95
97
|
and arc_command.is_nsfw == hk_command.is_nsfw
|
|
96
|
-
and arc_command.
|
|
98
|
+
and set(arc_command.invocation_contexts) == set(hk_command.context_types)
|
|
99
|
+
and set(arc_command.integration_types) == set(hk_command.integration_types)
|
|
97
100
|
and (
|
|
98
101
|
hk_command.guild_id in arc_command.guilds
|
|
99
102
|
if hk_command.guild_id is not None and arc_command.guilds is not hikari.UNDEFINED
|
arc/internal/version.py
CHANGED
arc/locale.py
CHANGED
|
@@ -14,12 +14,12 @@ if t.TYPE_CHECKING:
|
|
|
14
14
|
from arc.context.base import Context
|
|
15
15
|
|
|
16
16
|
__all__ = (
|
|
17
|
-
"
|
|
17
|
+
"CommandLocaleRequest",
|
|
18
|
+
"CustomLocaleRequest",
|
|
18
19
|
"LocaleRequest",
|
|
20
|
+
"LocaleRequestType",
|
|
19
21
|
"LocaleResponse",
|
|
20
|
-
"CommandLocaleRequest",
|
|
21
22
|
"OptionLocaleRequest",
|
|
22
|
-
"CustomLocaleRequest",
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
|
arc/plugin.py
CHANGED
|
@@ -11,7 +11,7 @@ from arc.internal.types import EventCallbackT, EventT, GatewayClientT, RESTClien
|
|
|
11
11
|
if t.TYPE_CHECKING:
|
|
12
12
|
from arc.context.base import AutodeferMode
|
|
13
13
|
|
|
14
|
-
__all__ = ("
|
|
14
|
+
__all__ = ("GatewayPluginBase", "RESTPluginBase")
|
|
15
15
|
|
|
16
16
|
P = t.ParamSpec("P")
|
|
17
17
|
T = t.TypeVar("T")
|
|
@@ -33,8 +33,11 @@ class RESTPluginBase(PluginBase[RESTClientT]):
|
|
|
33
33
|
autodefer : bool | AutodeferMode
|
|
34
34
|
If True, all commands in this plugin will automatically defer if it is taking longer than 2 seconds to respond.
|
|
35
35
|
This can be overridden on a per-command basis.
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
|
|
37
|
+
The integration types that commands will support the installation of
|
|
38
|
+
This can be overridden on a per-command basis.
|
|
39
|
+
invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
|
|
40
|
+
The context types that commands can be invoked in
|
|
38
41
|
This can be overridden on a per-command basis.
|
|
39
42
|
default_permissions : hikari.Permissions | hikari.UndefinedType
|
|
40
43
|
The default permissions for this plugin
|
|
@@ -81,8 +84,11 @@ class GatewayPluginBase(PluginBase[GatewayClientT]):
|
|
|
81
84
|
autodefer : bool | AutodeferMode
|
|
82
85
|
If True, all commands in this plugin will automatically defer if it is taking longer than 2 seconds to respond.
|
|
83
86
|
This can be overridden on a per-command basis.
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
|
|
88
|
+
The integration types that commands will support the installation of
|
|
89
|
+
This can be overridden on a per-command basis.
|
|
90
|
+
invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
|
|
91
|
+
The context types that commands can be invoked in
|
|
86
92
|
This can be overridden on a per-command basis.
|
|
87
93
|
default_permissions : hikari.Permissions | hikari.UndefinedType
|
|
88
94
|
The default permissions for this plugin
|
|
@@ -115,7 +121,8 @@ class GatewayPluginBase(PluginBase[GatewayClientT]):
|
|
|
115
121
|
default_enabled_guilds: t.Sequence[hikari.Snowflakeish | hikari.PartialGuild]
|
|
116
122
|
| hikari.UndefinedType = hikari.UNDEFINED,
|
|
117
123
|
autodefer: bool | AutodeferMode | hikari.UndefinedType = hikari.UNDEFINED,
|
|
118
|
-
|
|
124
|
+
integration_types: t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
125
|
+
invocation_contexts: t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType = hikari.UNDEFINED,
|
|
119
126
|
default_permissions: hikari.Permissions | hikari.UndefinedType = hikari.UNDEFINED,
|
|
120
127
|
is_nsfw: bool | hikari.UndefinedType = hikari.UNDEFINED,
|
|
121
128
|
) -> None:
|
|
@@ -123,7 +130,8 @@ class GatewayPluginBase(PluginBase[GatewayClientT]):
|
|
|
123
130
|
name=name,
|
|
124
131
|
default_enabled_guilds=default_enabled_guilds,
|
|
125
132
|
autodefer=autodefer,
|
|
126
|
-
|
|
133
|
+
integration_types=integration_types,
|
|
134
|
+
invocation_contexts=invocation_contexts,
|
|
127
135
|
default_permissions=default_permissions,
|
|
128
136
|
is_nsfw=is_nsfw,
|
|
129
137
|
)
|