Skip to content
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
2ede85f
refactor: optimize sync behavior
EepyElvyra Apr 26, 2022
14fb6d7
ooops
EepyElvyra Apr 26, 2022
0256ebd
Update interactions/api/http/interaction.py
EepyElvyra Apr 27, 2022
c447bea
Update interactions/client/bot.pyi
EepyElvyra Apr 27, 2022
dba98de
Update interactions/api/http/scheduledEvent.py
EepyElvyra Apr 27, 2022
7e72baa
Update interactions/client/bot.py
EepyElvyra Apr 27, 2022
11acf4b
Update bot.py
EepyElvyra Apr 27, 2022
7426776
ci: correct from checks.
pre-commit-ci[bot] Apr 27, 2022
a749a83
fix: Fix command check for user and member decorator
EepyElvyra Apr 28, 2022
a328711
Merge remote-tracking branch 'origin/rework_cmd_sync' into rework_cmd…
EepyElvyra Apr 28, 2022
998c0b3
Update interactions/client/bot.py
EepyElvyra Apr 29, 2022
518aad7
fix!: Fix autocomplete when sync is disabled
EepyElvyra Apr 30, 2022
622f3e2
Merge remote-tracking branch 'origin/rework_cmd_sync' into rework_cmd…
EepyElvyra Apr 30, 2022
951208d
Update bot.py
EepyElvyra May 1, 2022
3bd3820
Update bot.py
EepyElvyra May 1, 2022
8e8d59d
Update bot.pyi
EepyElvyra May 1, 2022
71e1aad
ci: correct from checks.
pre-commit-ci[bot] May 1, 2022
2548d63
Update bot.py
EepyElvyra May 1, 2022
a7dcf86
fix: fix option checks and autocomplete dispatch with command names
EepyElvyra May 2, 2022
f79c93a
ci
EepyElvyra May 2, 2022
f08a3d9
refactor: unnecessary if checks
EepyElvyra May 2, 2022
39cbf95
fix!: Fix synchronisation by properly checking attributes and their l…
FayeDel May 2, 2022
8f7b21a
refactor: Remove print statements.
FayeDel May 2, 2022
04ed0a7
refactor: move sync and autocomplete into _ready
EepyElvyra May 2, 2022
c91d8da
doc: add warning
EepyElvyra May 2, 2022
baaeb0d
Update interactions/client/bot.py
EepyElvyra May 3, 2022
95e5f6b
Merge branch 'unstable' into rework_cmd_sync
EepyElvyra May 5, 2022
c8076da
refactor!: Consider extensions in the sync process
EepyElvyra May 5, 2022
75e6db9
Merge branch 'unstable' into rework_cmd_sync
EepyElvyra May 5, 2022
3b57ee8
ci: correct from checks.
pre-commit-ci[bot] May 5, 2022
9694436
i hate merge conflicts
EepyElvyra May 5, 2022
97a926f
purge: remove debugging changes
EepyElvyra May 5, 2022
8697ce9
Update interactions/client/bot.py
EepyElvyra May 6, 2022
cc53d66
Update interactions/client/bot.py
EepyElvyra May 6, 2022
2405d79
fix: consider loading after bot start
EepyElvyra May 6, 2022
08f733e
ci: correct from checks.
pre-commit-ci[bot] May 6, 2022
00f3284
refactor: make compare sync static
EepyElvyra May 6, 2022
cfd2b4e
Merge remote-tracking branch 'origin/rework_cmd_sync' into rework_cmd…
EepyElvyra May 6, 2022
fbf5c72
ci: correct from checks.
pre-commit-ci[bot] May 6, 2022
08623f5
fix: consider sync toggle on load
EepyElvyra May 6, 2022
ca551f8
fix: Fix attribute reference typo.
FayeDel May 6, 2022
253dbe4
fix!: Attempt to fix critical error on startup with JSONException
EepyElvyra May 8, 2022
7ecb6f0
add check
EepyElvyra May 8, 2022
ea7d7bf
fix
EepyElvyra May 8, 2022
b379d46
refactor: change raise to warning if sync is off
EepyElvyra May 8, 2022
8f39278
ci: correct from checks.
pre-commit-ci[bot] May 8, 2022
a3b9c47
fix!: continue
EepyElvyra May 8, 2022
7630a81
fix!: fix snyc bug if the bot does not have the `application.commands…
EepyElvyra May 9, 2022
22ae9b4
fix: fix permission overwrite serialization and allow modifying chann…
EepyElvyra May 9, 2022
ba3d111
ci
EepyElvyra May 9, 2022
0dac1cc
Merge branch 'unstable' into rework_cmd_sync
EepyElvyra May 9, 2022
2fa7f6c
fix: Add missing `_`
EepyElvyra May 9, 2022
77ed70d
Merge remote-tracking branch 'origin/rework_cmd_sync' into rework_cmd…
EepyElvyra May 9, 2022
ca1e724
refactor: change critical to exception to provide a better DX
EepyElvyra May 9, 2022
b1fcebb
remove f-string
EepyElvyra May 9, 2022
05c6e57
fix
EepyElvyra May 10, 2022
1bb6bb1
Update interactions/api/models/channel.py
EepyElvyra May 11, 2022
b584b26
Update interactions/api/models/guild.py
EepyElvyra May 11, 2022
848e7f7
Update interactions/client/bot.py
EepyElvyra May 11, 2022
6a1cc28
Update interactions/client/bot.py
EepyElvyra May 11, 2022
d214655
Update interactions/client/bot.py
EepyElvyra May 11, 2022
c9ff68e
Update interactions/client/bot.py
EepyElvyra May 11, 2022
80e723e
ci: correct from checks.
pre-commit-ci[bot] May 11, 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
13 changes: 10 additions & 3 deletions interactions/api/models/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ def __init__(self, **kwargs):
else None
)
self.permission_overwrites = (
[Overwrite(**overwrite) for overwrite in self._json.get("permission_overwrites")]
[
Overwrite(**overwrite) if isinstance(overwrite, dict) else overwrite
for overwrite in self._json.get("permission_overwrites")
]
if self._json.get("permission_overwrites")
else None
)
Expand Down Expand Up @@ -349,10 +352,14 @@ async def modify(
self.rate_limit_per_user if rate_limit_per_user is MISSING else rate_limit_per_user
)
_position = self.position if position is MISSING else position
_parent_id = int(self.parent_id) if parent_id is MISSING else int(parent_id)
_parent_id = (
(int(self.parent_id) if self.parent_id else None)
if parent_id is MISSING
else int(parent_id)
)
_nsfw = self.nsfw if nsfw is MISSING else nsfw
_permission_overwrites = (
self.permission_overwrites
[_._json for _ in self.permission_overwrites]
if permission_overwrites is MISSING
else [overwrite._json for overwrite in permission_overwrites]
)
Expand Down
6 changes: 4 additions & 2 deletions interactions/api/models/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -834,10 +834,12 @@ async def modify_channel(
ch.rate_limit_per_user if rate_limit_per_user is MISSING else rate_limit_per_user
)
_position = ch.position if position is MISSING else position
_parent_id = ch.parent_id if parent_id is MISSING else parent_id
_parent_id = (
(int(ch.parent_id) if ch.parent_id else None) if parent_id is MISSING else parent_id
)
_nsfw = ch.nsfw if nsfw is MISSING else nsfw
_permission_overwrites = (
ch.permission_overwrites
[_._json for _ in ch.permission_overwrites]
if permission_overwrites is MISSING
else [overwrite._json for overwrite in permission_overwrites]
)
Expand Down
196 changes: 114 additions & 82 deletions interactions/client/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ async def __compare_sync(
"""

# sourcery skip: none-compare

attrs: List[str] = [
name
for name in ApplicationCommand.__slots__
Expand All @@ -170,6 +171,78 @@ async def __compare_sync(

_command: dict = {}

def __check_options(command, data):
# sourcery skip: none-compare
# sourcery no-metrics
_command_option_names = [_["name"] for _ in command.get("options")]
_data_option_names = [_["name"] for _ in data.get("options")]

if any(_ not in _command_option_names for _ in _data_option_names) or len(
_data_option_names
) != len(_command_option_names):
return False, command

for option in command.get("options"):
for _option in data.get("options"):
if _option["name"] == option["name"]:
for option_attr in option_attrs:
if (
option.get(option_attr)
and not _option.get(option_attr)
or not option.get(option_attr)
and _option.get(option_attr)
):
return False, command
elif option_attr == "choices":
if not option.get("choices") or not _option.get("choices"):
continue

_option_choice_names = [_["name"] for _ in option.get("choices")]
_data_choice_names = [_["name"] for _ in _option.get("choices")]

if any(
_ not in _option_choice_names for _ in _data_choice_names
) or len(_data_choice_names) != len(_option_choice_names):
return False, command

for choice in option.get("choices"):
for _choice in _option.get("choices"):
if choice["name"] == _choice["name"]:
for choice_attr in choice_attrs:
if (
choice.get(choice_attr)
and not _choice.get(choice_attr)
or not choice.get(choice_attr)
and _choice.get(choice_attr)
):
return False, command
elif choice.get(choice_attr) != _choice.get(
choice_attr
):
return False, command
else:
continue
elif option_attr == "required":
if (
option.get(option_attr) == None # noqa: E711
and _option.get(option_attr) == False # noqa: E712
):
# API not including if False
continue

elif option_attr == "options":
if not option.get(option_attr) and not _option.get("options"):
continue
_clean, _command = __check_options(option, _option)
if not _clean:
return _clean, _command

elif option.get(option_attr) != _option.get(option_attr):
return False, command
else:
continue
return True, command

for command in pool:
if command["name"] == data["name"]:
_command = command
Expand Down Expand Up @@ -197,83 +270,7 @@ async def __compare_sync(

elif command.get("options") and data.get("options"):

_command_option_names = [_["name"] for _ in command.get("options")]
_data_option_names = [_["name"] for _ in data.get("options")]

if any(
_ not in _command_option_names for _ in _data_option_names
) or len(_data_option_names) != len(_command_option_names):
clean = False
return clean, _command

for option in command.get("options"):
for _option in data.get("options"):
if _option["name"] == option["name"]:
for option_attr in option_attrs:
if (
option.get(option_attr)
and not _option.get(option_attr)
or not option.get(option_attr)
and _option.get(option_attr)
):
clean = False
return clean, _command
elif option_attr == "choices":
if not option.get("choices") or not _option.get(
"choices"
):
continue

_option_choice_names = [
_["name"] for _ in option.get("choices")
]
_data_choice_names = [
_["name"] for _ in _option.get("choices")
]

if any(
_ not in _option_choice_names
for _ in _data_choice_names
) or len(_data_choice_names) != len(
_option_choice_names
):
clean = False
return clean, _command

for choice in option.get("choices"):
for _choice in _option.get("choices"):
if choice["name"] == _choice["name"]:
for choice_attr in choice_attrs:
if (
choice.get(choice_attr)
and not _choice.get(choice_attr)
or not choice.get(choice_attr)
and _choice.get(choice_attr)
):
clean = False
return clean, _command
elif choice.get(
choice_attr
) != _choice.get(choice_attr):
clean = False
return clean, _command
else:
continue
elif option_attr == "required":
if (
option.get(option_attr) == None # noqa: E711
and _option.get(option_attr)
== False # noqa: E712
):
# API not including if False
continue
elif option.get(option_attr) != _option.get(
option_attr
):
clean = False
return clean, _command
else:
continue
clean, _command = __check_options(command, data)

if not clean:
return clean, _command
Expand Down Expand Up @@ -354,8 +351,8 @@ async def _ready(self) -> None:
await self.__register_name_autocomplete()

ready = True
except Exception as error:
log.critical(f"Could not prepare the client: {error}")
except Exception:
log.exception("Could not prepare the client:")
finally:
if ready:
log.debug("Client is now ready.")
Expand Down Expand Up @@ -398,6 +395,17 @@ async def __get_all_commands(self) -> None:
application_id=self.me.id, guild_id=_id, with_localizations=True
)

if isinstance(_cmds, dict) and _cmds.get("code"):
if int(_cmds.get("code")) != 50001:
raise JSONException(_cmds["code"], message=f'{_cmds["message"]} |')

log.info(
f"Your bot is missing access to guild with corresponding id {_id}! "
"Syncing commands will not be possible until it is invited with "
"`application.commands` scope!"
)
continue

for command in _cmds:
if command.get("code"):
# Error exists.
Expand Down Expand Up @@ -431,6 +439,7 @@ async def __sync(self) -> None: # sourcery no-metrics

__check_global_commands: List[str] = [cmd["name"] for cmd in _cmds]
__check_guild_commands: Dict[int, List[str]] = {}
__blocked_guilds: set = set()

# responsible for checking if a command is in the cache but not a coro -> allowing removal

Expand All @@ -439,6 +448,19 @@ async def __sync(self) -> None: # sourcery no-metrics
application_id=self.me.id, guild_id=_id, with_localizations=True
)

if isinstance(_cmds, dict) and _cmds.get("code"):
# Error exists.
if int(_cmds.get("code")) != 50001:
raise JSONException(_cmds["code"], message=f'{_cmds["message"]} |')

log.warning(
f"Your bot is missing access to guild with corresponding id {_id}! "
"Adding commands will not be possible until it is invited with "
"`application.commands` scope!"
)
__blocked_guilds.add(_id)
continue

for command in _cmds:
if command.get("code"):
# Error exists.
Expand All @@ -453,7 +475,9 @@ async def __sync(self) -> None: # sourcery no-metrics
_guild_command: dict
for _guild_command in coro._command_data:
_guild_id = _guild_command.get("guild_id")

if _guild_id in __blocked_guilds:
log.fatal(f"Cannot sync commands on guild with id {_guild_id}!")
raise JSONException(50001, message="Missing Access |")
if _guild_command["name"] not in __check_guild_commands[_guild_id]:
self.__guild_commands[_guild_id]["clean"] = False
self.__guild_commands[_guild_id]["commands"].append(_guild_command)
Expand Down Expand Up @@ -999,7 +1023,11 @@ def decorator(coro: Coroutine) -> Callable[..., Any]:
),
coro=coro,
)
coro._command_data = commands
if hasattr(coro, "__func__"):
coro.__func__._command_data = commands
else:
coro._command_data = commands

self.__command_coroutines.append(coro)

return self.event(coro, name=f"command_{name}")
Expand Down Expand Up @@ -1064,7 +1092,11 @@ def decorator(coro: Coroutine) -> Callable[..., Any]:
),
coro=coro,
)
coro._command_data = commands
if hasattr(coro, "__func__"):
coro.__func__._command_data = commands
else:
coro._command_data = commands

self.__command_coroutines.append(coro)

return self.event(coro, name=f"command_{name}")
Expand Down