Esempio n. 1
0
    async def edit(self, new_content: str = None, *,
                   embed: Embed = None) -> 'Message':
        """
        Edits this message.

        You must be the owner of this message to edit it.

        :param new_content: The new content for this message.
        :param embed: The new embed to provide.
        :return: This message, but edited with the new content.
        """
        if self.guild is None:
            is_me = self.author not in self.channel.recipients
        else:
            is_me = self.guild.me == self.author

        if not is_me:
            raise CuriousError("Cannot edit messages from other users")

        if embed:
            embed = embed.to_dict()

        # Prevent race conditions by spawning a listener, then waiting for the task once we've
        # sent the HTTP request.
        t = await curio.spawn(self._bot.wait_for("message_update",
                                                 predicate=lambda o, n: n.id == self.id))
        try:
            await self._bot.http.edit_message(self.channel.id, self.id, content=new_content,
                                              embed=embed)
        except:
            await t.cancel()
            raise
        old, new = await t.join()
        return new
Esempio n. 2
0
    async def edit(self,
                   new_content: str = None,
                   *,
                   embed: Embed = None) -> 'Message':
        """
        Edits this message.

        You must be the owner of this message to edit it.

        :param new_content: The new content for this message.
        :param embed: The new embed to provide.
        :return: This message, but edited with the new content.
        """
        if self.guild is None:
            is_me = self.author not in self.channel.recipients
        else:
            is_me = self.guild.me == self.author

        if not is_me:
            raise CuriousError("Cannot edit messages from other users")

        if embed:
            embed = embed.to_dict()

        async with self._bot.events.wait_for_manager(
                "message_update", lambda o, n: n.id == self.id):
            await self._bot.http.edit_message(self.channel.id,
                                              self.id,
                                              content=new_content,
                                              embed=embed)
        return self
Esempio n. 3
0
    def __init__(self, client, **kwargs):
        super().__init__(kwargs.get("id"), client)

        #: The content of the message.
        self.content = kwargs.get("content", None)  # type: str

        #: The ID of the guild this message is in.
        self.guild_id = None

        #: The ID of the channel the message was sent in.
        self.channel_id = int(kwargs.get("channel_id", 0))  # type: int

        #: The :class:`~.Channel` this message was sent in.
        self.channel = None  # type: dt_channel.Channel

        #: The ID of the author.
        self.author_id = int(kwargs.get("author", {}).get("id", 0)) or None  # type: int

        #: The author of this message. Can be one of: :class:`.Member`, :class:`.Webhook`,
        #: :class:`.User`.
        self.author = None  # type: typing.Union[dt_member.Member, dt_webhook.Webhook]

        type_ = kwargs.get("type", 0)
        #: The type of this message.
        self.type = MessageType(type_)

        #: The true timestamp of this message, a :class:`datetime.datetime`.
        #: This is not the snowflake timestamp.
        self.created_at = to_datetime(kwargs.get("timestamp", None))

        #: The edited timestamp of this message.
        #: This can sometimes be None.
        edited_timestamp = kwargs.get("edited_timestamp", None)
        if edited_timestamp is not None:
            self.edited_at = to_datetime(edited_timestamp)
        else:
            self.edited_at = None

        #: The list of :class:`~.Embed` objects this message contains.
        self.embeds = []
        for embed in kwargs.get("embeds", []):
            self.embeds.append(Embed(**embed))

        #: The list of attachments this message contains.
        self.attachments = []

        for attachment in kwargs.get("attachments", []):
            self.attachments.append(Attachment(**attachment))

        #: The mentions for this message.
        #: This is UNORDERED.
        self._mentions = kwargs.get("mentions", [])

        #: The role mentions for this message.
        #: This is UNORDERED.
        self._role_mentions = kwargs.get("mention_roles", [])

        #: The reactions for this message.
        self.reactions = []
Esempio n. 4
0
    async def send_current_page(self):
        """
        Sends the current page to the channel.
        """
        embed = Embed(description=self._message_chunks[self.page])
        embed.set_footer(text="Page {}/{}".format(self.page + 1, len(self._message_chunks)))

        if self._message is None:
            self._message = await self.channel.send(
                content=self.title,
                embed=embed
            )
        else:
            await self._message.edit(
                new_content=self.title,
                embed=embed
            )
Esempio n. 5
0
    async def send(self,
                   content: str = None,
                   *,
                   tts: bool = False,
                   embed: Embed = None) -> 'dt_message.Message':
        """
        Sends a message to this channel.

        This requires SEND_MESSAGES permission in the channel.
        If the content is not a string, it will be automatically stringified.

        .. code:: python

            await channel.send("Hello, world!")

        :param content: The content of the message to send.
        :param tts: Should this message be text to speech?
        :param embed: An embed object to send with this message.
        :return: A new :class:`~.Message` object.
        """
        if self.type not in [ChannelType.TEXT, ChannelType.PRIVATE]:
            raise CuriousError("Cannot send messages to a voice channel")

        if self.guild:
            if not self.permissions(self.guild.me).send_messages:
                raise PermissionsError("send_messages")

        if not isinstance(content, str) and content is not None:
            content = str(content)

        # check for empty messages
        if not content:
            if not embed:
                raise CuriousError("Cannot send an empty message")

            if self.guild and not self.permissions(self.guild.me).embed_links:
                raise PermissionsError("embed_links")
        else:
            if content and len(content) > 2000:
                raise CuriousError("Content must be less than 2000 characters")

        if embed is not None:
            embed = embed.to_dict()

        data = await self._bot.http.send_message(self.id,
                                                 content,
                                                 tts=tts,
                                                 embed=embed)
        obb = self._bot.state.make_message(data, cache=True)

        return obb
Esempio n. 6
0
    async def handle_message_update(self, gw: 'gateway.GatewayHandler',
                                    event_data: dict):
        """
        Called when MESSAGE_UPDATE is dispatched.
        """
        from_data = self.make_message(event_data, cache=False)
        if not from_data:
            return

        yield "message_update_uncached", from_data

        # Try and find the old message.
        old_message = self.find_message(from_data.id)
        if not old_message:
            return

        new_message = copy.copy(old_message)
        new_message.content = event_data.get("content", old_message.content)
        embeds = event_data.get("embeds")
        if not embeds:
            new_message.embeds = old_message.embeds
        else:
            new_message.embeds = [
                Embed(**em) for em in event_data.get("embeds")
            ]
        new_message._mentions = event_data.get("mentions",
                                               old_message._mentions)
        new_message._role_mentions = event_data.get("mention_roles",
                                                    old_message._role_mentions)

        self.messages.remove(old_message)
        self.messages.append(new_message)

        if old_message.content != new_message.content:
            # Fire a message_edit, as well as a message_update, because the content differs.
            yield "message_edit", old_message, new_message,

        yield "message_update", old_message, new_message,