fix conflicts
This commit is contained in:
@@ -45,6 +45,12 @@ from .guild import Guild
|
||||
from .mixins import Hashable
|
||||
from .sticker import Sticker
|
||||
|
||||
__all__ = (
|
||||
'Attachment',
|
||||
'Message',
|
||||
'MessageReference',
|
||||
'DeletedReferencedMessage',
|
||||
)
|
||||
|
||||
class Attachment:
|
||||
"""Represents an attachment from Discord.
|
||||
@@ -213,11 +219,45 @@ class Attachment:
|
||||
data = await self.read(use_cached=use_cached)
|
||||
return File(io.BytesIO(data), filename=self.filename, spoiler=spoiler)
|
||||
|
||||
class DeletedReferencedMessage:
|
||||
"""A special sentinel type that denotes whether the
|
||||
resolved message referenced message had since been deleted.
|
||||
|
||||
The purpose of this class is to separate referenced messages that could not be
|
||||
fetched and those that were previously fetched but have since been deleted.
|
||||
|
||||
.. versionadded:: 1.6
|
||||
"""
|
||||
|
||||
__slots__ = ('_parent')
|
||||
|
||||
def __init__(self, parent):
|
||||
self._parent = parent
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
""":class:`int`: The message ID of the deleted referenced message."""
|
||||
return self._parent.message_id
|
||||
|
||||
@property
|
||||
def channel_id(self):
|
||||
""":class:`int`: The channel ID of the deleted referenced message."""
|
||||
return self._parent.channel_id
|
||||
|
||||
@property
|
||||
def guild_id(self):
|
||||
"""Optional[:class:`int`]: The guild ID of the deleted referenced message."""
|
||||
return self._parent.guild_id
|
||||
|
||||
|
||||
class MessageReference:
|
||||
"""Represents a reference to a :class:`Message`.
|
||||
"""Represents a reference to a :class:`~discord.Message`.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. versionchanged:: 1.6
|
||||
This class can now be constructed by users.
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
message_id: Optional[:class:`int`]
|
||||
@@ -226,15 +266,56 @@ class MessageReference:
|
||||
The channel id of the message referenced.
|
||||
guild_id: Optional[:class:`int`]
|
||||
The guild id of the message referenced.
|
||||
resolved: Optional[Union[:class:`Message`, :class:`DeletedReferencedMessage`]]
|
||||
The message that this reference resolved to. If this is ``None``
|
||||
then the original message was not fetched either due to the discord API
|
||||
not attempting to resolve it or it not being available at the time of creation.
|
||||
If the message was resolved at a prior point but has since been deleted then
|
||||
this will be of type :class:`DeletedReferencedMessage`.
|
||||
|
||||
Currently, this is mainly the replied to message when a user replies to a message.
|
||||
|
||||
.. versionadded:: 1.6
|
||||
"""
|
||||
|
||||
__slots__ = ('message_id', 'channel_id', 'guild_id', '_state')
|
||||
__slots__ = ('message_id', 'channel_id', 'guild_id', 'resolved', '_state')
|
||||
|
||||
def __init__(self, state, **kwargs):
|
||||
self.message_id = utils._get_as_snowflake(kwargs, 'message_id')
|
||||
self.channel_id = int(kwargs.pop('channel_id'))
|
||||
self.guild_id = utils._get_as_snowflake(kwargs, 'guild_id')
|
||||
def __init__(self, *, message_id, channel_id, guild_id=None):
|
||||
self._state = None
|
||||
self.resolved = None
|
||||
self.message_id = message_id
|
||||
self.channel_id = channel_id
|
||||
self.guild_id = guild_id
|
||||
|
||||
@classmethod
|
||||
def with_state(cls, state, data):
|
||||
self = cls.__new__(cls)
|
||||
self.message_id = utils._get_as_snowflake(data, 'message_id')
|
||||
self.channel_id = int(data.pop('channel_id'))
|
||||
self.guild_id = utils._get_as_snowflake(data, 'guild_id')
|
||||
self._state = state
|
||||
self.resolved = None
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def from_message(cls, message):
|
||||
"""Creates a :class:`MessageReference` from an existing :class:`~discord.Message`.
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
Parameters
|
||||
----------
|
||||
message: :class:`~discord.Message`
|
||||
The message to be converted into a reference.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`MessageReference`
|
||||
A reference to the message.
|
||||
"""
|
||||
self = cls(message_id=message.id, channel_id=message.channel.id, guild_id=getattr(message.guild, 'id', None))
|
||||
self._state = message._state
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def from_message(cls, message):
|
||||
@@ -256,35 +337,21 @@ class MessageReference:
|
||||
|
||||
@property
|
||||
def cached_message(self):
|
||||
"""Optional[:class:`Message`]: The cached message, if found in the internal message cache."""
|
||||
"""Optional[:class:`~discord.Message`]: The cached message, if found in the internal message cache."""
|
||||
return self._state._get_message(self.message_id)
|
||||
|
||||
def __repr__(self):
|
||||
return '<MessageReference message_id={0.message_id!r} channel_id={0.channel_id!r} guild_id={0.guild_id!r}>'.format(self)
|
||||
|
||||
def to_dict(self, specify_channel=False):
|
||||
"""Converts the message reference to a dict, for transmission via the gateway.
|
||||
|
||||
.. versionadded:: 1.5.1.5
|
||||
|
||||
Parameters
|
||||
-------
|
||||
specify_channel: Optional[:class:`bool`]
|
||||
Whether to include the channel ID in the returned object.
|
||||
Defaults to False.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`dict`
|
||||
The reference as a dict.
|
||||
"""
|
||||
result = {'message_id': self.message_id} if self.message_id is not None else {}
|
||||
if specify_channel:
|
||||
result['channel_id'] = self.channel_id
|
||||
if self.guild_id is not None:
|
||||
result['guild_id'] = self.guild_id
|
||||
def to_dict(self):
|
||||
result = {'message_id': self.message_id} if self.message_id is not None else {}
|
||||
result['channel_id'] = self.channel_id
|
||||
if self.guild_id is not None:
|
||||
result['guild_id'] = self.guild_id
|
||||
return result
|
||||
|
||||
to_message_reference_dict = to_dict
|
||||
|
||||
def flatten_handlers(cls):
|
||||
prefix = len('_handle_')
|
||||
handlers = [
|
||||
@@ -332,10 +399,10 @@ class Message(Hashable):
|
||||
call: Optional[:class:`CallMessage`]
|
||||
The call that the message refers to. This is only applicable to messages of type
|
||||
:attr:`MessageType.call`.
|
||||
reference: Optional[:class:`MessageReference`]
|
||||
reference: Optional[:class:`~discord.MessageReference`]
|
||||
The message that this message references. This is only applicable to messages of
|
||||
type :attr:`MessageType.pins_add`, crossposted messages created by a
|
||||
followed channel integration or message replies.
|
||||
followed channel integration, or message replies.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
@@ -431,8 +498,27 @@ class Message(Hashable):
|
||||
self.nonce = data.get('nonce')
|
||||
self.stickers = [Sticker(data=data, state=state) for data in data.get('stickers', [])]
|
||||
|
||||
ref = data.get('message_reference')
|
||||
self.reference = MessageReference(state, **ref) if ref is not None else None
|
||||
try:
|
||||
ref = data['message_reference']
|
||||
except KeyError:
|
||||
self.reference = None
|
||||
else:
|
||||
self.reference = ref = MessageReference.with_state(state, ref)
|
||||
try:
|
||||
resolved = data['referenced_message']
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
if resolved is None:
|
||||
ref.resolved = DeletedReferencedMessage(ref)
|
||||
else:
|
||||
# Right now the channel IDs match but maybe in the future they won't.
|
||||
if ref.channel_id == channel.id:
|
||||
chan = channel
|
||||
else:
|
||||
chan, _ = state._get_guild_channel(resolved)
|
||||
|
||||
ref.resolved = self.__class__(channel=chan, data=resolved, state=state)
|
||||
|
||||
for handler in ('author', 'member', 'mentions', 'mention_roles', 'call', 'flags'):
|
||||
try:
|
||||
@@ -891,9 +977,22 @@ class Message(Hashable):
|
||||
before deleting the message we just edited. If the deletion fails,
|
||||
then it is silently ignored.
|
||||
allowed_mentions: Optional[:class:`~discord.AllowedMentions`]
|
||||
Controls the mentions being processed in this message.
|
||||
Controls the mentions being processed in this message. If this is
|
||||
passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`.
|
||||
The merging behaviour only overrides attributes that have been explicitly passed
|
||||
to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`.
|
||||
If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions`
|
||||
are used instead.
|
||||
|
||||
.. versionadded:: 1.4
|
||||
.. versionchanged:: 1.6
|
||||
:attr:`~discord.Client.allowed_mentions` serves as defaults unconditionally.
|
||||
|
||||
mention_author: Optional[:class:`bool`]
|
||||
Overrides the :attr:`~discord.AllowedMentions.replied_user` attribute
|
||||
of ``allowed_mentions``.
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
Raises
|
||||
-------
|
||||
@@ -931,17 +1030,24 @@ class Message(Hashable):
|
||||
|
||||
delete_after = fields.pop('delete_after', None)
|
||||
|
||||
try:
|
||||
allowed_mentions = fields.pop('allowed_mentions')
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
if allowed_mentions is not None:
|
||||
if self._state.allowed_mentions is not None:
|
||||
allowed_mentions = self._state.allowed_mentions.merge(allowed_mentions).to_dict()
|
||||
else:
|
||||
allowed_mentions = allowed_mentions.to_dict()
|
||||
fields['allowed_mentions'] = allowed_mentions
|
||||
mention_author = fields.pop('mention_author', None)
|
||||
allowed_mentions = fields.pop('allowed_mentions', None)
|
||||
if allowed_mentions is not None:
|
||||
if self._state.allowed_mentions is not None:
|
||||
allowed_mentions = self._state.allowed_mentions.merge(allowed_mentions)
|
||||
allowed_mentions = allowed_mentions.to_dict()
|
||||
if mention_author is not None:
|
||||
allowed_mentions['replied_user'] = mention_author
|
||||
fields['allowed_mentions'] = allowed_mentions
|
||||
elif mention_author is not None:
|
||||
if self._state.allowed_mentions is not None:
|
||||
allowed_mentions = self._state.allowed_mentions.to_dict()
|
||||
allowed_mentions['replied_user'] = mention_author
|
||||
else:
|
||||
allowed_mentions = {'replied_user': mention_author}
|
||||
fields['allowed_mentions'] = allowed_mentions
|
||||
elif self._state.allowed_mentions is not None:
|
||||
fields['allowed_mentions'] = self._state.allowed_mentions.to_dict()
|
||||
|
||||
if fields:
|
||||
data = await self._state.http.edit_message(self.channel.id, self.id, **fields)
|
||||
@@ -1180,26 +1286,50 @@ class Message(Hashable):
|
||||
|
||||
async def reply(self, content=None, **kwargs):
|
||||
"""|coro|
|
||||
A shortcut method to :meth:`abc.Messageable.send` to reply to the
|
||||
:class:`Message`.
|
||||
|
||||
.. versionadded:: 1.5.1.5
|
||||
|
||||
Raises
|
||||
--------
|
||||
~discord.HTTPException
|
||||
Sending the message failed.
|
||||
~discord.Forbidden
|
||||
You do not have the proper permissions to send the message.
|
||||
~discord.InvalidArgument
|
||||
The ``files`` list is not of the appropriate size or
|
||||
you specified both ``file`` and ``files``.
|
||||
|
||||
Returns
|
||||
---------
|
||||
:class:`Message`
|
||||
The message that was sent.
|
||||
"""
|
||||
|
||||
reference = MessageReference.from_message(self)
|
||||
return await self.channel.send(content, message_reference=reference, **kwargs)
|
||||
A shortcut method to :meth:`abc.Messageable.send` to reply to the
|
||||
:class:`Message`.
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
Raises
|
||||
--------
|
||||
~discord.HTTPException
|
||||
Sending the message failed.
|
||||
~discord.Forbidden
|
||||
You do not have the proper permissions to send the message.
|
||||
~discord.InvalidArgument
|
||||
The ``files`` list is not of the appropriate size or
|
||||
you specified both ``file`` and ``files``.
|
||||
|
||||
Returns
|
||||
---------
|
||||
:class:`Message`
|
||||
The message that was sent.
|
||||
"""
|
||||
|
||||
return await self.channel.send(content, reference=self, **kwargs)
|
||||
|
||||
def to_reference(self):
|
||||
"""Creates a :class:`~discord.MessageReference` from the current message.
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
Returns
|
||||
---------
|
||||
:class:`~discord.MessageReference`
|
||||
The reference to this message.
|
||||
"""
|
||||
|
||||
return MessageReference.from_message(self)
|
||||
|
||||
def to_message_reference_dict(self):
|
||||
data = {
|
||||
'message_id': self.id,
|
||||
'channel_id': self.channel.id,
|
||||
}
|
||||
|
||||
if self.guild is not None:
|
||||
data['guild_id'] = self.guild.id
|
||||
|
||||
return data
|
||||
|
||||
Reference in New Issue
Block a user