-
-
Notifications
You must be signed in to change notification settings - Fork 497
fix: GuildSchedule not being cached correctly + missing fields #3025
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 36 commits
43227c4
fe47678
fff9b3b
9e6a986
7b2c31f
5a2581e
973a3d2
9d1d5d7
8c85a05
40d79b6
b5dc3e9
405f2c6
13420ce
469a7b5
a2f09fe
7e42577
1c50c9e
2ff8daf
6dfd511
7fdf52e
bafd549
8f887d3
6772e09
79194b5
70c37cb
2800a08
b9ddb02
7b4f7f5
44fbd76
a548783
a594faa
294dc39
ef960ff
8c4c395
b1bbf52
ddd0c0e
28b4682
c78136d
7022e67
b86cd07
124169b
8cd3495
61078d3
45c2beb
425be22
b01dbcf
207396e
fd65324
38e0034
4742b65
fe312f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,7 +51,7 @@ | |
| from .guild import Guild | ||
| from .member import Member | ||
| from .role import Role | ||
| from .scheduled_events import ScheduledEvent | ||
| from .scheduled_events import ScheduledEvent, ScheduledEventEntityMetadata | ||
| from .stage_instance import StageInstance | ||
| from .state import ConnectionState | ||
| from .sticker import GuildSticker | ||
|
|
@@ -217,6 +217,20 @@ def _transform_communication_disabled_until( | |
| return None | ||
|
|
||
|
|
||
| def _transform_entity_metadata( | ||
| entry: AuditLogEntry, data: dict[str, str] | str | None | ||
| ) -> ScheduledEventEntityMetadata | None: | ||
| from .scheduled_events import ScheduledEventEntityMetadata | ||
|
|
||
| if data is None: | ||
| return None | ||
| if isinstance(data, dict): | ||
| location = data.get("location") | ||
| else: | ||
| location = data | ||
| return ScheduledEventEntityMetadata(location=location) | ||
|
|
||
|
|
||
| class AuditLogDiff: | ||
| def __len__(self) -> int: | ||
| return len(self.__dict__) | ||
|
|
@@ -271,6 +285,8 @@ class AuditLogChanges: | |
| "default_notifications", | ||
| _enum_transformer(enums.NotificationLevel), | ||
| ), | ||
| "entity_metadata": (None, _transform_entity_metadata), | ||
| "location": (None, _transform_entity_metadata), | ||
| "rtc_region": (None, _enum_transformer(enums.VoiceRegion)), | ||
| "video_quality_mode": (None, _enum_transformer(enums.VideoQualityMode)), | ||
| "privacy_level": (None, _enum_transformer(enums.StagePrivacyLevel)), | ||
|
|
@@ -279,7 +295,7 @@ class AuditLogChanges: | |
| "status": (None, _enum_transformer(enums.ScheduledEventStatus)), | ||
| "entity_type": ( | ||
| "location_type", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This renames it to location_type which makes it go against the entire pr's idea. But at the same time, it would be brekaing to change it without backwards compat.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i dont understand ur statement, but i didnt really change auditlogs as now its working fine, and im scared touching anything would break it as the code is a big mess imo
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Pycord-Development/all-contributors Can someone take a look at this audit log stuff as well that is not me ? I'm worried I'm missing something and this is quite a mess |
||
| _enum_transformer(enums.ScheduledEventLocationType), | ||
| _enum_transformer(enums.ScheduledEventEntityType), | ||
| ), | ||
| "command_id": ("command_id", _transform_snowflake), | ||
| "image_hash": ("image", _transform_scheduled_event_image), | ||
|
|
@@ -318,7 +334,11 @@ def __init__( | |
| "$add_allow_list", | ||
| ]: | ||
| self._handle_trigger_metadata( | ||
| self.before, self.after, entry, elem["new_value"], attr # type: ignore | ||
| self.before, | ||
| self.after, | ||
| entry, | ||
| elem["new_value"], | ||
| attr, # type: ignore | ||
| ) | ||
| continue | ||
| elif attr in [ | ||
|
|
@@ -327,7 +347,11 @@ def __init__( | |
| "$remove_allow_list", | ||
| ]: | ||
| self._handle_trigger_metadata( | ||
| self.after, self.before, entry, elem["new_value"], attr # type: ignore | ||
| self.after, | ||
| self.before, | ||
| entry, | ||
| elem["new_value"], | ||
| attr, # type: ignore | ||
| ) | ||
| continue | ||
|
|
||
|
|
@@ -349,21 +373,6 @@ def __init__( | |
| if transformer: | ||
| before = transformer(entry, before) | ||
|
|
||
| if attr == "location" and hasattr(self.before, "location_type"): | ||
| from .scheduled_events import ScheduledEventLocation | ||
|
|
||
| if ( | ||
| self.before.location_type | ||
| is enums.ScheduledEventLocationType.external | ||
| ): | ||
| before = ScheduledEventLocation(state=state, value=before) | ||
| elif hasattr(self.before, "channel"): | ||
| before = ScheduledEventLocation( | ||
| state=state, value=self.before.channel | ||
| ) | ||
|
|
||
| setattr(self.before, attr, before) | ||
|
|
||
| try: | ||
| after = elem["new_value"] | ||
| except KeyError: | ||
|
|
@@ -372,20 +381,10 @@ def __init__( | |
| if transformer: | ||
| after = transformer(entry, after) | ||
|
|
||
| if attr == "location" and hasattr(self.after, "location_type"): | ||
| from .scheduled_events import ScheduledEventLocation | ||
|
|
||
| if ( | ||
| self.after.location_type | ||
| is enums.ScheduledEventLocationType.external | ||
| ): | ||
| after = ScheduledEventLocation(state=state, value=after) | ||
| elif hasattr(self.after, "channel"): | ||
| after = ScheduledEventLocation( | ||
| state=state, value=self.after.channel | ||
| ) | ||
|
|
||
| setattr(self.after, attr, after) | ||
| if attr == "location": | ||
| setattr(self.after, "entity_metadata", after) | ||
| setattr(self.before, "entity_metadata", before) | ||
|
|
||
| # add an alias | ||
| if hasattr(self.after, "colour"): | ||
|
|
@@ -691,7 +690,12 @@ def _convert_target_invite(self, target_id: int) -> Invite: | |
| "uses": changeset.uses, | ||
| } | ||
|
|
||
| obj = Invite(state=self._state, data=fake_payload, guild=self.guild, channel=changeset.channel) # type: ignore | ||
| obj = Invite( | ||
| state=self._state, | ||
| data=fake_payload, | ||
| guild=self.guild, | ||
| channel=changeset.channel, | ||
| ) # type: ignore | ||
| try: | ||
| obj.inviter = changeset.inviter | ||
| except AttributeError: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,15 +61,21 @@ | |
| NotificationLevel, | ||
| NSFWLevel, | ||
| OnboardingMode, | ||
| ScheduledEventLocationType, | ||
| ScheduledEventEntityType, | ||
| ScheduledEventPrivacyLevel, | ||
| SortOrder, | ||
| VerificationLevel, | ||
| VideoQualityMode, | ||
| VoiceRegion, | ||
| try_enum, | ||
| ) | ||
| from .errors import ClientException, HTTPException, InvalidArgument, InvalidData | ||
| from .errors import ( | ||
| ClientException, | ||
| HTTPException, | ||
| InvalidArgument, | ||
| InvalidData, | ||
| ValidationError, | ||
| ) | ||
| from .file import File | ||
| from .flags import SystemChannelFlags | ||
| from .incidents import IncidentsData | ||
|
|
@@ -87,13 +93,17 @@ | |
| from .onboarding import Onboarding | ||
| from .permissions import PermissionOverwrite | ||
| from .role import Role, RoleColours | ||
| from .scheduled_events import ScheduledEvent, ScheduledEventLocation | ||
| from .scheduled_events import ( | ||
| ScheduledEvent, | ||
| ScheduledEventEntityMetadata, | ||
| ScheduledEventLocation, | ||
| ) | ||
| from .soundboard import SoundboardSound | ||
| from .stage_instance import StageInstance | ||
| from .sticker import GuildSticker | ||
| from .threads import Thread, ThreadMember | ||
| from .user import User | ||
| from .utils import _D, _FETCHABLE | ||
| from .utils import _D, _FETCHABLE, warn_deprecated | ||
| from .welcome_screen import WelcomeScreen, WelcomeScreenChannel | ||
| from .widget import Widget | ||
|
|
||
|
|
@@ -4276,37 +4286,82 @@ def get_scheduled_event(self, event_id: int, /) -> ScheduledEvent | None: | |
| """ | ||
| return self._scheduled_events.get(event_id) | ||
|
|
||
| @overload | ||
| async def create_scheduled_event( | ||
| self, | ||
| *, | ||
| name: str, | ||
| description: str = MISSING, | ||
| start_time: datetime.datetime, | ||
| end_time: datetime.datetime = MISSING, | ||
| location: str | int | VoiceChannel | StageChannel | ScheduledEventLocation, | ||
| location: ( | ||
| str | int | VoiceChannel | StageChannel | ScheduledEventLocation | ||
| ) = MISSING, | ||
| reason: str | None = None, | ||
| image: bytes = MISSING, | ||
| ) -> ScheduledEvent | None: ... | ||
|
|
||
| @overload | ||
| async def create_scheduled_event( | ||
| self, | ||
| *, | ||
| name: str, | ||
| description: str = MISSING, | ||
| scheduled_start_time: datetime.datetime, | ||
| scheduled_end_time: datetime.datetime = MISSING, | ||
| entity_type: ScheduledEventEntityType = MISSING, | ||
| entity_metadata: ScheduledEventEntityMetadata | None = MISSING, | ||
| channel_id: int = MISSING, | ||
| privacy_level: ScheduledEventPrivacyLevel = ScheduledEventPrivacyLevel.guild_only, | ||
|
Lumabots marked this conversation as resolved.
|
||
| reason: str | None = None, | ||
| image: bytes = MISSING, | ||
| ) -> ScheduledEvent | None: ... | ||
| async def create_scheduled_event( | ||
| self, | ||
| *, | ||
| name: str, | ||
| description: str = MISSING, | ||
| scheduled_start_time: datetime.datetime, | ||
| scheduled_end_time: datetime.datetime = MISSING, | ||
| location: ( | ||
| str | int | VoiceChannel | StageChannel | ScheduledEventLocation | ||
| ) = MISSING, | ||
| entity_type: ScheduledEventEntityType = MISSING, | ||
| entity_metadata: ScheduledEventEntityMetadata | None = MISSING, | ||
| channel_id: int = MISSING, | ||
|
Lumabots marked this conversation as resolved.
|
||
| privacy_level: ScheduledEventPrivacyLevel = ScheduledEventPrivacyLevel.guild_only, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see above
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here it wasn't added tho so we can't remove it. But you can
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. deprecate it and avoid emitting it in calls |
||
| reason: str | None = None, | ||
| image: bytes = MISSING, | ||
| start_time: datetime.datetime = MISSING, | ||
| end_time: datetime.datetime = MISSING, | ||
| ) -> ScheduledEvent | None: | ||
| """|coro| | ||
| Creates a scheduled event. | ||
|
|
||
| For EXTERNAL events, ``entity_metadata`` with a location and ``end_time`` are required. | ||
| For STAGE_INSTANCE or VOICE events, ``channel_id`` is required. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| name: :class:`str` | ||
| The name of the scheduled event. | ||
| description: Optional[:class:`str`] | ||
| The description of the scheduled event. | ||
| start_time: :class:`datetime.datetime` | ||
| scheduled_start_time: :class:`datetime.datetime` | ||
| A datetime object of when the scheduled event is supposed to start. | ||
| end_time: Optional[:class:`datetime.datetime`] | ||
| scheduled_end_time: Optional[:class:`datetime.datetime`] | ||
| A datetime object of when the scheduled event is supposed to end. | ||
| location: :class:`ScheduledEventLocation` | ||
| The location of where the event is happening. | ||
| Required for EXTERNAL events. | ||
| entity_type: :class:`ScheduledEventEntityType` | ||
| The type of scheduled event (STAGE_INSTANCE, VOICE, or EXTERNAL). | ||
| entity_metadata: Optional[:class:`ScheduledEventEntityMetadata`] | ||
| The entity metadata (required for EXTERNAL events with a location). | ||
| channel_id: Optional[Union[:class:`int`, :class:`VoiceChannel`, :class:`StageChannel`]] | ||
| The channel ID for STAGE_INSTANCE or VOICE events. | ||
| Can be a channel object or a snowflake ID. | ||
| privacy_level: :class:`ScheduledEventPrivacyLevel` | ||
| The privacy level of the event. Currently, the only possible value | ||
| is :attr:`ScheduledEventPrivacyLevel.guild_only`, which is default, | ||
| so there is no need to change this parameter. | ||
| is :attr:`ScheduledEventPrivacyLevel.guild_only`, which is default. | ||
| reason: Optional[:class:`str`] | ||
| The reason to show in the audit log. | ||
| image: Optional[:class:`bytes`] | ||
|
|
@@ -4323,34 +4378,74 @@ async def create_scheduled_event( | |
| You do not have the Manage Events permission. | ||
| HTTPException | ||
| The operation failed. | ||
| ValidationError | ||
| Invalid parameters for the event type. | ||
| """ | ||
| payload: dict[str, str | int] = { | ||
|
Lumabots marked this conversation as resolved.
|
||
| "name": name, | ||
| "scheduled_start_time": start_time.isoformat(), | ||
| "scheduled_start_time": scheduled_start_time.isoformat(), | ||
| "privacy_level": int(privacy_level), | ||
| "entity_type": int(entity_type), | ||
|
Lumabots marked this conversation as resolved.
Outdated
|
||
| } | ||
| if location is MISSING and entity_type is MISSING: | ||
| raise TypeError("Either location or entity_type must be provided.") | ||
| if start_time is MISSING and scheduled_start_time is MISSING: | ||
| raise TypeError( | ||
| "Either start_time or scheduled_start_time must be provided." | ||
| ) | ||
| if start_time is not MISSING: | ||
| warn_deprecated("start_time", "scheduled_start_time", "2.7") | ||
| if scheduled_start_time is MISSING: | ||
| scheduled_start_time = start_time | ||
|
|
||
| if not isinstance(location, ScheduledEventLocation): | ||
| location = ScheduledEventLocation(state=self._state, value=location) | ||
|
|
||
| payload["entity_type"] = location.type.value | ||
|
|
||
| if location.type == ScheduledEventLocationType.external: | ||
| payload["channel_id"] = None | ||
| payload["entity_metadata"] = {"location": location.value} | ||
| else: | ||
| payload["channel_id"] = location.value.id | ||
| payload["entity_metadata"] = None | ||
| if end_time is not MISSING: | ||
| warn_deprecated("end_time", "scheduled_end_time", "2.7") | ||
| if scheduled_end_time is MISSING: | ||
| scheduled_end_time = end_time | ||
|
|
||
| if location is not MISSING: | ||
| warn_deprecated("location", "entity_metadata", "2.7", "3.0") | ||
| if entity_metadata is MISSING: | ||
| if not isinstance(location, (ScheduledEventLocation)): | ||
| location = ScheduledEventLocation(state=self._state, value=location) | ||
| if entity_type is MISSING: | ||
| entity_type = location.type | ||
| if location.type == ScheduledEventEntityType.external: | ||
| entity_metadata = ScheduledEventEntityMetadata(str(location)) | ||
|
|
||
| if scheduled_end_time is not MISSING: | ||
| payload["scheduled_end_time"] = scheduled_end_time.isoformat() | ||
|
|
||
| if description is not MISSING: | ||
| payload["description"] = description | ||
|
|
||
| if end_time is not MISSING: | ||
| payload["scheduled_end_time"] = end_time.isoformat() | ||
|
|
||
| if image is not MISSING: | ||
| payload["image"] = utils._bytes_to_base64_data(image) | ||
|
|
||
| if entity_type == ScheduledEventEntityType.external: | ||
| if entity_metadata is MISSING or entity_metadata is None: | ||
|
Lumabots marked this conversation as resolved.
|
||
| raise ValidationError( | ||
| "entity_metadata with a location is required for EXTERNAL events." | ||
|
Lumabots marked this conversation as resolved.
Outdated
|
||
| ) | ||
| if not entity_metadata.location: | ||
| raise ValidationError( | ||
| "entity_metadata.location cannot be empty for EXTERNAL events." | ||
| ) | ||
| if scheduled_end_time is MISSING: | ||
| raise ValidationError( | ||
| "scheduled_end_time is required for EXTERNAL events." | ||
| ) | ||
|
|
||
| payload["channel_id"] = None | ||
| payload["entity_metadata"] = entity_metadata.to_payload() | ||
| else: | ||
| if channel_id is MISSING: | ||
| raise ValidationError( | ||
| "channel_id is required for STAGE_INSTANCE and VOICE events." | ||
| ) | ||
|
|
||
| payload["channel_id"] = channel_id | ||
|
|
||
| data = await self._state.http.create_scheduled_event( | ||
| guild_id=self.id, reason=reason, **payload | ||
| ) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like it is weird that they both get the same transformer when the two are different types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i made it just to be compatible like before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still confused, location isn't supposed to exist as a top level property on Discord's side no ? So why even do we want to set this if it's never there in the first place ? This code is a mess so I may be wrong here but I'm confused as to why we would handle something Discord doesn't send.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont know what is happening there exactly, but i do know from testing that location is being triggered sometimes, maybe because of how we use it inside py-cord