Skip to content
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1155cf4
fix: Error starting when using scope param in command decorator (#1217)
H3rmt Jan 9, 2023
628a472
fix(attrs): add factory value to interaction resolved data (#1212)
Damego Jan 10, 2023
6ea3919
feat: Add `channel` & `guild` property for `VoiceState` (#1215)
Damego Jan 10, 2023
496ec39
fix: bug can't use list with components in `disable_components` (#1218)
Damego Jan 10, 2023
f26dfd3
feat: Add support for the event `GUILD_AUDIT_LOG_ENTRY_CREATE` (#1221)
GeomKid Jan 14, 2023
9270d3c
fix: Warns user that the bot is not in guild than rather fails (#1220)
GeomKid Jan 14, 2023
a6f832d
docs: add missed fields for the `GuildAuditLogEntry` (#1222)
Damego Jan 15, 2023
b4154b8
refactor!: Change type of permissions attrs to `Permissions` (#1209)
Damego Jan 15, 2023
d2f7668
refactor: add an ability to delay bot's token (#1216)
Catalyst4222 Jan 15, 2023
4eeb138
fix: Skip guild from syncing instead of raising an error (#1223)
GeomKid Jan 17, 2023
13efcc4
feat: Add helpers for role connection (#1207)
Damego Jan 21, 2023
646e16c
feat: Add support for age-restricted commands (#1208)
Damego Jan 21, 2023
a6d93ec
refactor: move `delete` to base context (#1219)
Damego Jan 21, 2023
f052b44
feat: Implement own `IntEnum` & `StrEnum` (#1201)
Damego Jan 21, 2023
b34fbfd
fix: make sure `Client._http` is not a string
Damego Jan 22, 2023
a997fae
Merge pull request #1239 from Damego/make-sure-http-is-not-a-string
FayeDel Jan 22, 2023
9810c5b
refactor: change logging level to debug for per-route ratelimit (#1242)
Damego Jan 23, 2023
438c8e8
docs: add missed docs for role connection metadata (#1244)
Damego Jan 25, 2023
b583d8d
feat: add member flags (#1252)
Damego Jan 27, 2023
090add6
docs: remove extra brackets in audit log entry (#1253)
Damego Jan 27, 2023
837a866
ci: weekly check. (#1258)
pre-commit-ci[bot] Jan 31, 2023
067ea9b
refactor: return embed on update (#1259)
Morgandri1 Jan 31, 2023
3784072
refactor(context): allow edit message from modal interaction (#1245)
Damego Feb 3, 2023
2c3ffa3
fix: `client`, `command` and `extension` are missed in `on_command` e…
Damego Feb 3, 2023
e8075e4
feat: add `component` property to `ComponentContext` (#1268)
GeomKid Feb 4, 2023
79857b7
feat: add the `on_disconnect` event (#1199)
Catalyst4222 Feb 5, 2023
c890be5
chore: Bump version to v4.4 (#1269)
FayeDel Feb 6, 2023
55da69a
ci: weekly check. (#1272)
pre-commit-ci[bot] Feb 7, 2023
be2ac0e
fix: null values for `message_reference` after serializing (#1271)
Damego Feb 9, 2023
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: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ repos:
types: [file, python]
args: [--max-line-length=100, --ignore=E203 E301 E302 E501 E402 E704 W503 W504]
- repo: https://github.com/pycqa/isort
rev: 5.11.4
rev: 5.12.0
hooks:
- id: isort
name: isort Formatting
Expand Down
8 changes: 8 additions & 0 deletions docs/events.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ There are several different internal events:

- ``raw_socket_create``
- ``on_start``
- ``on_disconnect``
- ``on_interaction``
- ``on_command``
- ``on_command_error``
Expand Down Expand Up @@ -82,6 +83,13 @@ This function takes no arguments.
.. attention::
Unlike ``on_ready``, this event will never be dispatched more than once.

Event: ``on_disconnect``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
This event fires whenever the connection is invalidated and will often precede an ``on_ready`` event

This function takes no arguments.


Event: ``on_interaction``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
This event fires on any interaction (commands, components, autocomplete and modals).
Expand Down
10 changes: 7 additions & 3 deletions interactions/api/gateway/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
wait_for,
)
from contextlib import suppress
from enum import IntEnum
from sys import platform, version_info
from time import perf_counter
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union
Expand All @@ -26,7 +25,7 @@
from aiohttp import ClientWebSocketResponse, WSMessage, WSMsgType

from ...base import __version__, get_logger
from ...client.enums import ComponentType, InteractionType, OptionType
from ...client.enums import ComponentType, IntEnum, InteractionType, OptionType
from ...client.models import Option
from ...utils.missing import MISSING
from ..dispatch import Listener
Expand Down Expand Up @@ -404,7 +403,6 @@ def _dispatch_interaction_event(self, data: dict) -> None:
_option = self.__sub_command_context(option, _context)
__kwargs.update(_option)

self._dispatch.dispatch("on_command", _context)
elif data["type"] == InteractionType.MESSAGE_COMPONENT:
_name = f"component_{_context.data.custom_id}"

Expand Down Expand Up @@ -931,6 +929,12 @@ async def _reconnect(self, to_resume: bool, code: Optional[int] = 1012) -> None:
if self.__heartbeat_event.is_set():
self.__heartbeat_event.clear() # Because we're hardresetting the process

self._dispatch.dispatch(
"on_disconnect"
) # will be followed by the on_ready event after reconnection
# reconnection happens whenever it disconnects either with or without a resume prompt
# as this is called whenever the WS client closes

if not to_resume:
url = self.ws_url if self.ws_url else await self._http.get_gateway()
else:
Expand Down
2 changes: 1 addition & 1 deletion interactions/api/http/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ async def request(self, route: Route, **kwargs) -> Optional[Any]:
await asyncio.sleep(_limiter.reset_after)
continue
if remaining is not None and int(remaining) == 0:
log.warning(
log.debug(
f"The HTTP client has exhausted a per-route ratelimit. Locking route for {reset_after} seconds."
)
self._loop.call_later(reset_after, _limiter.release_lock)
Expand Down
4 changes: 2 additions & 2 deletions interactions/api/models/audit_log.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# versionadded declared in docs gen file

from enum import IntEnum
from typing import TYPE_CHECKING, List, Optional, TypeVar

from ...client.enums import IntEnum
from ...utils.attrs_utils import DictSerializerMixin, convert_list, define, field
from .channel import Channel
from .misc import Snowflake
Expand Down Expand Up @@ -235,7 +235,7 @@ class AuditLogEntry(DictSerializerMixin):
:ivar Snowflake id: ID of the entry
:ivar AuditLogEvents action_type: Type of action that occurred
:ivar OptionalAuditEntryInfo options: Additional info for certain event types
:ivar str reason: Reason for the change (1-512 characters)
:ivar Optional[str] reason: Reason for the change (1-512 characters)
"""

target_id: Optional[str] = field(default=None)
Expand Down
11 changes: 7 additions & 4 deletions interactions/api/models/channel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from asyncio import Task, create_task, get_running_loop, sleep
from datetime import datetime, timedelta, timezone
from enum import IntEnum
from inspect import isawaitable
from math import inf
from typing import (
Expand All @@ -17,11 +16,13 @@
)
from warnings import warn

from ...client.enums import IntEnum
from ...utils.abc.base_context_managers import BaseAsyncContextManager
from ...utils.abc.base_iterators import DiscordPaginationIterator
from ...utils.attrs_utils import (
ClientSerializerMixin,
DictSerializerMixin,
convert_int,
convert_list,
define,
field,
Expand Down Expand Up @@ -433,7 +434,7 @@ class Channel(ClientSerializerMixin, IDMixin):
:ivar Optional[ThreadMetadata] thread_metadata: The thread metadata of the channel.
:ivar Optional[ThreadMember] member: The member of the thread in the channel.
:ivar Optional[int] default_auto_archive_duration: The set auto-archive time for all threads to naturally follow in the channel.
:ivar Optional[str] permissions: The permissions of the channel.
:ivar Optional[Permissions] permissions: The permissions of the channel.
:ivar Optional[int] flags: The flags of the channel.
:ivar Optional[int] total_message_sent: Number of messages ever sent in a thread.
:ivar Optional[int] default_thread_slowmode_delay: The default slowmode delay in seconds for threads, if this channel is a forum.
Expand Down Expand Up @@ -484,7 +485,9 @@ class Channel(ClientSerializerMixin, IDMixin):
converter=ThreadMember, default=None, add_client=True, repr=False
)
default_auto_archive_duration: Optional[int] = field(default=None)
permissions: Optional[str] = field(default=None, repr=False)
permissions: Optional[Permissions] = field(
converter=convert_int(Permissions), default=None, repr=False
)
flags: Optional[int] = field(default=None, repr=False)
total_message_sent: Optional[int] = field(default=None, repr=False)
default_thread_slowmode_delay: Optional[int] = field(default=None, repr=False)
Expand Down Expand Up @@ -2070,7 +2073,7 @@ async def add_permission_overwrite(
_id = int(id)
_type = type

if not _type:
if _type is MISSING:
raise LibraryException(12, "Please set the type of the overwrite!")

overwrites.append(Overwrite(id=_id, type=_type, allow=allow, deny=deny))
Expand Down
34 changes: 31 additions & 3 deletions interactions/api/models/flags.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from enum import Enum, IntFlag
from enum import IntFlag

__all__ = ("Intents", "AppFlags", "StatusType", "UserFlags", "Permissions", "MessageFlags")
from ...client.enums import StrEnum

__all__ = (
"Intents",
"AppFlags",
"StatusType",
"UserFlags",
"Permissions",
"MessageFlags",
"MemberFlags",
)


class Intents(IntFlag):
Expand Down Expand Up @@ -176,7 +186,7 @@ class AppFlags(IntFlag):
APPLICATION_COMMAND_BADGE = 1 << 23


class StatusType(str, Enum):
class StatusType(StrEnum):
"""
An enumerable object representing Discord status icons that a user may have.
"""
Expand Down Expand Up @@ -214,3 +224,21 @@ class MessageFlags(IntFlag):
EPHEMERAL = 1 << 6
LOADING = 1 << 7
FAILED_TO_MENTION_SOME_ROLES_IN_THREAD = 1 << 8


class MemberFlags(IntFlag):
"""
.. versionadded:: 4.4.0

An integer flag bitshift object representing member flags on the guild.

:ivar int DID_REJOIN: Member has left and rejoined the guild
:ivar int COMPLETED_ONBOARDING: Member has completed onboarding
:ivar int BYPASSES_VERIFICATION: Member bypasses guild verification requirements
:ivar int STARTED_ONBOARDING: Member has started onboarding
"""

DID_REJOIN = 1 << 0
COMPLETED_ONBOARDING = 1 << 1
BYPASSES_VERIFICATION = 1 << 2
STARTED_ONBOARDING = 1 << 3
25 changes: 15 additions & 10 deletions interactions/api/models/guild.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from datetime import datetime
from enum import Enum, IntEnum
from inspect import isawaitable
from math import inf
from typing import (
Expand All @@ -16,10 +15,12 @@
)
from warnings import warn

from ...client.enums import IntEnum, StrEnum
from ...utils.abc.base_iterators import DiscordPaginationIterator
from ...utils.attrs_utils import (
ClientSerializerMixin,
DictSerializerMixin,
convert_int,
convert_list,
define,
field,
Expand All @@ -29,6 +30,7 @@
from .audit_log import AuditLogEvents, AuditLogs
from .channel import Channel, ChannelType, Thread, ThreadMember
from .emoji import Emoji
from .flags import Permissions
from .member import Member
from .message import Sticker, StickerPack
from .misc import (
Expand Down Expand Up @@ -123,7 +125,7 @@ class InviteTargetType(IntEnum):
EMBEDDED_APPLICATION = 2


class GuildFeatures(Enum):
class GuildFeatures(StrEnum):
ANIMATED_BANNER = "ANIMATED_BANNER"
ANIMATED_ICON = "ANIMATED_ICON"
BANNER = "BANNER"
Expand Down Expand Up @@ -349,7 +351,7 @@ class Guild(ClientSerializerMixin, IDMixin):
:ivar Optional[str] discovery_splash: The discovery splash banner of the guild.
:ivar Optional[bool] owner: Whether the guild is owned.
:ivar Snowflake owner_id: The ID of the owner of the guild.
:ivar Optional[str] permissions: The permissions of the guild.
:ivar Optional[Permissions] permissions: The permissions of the guild.
:ivar Optional[str] region: The geographical region of the guild.
:ivar Optional[Snowflake] afk_channel_id: The AFK voice channel of the guild.
:ivar int afk_timeout: The timeout of the AFK voice channel of the guild.
Expand Down Expand Up @@ -400,7 +402,9 @@ class Guild(ClientSerializerMixin, IDMixin):
discovery_splash: Optional[str] = field(default=None, repr=False)
owner: Optional[bool] = field(default=None)
owner_id: Snowflake = field(converter=Snowflake, default=None)
permissions: Optional[str] = field(default=None, repr=False)
permissions: Optional[Permissions] = field(
converter=convert_int(Permissions), default=None, repr=False
)
region: Optional[str] = field(default=None, repr=False) # None, we don't do Voices.
afk_channel_id: Optional[Snowflake] = field(converter=Snowflake, default=None)
afk_timeout: Optional[int] = field(default=None)
Expand Down Expand Up @@ -703,7 +707,7 @@ async def remove_member_role(
async def create_role(
self,
name: str,
permissions: Optional[int] = MISSING,
permissions: Optional[Union[Permissions, int]] = MISSING,
color: Optional[int] = 0,
hoist: Optional[bool] = False,
icon: Optional[Image] = MISSING,
Expand All @@ -718,7 +722,7 @@ async def create_role(

:param str name: The name of the role
:param Optional[int] color: RGB color value as integer, default ``0``
:param Optional[int] permissions: Bitwise value of the enabled/disabled permissions
:param Optional[Union[Permissions, int]] permissions: Bitwise value of the enabled/disabled permissions
:param Optional[bool] hoist: Whether the role should be displayed separately in the sidebar, default ``False``
:param Optional[Image] icon: The role's icon image (if the guild has the ROLE_ICONS feature)
:param Optional[str] unicode_emoji: The role's unicode emoji as a standard emoji (if the guild has the ROLE_ICONS feature)
Expand All @@ -729,7 +733,8 @@ async def create_role(
"""
if not self._client:
raise LibraryException(code=13)
_permissions = permissions if permissions is not MISSING else None

_permissions = int(permissions) if permissions is not MISSING else None
_icon = icon if icon is not MISSING else None
_unicode_emoji = unicode_emoji if unicode_emoji is not MISSING else None
payload = dict(
Expand Down Expand Up @@ -839,7 +844,7 @@ async def modify_role(
self,
role_id: Union[int, Snowflake, Role],
name: Optional[str] = MISSING,
permissions: Optional[int] = MISSING,
permissions: Optional[Union[Permissions, int]] = MISSING,
color: Optional[int] = MISSING,
hoist: Optional[bool] = MISSING,
icon: Optional[Image] = MISSING,
Expand All @@ -855,7 +860,7 @@ async def modify_role(
:param Union[int, Snowflake, Role] role_id: The id of the role to edit
:param Optional[str] name: The name of the role, defaults to the current value of the role
:param Optional[int] color: RGB color value as integer, defaults to the current value of the role
:param Optional[int] permissions: Bitwise value of the enabled/disabled permissions, defaults to the current value of the role
:param Optional[Union[Permissions, int]] permissions: Bitwise value of the enabled/disabled permissions, defaults to the current value of the role
:param Optional[bool] hoist: Whether the role should be displayed separately in the sidebar, defaults to the current value of the role
:param Optional[Image] icon: The role's icon image (if the guild has the ROLE_ICONS feature), defaults to the current value of the role
:param Optional[str] unicode_emoji: The role's unicode emoji as a standard emoji (if the guild has the ROLE_ICONS feature), defaults to the current value of the role
Expand All @@ -876,7 +881,7 @@ async def modify_role(
_color = role.color if color is MISSING else color
_hoist = role.hoist if hoist is MISSING else hoist
_mentionable = role.mentionable if mentionable is MISSING else mentionable
_permissions = role.permissions if permissions is MISSING else permissions
_permissions = int(role.permissions if permissions is MISSING else permissions)
_icon = role.icon if icon is MISSING else icon
_unicode_emoji = role.unicode_emoji if unicode_emoji is MISSING else unicode_emoji

Expand Down
Loading