aboutsummaryrefslogtreecommitdiff
path: root/discord/state.py
diff options
context:
space:
mode:
authorRapptz <[email protected]>2017-06-09 18:36:59 -0400
committerRapptz <[email protected]>2017-06-09 18:36:59 -0400
commitd239cc26666ff255a0c86c83541ef90f2b586598 (patch)
treef7c644f297190cede85b324bdb1d776543523a1e /discord/state.py
parentAllow sending files list smaller than 2 elements in Messageable.send (diff)
downloaddiscord.py-d239cc26666ff255a0c86c83541ef90f2b586598.tar.xz
discord.py-d239cc26666ff255a0c86c83541ef90f2b586598.zip
Implement "partial" message events.
These are events that get triggered regardless of the state of the message cache. Useful for getting data from before the bot was booted.
Diffstat (limited to 'discord/state.py')
-rw-r--r--discord/state.py65
1 files changed, 52 insertions, 13 deletions
diff --git a/discord/state.py b/discord/state.py
index aaa3aa54..67f8f763 100644
--- a/discord/state.py
+++ b/discord/state.py
@@ -26,7 +26,7 @@ DEALINGS IN THE SOFTWARE.
from .guild import Guild
from .user import User, ClientUser
-from .emoji import Emoji, PartialEmoji
+from .emoji import Emoji, PartialReactionEmoji
from .message import Message
from .relationship import Relationship
from .channel import *
@@ -35,6 +35,7 @@ from .role import Role
from .enums import ChannelType, try_enum, Status
from .calls import GroupCall
from . import utils, compat
+from .embeds import Embed
from collections import deque, namedtuple
import copy, enum, math
@@ -314,20 +315,27 @@ class ConnectionState:
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)
+
found = self._get_message(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 = set(map(int, data.get('ids', [])))
- to_be_deleted = list(filter(lambda m: m.id in message_ids, self._messages))
+ 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]
for msg in to_be_deleted:
self.dispatch('message_delete', msg)
self._messages.remove(msg)
def parse_message_update(self, data):
- message = self._get_message(int(data['id']))
+ message_id = int(data['id'])
+ self.dispatch('raw_message_edit', message_id, data)
+ message = self._get_message(message_id)
if message is not None:
older_message = copy.copy(message)
if 'call' in data:
@@ -335,36 +343,61 @@ class ConnectionState:
message._handle_call(data['call'])
elif 'content' not in data:
# embed only edit
- message.embeds = data['embeds']
+ message.embeds = [Embed.from_data(d) for d in data['embeds']]
else:
message._update(channel=message.channel, data=data)
self.dispatch('message_edit', older_message, message)
def parse_message_reaction_add(self, data):
- message = self._get_message(int(data['message_id']))
+ 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 = PartialReactionEmoji(id=emoji_id, name=emoji_data['name'])
+ self.dispatch('raw_reaction_add', emoji, message_id, channel_id, user_id)
+
+ # rich interface here
+ message = self._get_message(message_id)
if message is not None:
- reaction = message._add_reaction(data)
- user = self._get_reaction_user(message.channel, int(data['user_id']))
+ emoji = self._upgrade_partial_emoji(emoji)
+ reaction = message._add_reaction(data, emoji, user_id)
+ user = self._get_reaction_user(message.channel, user_id)
if user:
self.dispatch('reaction_add', reaction, user)
def parse_message_reaction_remove_all(self, data):
- message = self._get_message(int(data['message_id']))
+ message_id = int(data['message_id'])
+ channel_id = int(data['channel_id'])
+ self.dispatch('raw_reaction_clear', message_id, channel_id)
+
+ message = self._get_message(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 = self._get_message(int(data['message_id']))
+ 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 = PartialReactionEmoji(id=emoji_id, name=emoji_data['name'])
+ self.dispatch('raw_reaction_remove', emoji, message_id, channel_id, user_id)
+
+ message = self._get_message(message_id)
if message is not None:
+ emoji = self._upgrade_partial_emoji(emoji)
try:
- reaction = message._remove_reaction(data)
+ reaction = message._remove_reaction(data, emoji, user_id)
except (AttributeError, ValueError) as e: # eventual consistency lol
pass
else:
- user = self._get_reaction_user(message.channel, int(data['user_id']))
+ user = self._get_reaction_user(message.channel, user_id)
if user:
self.dispatch('reaction_remove', reaction, user)
@@ -790,7 +823,13 @@ class ConnectionState:
try:
return self._emojis[emoji_id]
except KeyError:
- return PartialEmoji(id=emoji_id, name=data['name'])
+ return PartialReactionEmoji(id=emoji_id, name=data['name'])
+
+ def _upgrade_partial_emoji(self, emoji):
+ try:
+ return self._emojis[emoji.id]
+ except KeyError:
+ return emoji
def get_channel(self, id):
if id is None: