diff options
| author | Rapptz <[email protected]> | 2018-04-14 02:23:38 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2018-04-14 02:23:38 -0400 |
| commit | 56650ae7c235a85dac202ea57aa1bab2603a7f92 (patch) | |
| tree | 8403ee92f17c3919b79bda711120d469e9053615 /discord/state.py | |
| parent | Downgrade websockets due to bugs. (diff) | |
| download | discord.py-56650ae7c235a85dac202ea57aa1bab2603a7f92.tar.xz discord.py-56650ae7c235a85dac202ea57aa1bab2603a7f92.zip | |
Change raw events to use slotted data models instead of parameters.
This allows for internal changes in Discord to not cause a breaking
change every time something changes.
Also implements #1214 which adds guild_id to every event where
applicable.
This is a breaking change.
Diffstat (limited to 'discord/state.py')
| -rw-r--r-- | discord/state.py | 72 |
1 files changed, 38 insertions, 34 deletions
diff --git a/discord/state.py b/discord/state.py index cb413cd8..26a411a4 100644 --- a/discord/state.py +++ b/discord/state.py @@ -31,6 +31,7 @@ from .emoji import Emoji, PartialEmoji from .message import Message from .relationship import Relationship from .channel import * +from .raw_models import * from .member import Member from .role import Role from .enums import ChannelType, try_enum, Status @@ -243,6 +244,17 @@ class ConnectionState: for chunk in range(math.ceil(guild._member_count / 1000)): yield self.receive_chunk(guild.id) + def _get_guild_channel(self, data): + try: + guild = self._get_guild(int(data['guild_id'])) + except KeyError: + channel = self.get_channel(int(data['channel_id'])) + guild = None + else: + channel = guild and guild.get_channel(int(data['channel_id'])) + + return channel, guild + @asyncio.coroutine def request_offline_members(self, guilds): # get all the chunks @@ -330,34 +342,33 @@ class ConnectionState: self.dispatch('resumed') def parse_message_create(self, data): - channel = self.get_channel(int(data['channel_id'])) + channel, _ = self._get_guild_channel(data) message = Message(channel=channel, data=data, state=self) self.dispatch('message', message) self._messages.append(message) def parse_message_delete(self, data): - message_id = int(data['id']) - channel_id = int(data['channel_id']) - self.dispatch('raw_message_delete', message_id, channel_id) + raw = RawMessageDeleteEvent(data) + self.dispatch('raw_message_delete', raw) - found = self._get_message(message_id) + found = self._get_message(raw.message_id) if found is not None: self.dispatch('message_delete', found) self._messages.remove(found) def parse_message_delete_bulk(self, data): - message_ids = { int(x) for x in data.get('ids', []) } - channel_id = int(data['channel_id']) - self.dispatch('raw_bulk_message_delete', message_ids, channel_id) - to_be_deleted = [message for message in self._messages if message.id in message_ids] + raw = RawBulkMessageDeleteEvent(data) + self.dispatch('raw_bulk_message_delete', raw) + + to_be_deleted = [message for message in self._messages if message.id in raw.message_ids] for msg in to_be_deleted: self.dispatch('message_delete', msg) self._messages.remove(msg) def parse_message_update(self, data): - message_id = int(data['id']) - self.dispatch('raw_message_edit', message_id, data) - message = self._get_message(message_id) + raw = RawMessageUpdateEvent(data) + self.dispatch('raw_message_edit', raw) + message = self._get_message(raw.message_id) if message is not None: older_message = copy.copy(message) if 'call' in data: @@ -372,54 +383,47 @@ class ConnectionState: self.dispatch('message_edit', older_message, message) def parse_message_reaction_add(self, data): - message_id = int(data['message_id']) - user_id = int(data['user_id']) - channel_id = int(data['channel_id']) - emoji_data = data['emoji'] emoji_id = utils._get_as_snowflake(emoji_data, 'id') emoji = PartialEmoji(animated=emoji_data['animated'], id=emoji_id, name=emoji_data['name']) - self.dispatch('raw_reaction_add', emoji, message_id, channel_id, user_id) + raw = RawReactionActionEvent(data, emoji) + self.dispatch('raw_reaction_add', raw) # rich interface here - message = self._get_message(message_id) + message = self._get_message(raw.message_id) if message is not None: emoji = self._upgrade_partial_emoji(emoji) - reaction = message._add_reaction(data, emoji, user_id) - user = self._get_reaction_user(message.channel, user_id) + reaction = message._add_reaction(data, emoji, raw.user_id) + user = self._get_reaction_user(message.channel, raw.user_id) if user: self.dispatch('reaction_add', reaction, user) def parse_message_reaction_remove_all(self, data): - message_id = int(data['message_id']) - channel_id = int(data['channel_id']) - self.dispatch('raw_reaction_clear', message_id, channel_id) + raw = RawReactionClearEvent(data) + self.dispatch('raw_reaction_clear', raw) - message = self._get_message(message_id) + message = self._get_message(raw.message_id) if message is not None: old_reactions = message.reactions.copy() message.reactions.clear() self.dispatch('reaction_clear', message, old_reactions) def parse_message_reaction_remove(self, data): - message_id = int(data['message_id']) - user_id = int(data['user_id']) - channel_id = int(data['channel_id']) - emoji_data = data['emoji'] emoji_id = utils._get_as_snowflake(emoji_data, 'id') emoji = PartialEmoji(animated=emoji_data['animated'], id=emoji_id, name=emoji_data['name']) - self.dispatch('raw_reaction_remove', emoji, message_id, channel_id, user_id) + raw = RawReactionActionEvent(data, emoji) + self.dispatch('raw_reaction_remove', raw) - message = self._get_message(message_id) + message = self._get_message(raw.message_id) if message is not None: emoji = self._upgrade_partial_emoji(emoji) try: - reaction = message._remove_reaction(data, emoji, user_id) + reaction = message._remove_reaction(data, emoji, raw.user_id) except (AttributeError, ValueError) as e: # eventual consistency lol pass else: - user = self._get_reaction_user(message.channel, user_id) + user = self._get_reaction_user(message.channel, raw.user_id) if user: self.dispatch('reaction_remove', reaction, user) @@ -804,14 +808,14 @@ class ConnectionState: compat.create_task(vc._create_socket(key_id, data)) def parse_typing_start(self, data): - channel = self.get_channel(int(data['channel_id'])) + channel, guild = self._get_guild_channel(data) if channel is not None: member = None user_id = utils._get_as_snowflake(data, 'user_id') if isinstance(channel, DMChannel): member = channel.recipient elif isinstance(channel, TextChannel): - member = channel.guild.get_member(user_id) + member = guild.get_member(user_id) elif isinstance(channel, GroupChannel): member = utils.find(lambda x: x.id == user_id, channel.recipients) |