Esempio n. 1
0
    async def update_available_help_channels(self) -> None:
        """Updates the dynamic message within #how-to-get-help for available help channels."""
        if not self.available_help_channels:
            self.available_help_channels = set(
                c for c in self.available_category.channels if not _channel.is_excluded_channel(c)
            )

        available_channels = AVAILABLE_HELP_CHANNELS.format(
            available=", ".join(
                c.mention for c in sorted(self.available_help_channels, key=attrgetter("position"))
            ) or None
        )

        if self.dynamic_message is not None:
            try:
                log.trace("Help channels have changed, dynamic message has been edited.")
                await self.bot.http.edit_message(
                    constants.Channels.how_to_get_help, self.dynamic_message, content=available_channels
                )
            except discord.NotFound:
                pass
            else:
                return

        log.trace("Dynamic message could not be edited or found. Creating a new one.")
        new_dynamic_message = await self.bot.http.send_message(
            constants.Channels.how_to_get_help, available_channels
        )
        self.dynamic_message = new_dynamic_message["id"]
        await _caches.dynamic_message.set("message_id", self.dynamic_message)
Esempio n. 2
0
    async def on_message(self, message: discord.Message) -> None:
        """Move an available channel to the In Use category and replace it with a dormant one."""
        if message.author.bot:
            return  # Ignore messages sent by bots.

        channel = message.channel

        await _message.check_for_answer(message)

        is_available = channel_utils.is_in_category(
            channel, constants.Categories.help_available)
        if not is_available or _channel.is_excluded_channel(channel):
            return  # Ignore messages outside the Available category or in excluded channels.

        log.trace(
            "Waiting for the cog to be ready before processing messages.")
        await self.init_task

        log.trace(
            "Acquiring lock to prevent a channel from being processed twice..."
        )
        async with self.on_message_lock:
            log.trace(f"on_message lock acquired for {message.id}.")

            if not channel_utils.is_in_category(
                    channel, constants.Categories.help_available):
                log.debug(
                    f"Message {message.id} will not make #{channel} ({channel.id}) in-use "
                    f"because another message in the channel already triggered that."
                )
                return

            log.info(
                f"Channel #{channel} was claimed by `{message.author.id}`.")
            await self.move_to_in_use(channel)
            await _cooldown.revoke_send_permissions(message.author,
                                                    self.scheduler)

            await _message.pin(message)

            # Add user with channel for dormant check.
            await _caches.claimants.set(channel.id, message.author.id)

            self.bot.stats.incr("help.claimed")

            # Must use a timezone-aware datetime to ensure a correct POSIX timestamp.
            timestamp = datetime.now(timezone.utc).timestamp()
            await _caches.claim_times.set(channel.id, timestamp)

            await _caches.unanswered.set(channel.id, True)

            log.trace(f"Releasing on_message lock for {message.id}.")

        # Move a dormant channel to the Available category to fill in the gap.
        # This is done last and outside the lock because it may wait indefinitely for a channel to
        # be put in the queue.
        await self.move_to_available()
Esempio n. 3
0
    async def on_message(self, message: discord.Message) -> None:
        """Move an available channel to the In Use category and replace it with a dormant one."""
        if message.author.bot:
            return  # Ignore messages sent by bots.

        await self.init_task

        if channel_utils.is_in_category(message.channel, constants.Categories.help_available):
            if not _channel.is_excluded_channel(message.channel):
                await self.claim_channel(message)
        else:
            await _message.update_message_caches(message)