Skip to content

Commit

Permalink
Merge branch 'master' into fix/ban-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Lulalaby committed Apr 30, 2023
2 parents bd60477 + 04da6ed commit 8556ed2
Show file tree
Hide file tree
Showing 39 changed files with 706 additions and 125 deletions.
7 changes: 4 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ci:
autoupdate_commit_msg: "chore(pre-commit): pre-commit autoupdate"
autofix_commit_msg: "style(pre-commit): auto fixes from pre-commit.com hooks"

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
Expand All @@ -8,7 +9,7 @@ repos:
- id: trailing-whitespace
- id: end-of-file-fixer
- repo: https://github.com/PyCQA/autoflake
rev: v2.0.2
rev: v2.1.1
hooks:
- id: autoflake
# args:
Expand All @@ -27,7 +28,7 @@ repos:
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.1.0
rev: 23.3.0
hooks:
- id: black
args: [--safe, --quiet]
Expand Down Expand Up @@ -76,7 +77,7 @@ repos:
# - id: mypy

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0-alpha.6
rev: v3.0.0-alpha.9-for-vscode
hooks:
- id: prettier
args: [--prose-wrap=always, --print-width=88]
Expand Down
46 changes: 45 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ These changes are available on the `master` branch, but have not yet been releas

### Added

- Added possibility to start bot via async context manager.
([#1801](https://github.com/Pycord-Development/pycord/pull/1801))
- Added new parameters (`author`, `footer`, `image`, `thumbnail`) to `discord.Embed`.
([#1996](https://github.com/Pycord-Development/pycord/pull/1996))
- Added new events `on_bridge_command`, `on_bridge_command_completion`, and
`on_bridge_command_error`.
([#1916](https://github.com/Pycord-Development/pycord/pull/1916))
Expand All @@ -22,9 +26,34 @@ These changes are available on the `master` branch, but have not yet been releas
- Added support for one-time event listeners in `@client.listen()`.
([#1957](https://github.com/Pycord-Development/pycord/pull/1957))
- Added `current_page` argument to Paginator.update().
([#1983](https://github.com/Pycord-Development/pycord/pull/1983)
([#1983](https://github.com/Pycord-Development/pycord/pull/1983))
- Added new `application_auto_moderation_rule_create_badge` to `ApplicationFlags`.
([#1992](https://github.com/Pycord-Development/pycord/pull/1992))
- Added `custom_message` to AutoModActionMetadata.
([#2029](https://github.com/Pycord-Development/pycord/pull/2029))
- Added support for
[voice messages](https://github.com/discord/discord-api-docs/pull/6082).
([#2016](https://github.com/Pycord-Development/pycord/pull/2016))
- Added the `data` attribute to all
[Raw Event payloads](https://docs.pycord.dev/en/master/api/models.html#events).
([#2023](https://github.com/Pycord-Development/pycord/pull/2023))
- Added and documented missing `AuditLogAction` enums.
([#2030](https://github.com/Pycord-Development/pycord/pull/2030))
- `AuditLogDiff` now supports AutoMod related models.
([#2030](https://github.com/Pycord-Development/pycord/pull/2030))
- Added `Interaction.respond` and `Interaction.edit` as shortcut responses.
([#2026](https://github.com/Pycord-Development/pycord/pull/2026))

### Changed

- Suppressed FFMPEG output when recording voice channels.
([#1993](https://github.com/Pycord-Development/pycord/pull/1993))
- Changed file-upload size limit from 8 MB to 25 MB accordingly.
([#2014](https://github.com/Pycord-Development/pycord/pull/2014))
- `Interaction.channel` is received from the gateway, so it can now be `DMChannel` and
`GroupChannel`. ([#2025](https://github.com/Pycord-Development/pycord/pull/2025))
- `DMChannel.recipients` can now be `None`
([#2025](https://github.com/Pycord-Development/pycord/pull/2025))

### Removed

Expand All @@ -36,6 +65,21 @@ These changes are available on the `master` branch, but have not yet been releas
- Fixed `AttributeError` caused by
[#1957](https://github.com/Pycord-Development/pycord/pull/1957) when using listeners
in cogs. ([#1989](https://github.com/Pycord-Development/pycord/pull/1989))
- Editing a webhook message if the thread is a forum post or if the thread is a private
thread ([#1981](https://github.com/Pycord-Development/pycord/pull/1981))
- Fixed `View.message` not being set when view is sent using webhooks, including
`Interaction.followup.send` or when a message is edited.
([#1997](https://github.com/Pycord-Development/pycord/pull/1997))
- Fixed `None` being handled incorrectly for avatar in `ClientUser.edit`.
([#1994](https://github.com/Pycord-Development/pycord/pull/1994))
- Fixed scheduled events breaking when changing the location from external to a channel.
([#1998](https://github.com/Pycord-Development/pycord/pull/1998))
- Fixed boolean converter breaking for bridge commands. Fix bridge command Options not
working. ([#1999](https://github.com/Pycord-Development/pycord/pull/1999))
- Fixed `TypeError` being raised when passing `name` argument to bridge groups.
([#2000](https://github.com/Pycord-Development/pycord/pull/2000))
- Fixed `TypeError` in AutoModRule.
([#2029](https://github.com/Pycord-Development/pycord/pull/2029))

## [2.4.1] - 2023-03-20

Expand Down
2 changes: 1 addition & 1 deletion discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@ async def send(
.. versionadded:: 2.0
suppress: :class:`bool`
Whether to suppress embeds for the message.
slient: :class:`bool`
silent: :class:`bool`
Whether to suppress push and desktop notifications for the message.
.. versionadded:: 2.4
Expand Down
80 changes: 79 additions & 1 deletion discord/audit_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

from . import enums, utils
from .asset import Asset
from .automod import AutoModAction, AutoModTriggerMetadata
from .colour import Colour
from .invite import Invite
from .mixins import Hashable
Expand Down Expand Up @@ -57,6 +58,8 @@
from .threads import Thread
from .types.audit_log import AuditLogChange as AuditLogChangePayload
from .types.audit_log import AuditLogEntry as AuditLogEntryPayload
from .types.automod import AutoModAction as AutoModActionPayload
from .types.automod import AutoModTriggerMetadata as AutoModTriggerMetadataPayload
from .types.channel import PermissionOverwrite as PermissionOverwritePayload
from .types.role import Role as RolePayload
from .types.snowflake import Snowflake
Expand All @@ -83,6 +86,22 @@ def _transform_channel(
return entry.guild.get_channel(int(data)) or Object(id=data)


def _transform_channels(
entry: AuditLogEntry, data: list[Snowflake] | None
) -> list[abc.GuildChannel | Object] | None:
if data is None:
return None
return [_transform_channel(entry, channel) for channel in data]


def _transform_roles(
entry: AuditLogEntry, data: list[Snowflake] | None
) -> list[Role | Object] | None:
if data is None:
return None
return [entry.guild.get_role(int(r)) or Object(id=r) for r in data]


def _transform_member_id(
entry: AuditLogEntry, data: Snowflake | None
) -> Member | User | None:
Expand Down Expand Up @@ -172,6 +191,24 @@ def _transform_type(
return enums.try_enum(enums.ChannelType, data)


def _transform_actions(
entry: AuditLogEntry, data: list[AutoModActionPayload] | None
) -> AutoModAction | None:
if data is None:
return None
else:
return [AutoModAction.from_dict(d) for d in data]


def _transform_trigger_metadata(
entry: AuditLogEntry, data: list[AutoModActionPayload] | None
) -> AutoModAction | None:
if data is None:
return None
else:
return AutoModTriggerMetadata.from_dict(data)


class AuditLogDiff:
def __len__(self) -> int:
return len(self.__dict__)
Expand Down Expand Up @@ -240,6 +277,12 @@ class AuditLogChanges:
),
"command_id": ("command_id", _transform_snowflake),
"image_hash": ("cover", _transform_scheduled_event_cover),
"trigger_type": (None, _enum_transformer(enums.AutoModTriggerType)),
"event_type": (None, _enum_transformer(enums.AutoModEventType)),
"actions": (None, _transform_actions),
"trigger_metadata": (None, _transform_trigger_metadata),
"exempt_roles": (None, _transform_roles),
"exempt_channels": (None, _transform_channels),
}

def __init__(
Expand All @@ -255,13 +298,31 @@ def __init__(
for elem in sorted(data, key=lambda i: i["key"]):
attr = elem["key"]

# special cases for role add/remove
# special cases for role/trigger_metadata add/remove
if attr == "$add":
self._handle_role(self.before, self.after, entry, elem["new_value"]) # type: ignore
continue
elif attr == "$remove":
self._handle_role(self.after, self.before, entry, elem["new_value"]) # type: ignore
continue
elif attr in [
"$add_keyword_filter",
"$add_regex_patterns",
"$add_allow_list",
]:
self._handle_trigger_metadata(
self.before, self.after, entry, elem["new_value"], attr
)
continue
elif attr in [
"$remove_keyword_filter",
"$remove_regex_patterns",
"$remove_allow_list",
]:
self._handle_trigger_metadata(
self.after, self.before, entry, elem["new_value"], attr
)
continue

try:
key, transformer = self.TRANSFORMERS[attr]
Expand Down Expand Up @@ -355,6 +416,23 @@ def _handle_role(

setattr(second, "roles", data)

def _handle_trigger_metadata(
self,
first: AuditLogDiff,
second: AuditLogDiff,
entry: AuditLogEntry,
elem: list[AutoModTriggerMetadataPayload],
attr: str,
) -> None:
if not hasattr(first, "trigger_metadata"):
setattr(first, "trigger_metadata", None)

key = attr.split("_", 1)[-1]
data = {key: elem}
tm = AutoModTriggerMetadata.from_dict(data)

setattr(second, "trigger_metadata", tm)


class _AuditLogProxyMemberPrune:
delete_member_days: int
Expand Down
21 changes: 19 additions & 2 deletions discord/automod.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,29 @@ class AutoModActionMetadata:
timeout_duration: :class:`datetime.timedelta`
How long the member that triggered the action should be timed out for.
Only for actions of type :attr:`AutoModActionType.timeout`.
custom_message: :class:`str`
An additional message shown to members when their message is blocked.
Maximum 150 characters.
Only for actions of type :attr:`AutoModActionType.block_message`.
"""

# maybe add a table of action types and attributes?

__slots__ = (
"channel_id",
"timeout_duration",
"custom_message",
)

def __init__(
self, channel_id: int = MISSING, timeout_duration: timedelta = MISSING
self,
channel_id: int = MISSING,
timeout_duration: timedelta = MISSING,
custom_message: str = MISSING,
):
self.channel_id: int = channel_id
self.timeout_duration: timedelta = timeout_duration
self.custom_message: str = custom_message

def to_dict(self) -> dict:
data = {}
Expand All @@ -100,6 +109,9 @@ def to_dict(self) -> dict:
if self.timeout_duration is not MISSING:
data["duration_seconds"] = self.timeout_duration.total_seconds()

if self.custom_message is not MISSING:
data["custom_message"] = self.custom_message

return data

@classmethod
Expand All @@ -113,12 +125,16 @@ def from_dict(cls, data: AutoModActionMetadataPayload):
# might need an explicit int cast
kwargs["timeout_duration"] = timedelta(seconds=duration_seconds)

if (custom_message := data.get("custom_message")) is not None:
kwargs["custom_message"] = custom_message

return cls(**kwargs)

def __repr__(self) -> str:
repr_attrs = (
"channel_id",
"timeout_duration",
"custom_message",
)
inner = []

Expand Down Expand Up @@ -301,7 +317,7 @@ def __repr__(self) -> str:
inner.append(f"{attr}={value}")
inner = " ".join(inner)

return f"<AutoModActionMetadata {inner}>"
return f"<AutoModTriggerMetadata {inner}>"


class AutoModRule(Hashable):
Expand Down Expand Up @@ -352,6 +368,7 @@ class AutoModRule(Hashable):
"""

__slots__ = (
"__dict__",
"_state",
"id",
"guild_id",
Expand Down
4 changes: 3 additions & 1 deletion discord/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2838,7 +2838,9 @@ def __init__(
self, *, me: ClientUser, state: ConnectionState, data: DMChannelPayload
):
self._state: ConnectionState = state
self.recipient: User | None = state.store_user(data["recipients"][0])
self.recipient: User | None = None
if r := data.get("recipients"):
self.recipient: state.store_user(r[0])
self.me: ClientUser = me
self.id: int = int(data["id"])

Expand Down
22 changes: 22 additions & 0 deletions discord/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import signal
import sys
import traceback
from types import TracebackType
from typing import TYPE_CHECKING, Any, Callable, Coroutine, Generator, Sequence, TypeVar

import aiohttp
Expand Down Expand Up @@ -253,6 +254,27 @@ def __init__(
VoiceClient.warn_nacl = False
_log.warning("PyNaCl is not installed, voice will NOT be supported")

async def __aenter__(self) -> Client:
loop = asyncio.get_running_loop()
self.loop = loop
self.http.loop = loop
self._connection.loop = loop

self._ready = asyncio.Event()

return self

async def __aexit__(
self,
exc_t: BaseException | None,
exc_v: BaseException | None,
exc_tb: TracebackType | None,
) -> None:
if not self.is_closed():
await self.close()

# internals

def _get_websocket(
self, guild_id: int | None = None, *, shard_id: int | None = None
) -> DiscordWebSocket:
Expand Down
Loading

0 comments on commit 8556ed2

Please sign in to comment.