Skip to content

tux.cogs.moderation.slowmode

Classes:

Name Description
Slowmode

Classes

Slowmode(bot: Tux)

Bases: Cog

Methods:

Name Description
slowmode

Set or get the slowmode for a channel.

Source code in tux/cogs/moderation/slowmode.py
Python
def __init__(self, bot: Tux) -> None:
    self.bot = bot

Functions

slowmode(ctx: commands.Context[Tux], channel_or_delay: str | None = None, delay: str | None = None) -> None async

Set or get the slowmode for a channel.

Parameters:

Name Type Description Default
ctx Context[Tux]

The context of the command.

required
channel_or_delay Optional[str]

Either a channel mention/ID or a delay value.

None
delay Optional[str]

A delay value if channel_or_delay was a channel.

None

Examples:

$slowmode - Get slowmode for current channel $slowmode 10 - Set 10 second slowmode in current channel $slowmode 5s - Set 5 second slowmode in current channel $slowmode 2m - Set 2 minute slowmode in current channel $slowmode 0 - Turn off slowmode in current channel $slowmode #general - Get slowmode for #general $slowmode #general 10 - Set 10 second slowmode in #general

Source code in tux/cogs/moderation/slowmode.py
Python
@commands.hybrid_command(
    name="slowmode",
    aliases=["sm"],
    usage="slowmode [channel] [seconds]",
)
@commands.guild_only()
@checks.has_pl(2)
async def slowmode(
    self,
    ctx: commands.Context[Tux],
    channel_or_delay: str | None = None,
    delay: str | None = None,
) -> None:
    """
    Set or get the slowmode for a channel.

    Parameters
    ----------
    ctx : commands.Context[Tux]
        The context of the command.
    channel_or_delay : Optional[str]
        Either a channel mention/ID or a delay value.
    delay : Optional[str]
        A delay value if channel_or_delay was a channel.

    Examples
    --------
    $slowmode - Get slowmode for current channel
    $slowmode 10 - Set 10 second slowmode in current channel
    $slowmode 5s - Set 5 second slowmode in current channel
    $slowmode 2m - Set 2 minute slowmode in current channel
    $slowmode 0 - Turn off slowmode in current channel
    $slowmode #general - Get slowmode for #general
    $slowmode #general 10 - Set 10 second slowmode in #general
    """
    assert ctx.guild

    await ctx.defer(ephemeral=True)

    target_channel = None
    delay_value = None

    # Try to parse first argument as a channel
    if channel_or_delay:
        with suppress(commands.CommandError):
            # Try GuildChannel converter which handles all types
            target_channel = await commands.GuildChannelConverter().convert(ctx, channel_or_delay)

    # If first argument was a channel, use second argument as delay
    if target_channel:
        delay_value = delay
    # Otherwise, the first argument might be a delay
    elif channel_or_delay:
        delay_value = channel_or_delay

    # If no channel specified, use current channel
    if not target_channel:
        target_channel = ctx.channel

    # Ensure target_channel is a type that supports slowmode
    if not isinstance(
        target_channel,
        discord.TextChannel | discord.Thread | discord.VoiceChannel | discord.ForumChannel | discord.StageChannel,
    ):
        await ctx.send(
            f"Slowmode cannot be set for this type of channel ({type(target_channel).__name__}).",
            ephemeral=True,
        )
        return

    # Now we have target_channel and maybe delay_value

    # If no delay value, get the current slowmode
    if not delay_value:
        await self._get_slowmode(ctx, target_channel)
    else:
        # Otherwise, set the slowmode
        await self._set_slowmode(ctx, target_channel, delay_value)
_channel_supports_slowmode(channel: SlowmodeChannel) -> bool staticmethod

Check if a channel supports slowmode.

Parameters:

Name Type Description Default
channel SlowmodeChannel

The channel to check

required

Returns:

Type Description
bool

True if the channel supports slowmode, False otherwise

Source code in tux/cogs/moderation/slowmode.py
Python
@staticmethod
def _channel_supports_slowmode(channel: SlowmodeChannel) -> bool:
    """
    Check if a channel supports slowmode.

    Parameters
    ----------
    channel : SlowmodeChannel
        The channel to check

    Returns
    -------
    bool
        True if the channel supports slowmode, False otherwise
    """
    return hasattr(channel, "slowmode_delay") and callable(getattr(channel, "edit", None))
_format_slowmode_message(delay: int, channel_mention: str) -> str staticmethod

Format slowmode delay into a readable message.

Source code in tux/cogs/moderation/slowmode.py
Python
@staticmethod
def _format_slowmode_message(delay: int, channel_mention: str) -> str:
    """Format slowmode delay into a readable message."""
    if delay == 0:
        return f"Slowmode is disabled in {channel_mention}."
    if delay == 1:
        return f"The slowmode in {channel_mention} is 1 second."
    if delay < 60:
        return f"The slowmode in {channel_mention} is {delay} seconds."
    if delay == 60:
        return f"The slowmode in {channel_mention} is 1 minute."

    minutes, seconds = divmod(delay, 60)
    if seconds == 0:
        return f"The slowmode in {channel_mention} is {minutes} minutes."
    minute_suffix = "s" if minutes > 1 else ""
    second_suffix = "s" if seconds > 1 else ""

    return (
        f"The slowmode in {channel_mention} is {minutes} minute{minute_suffix} and {seconds} second{second_suffix}."
    )
_get_slowmode(ctx: commands.Context[Tux], channel: SlowmodeChannel) -> None async staticmethod

Display the current slowmode setting for a channel.

Parameters:

Name Type Description Default
ctx Context[Tux]

The command context

required
channel SlowmodeChannel

The channel to check

required
Source code in tux/cogs/moderation/slowmode.py
Python
@staticmethod
async def _get_slowmode(
    ctx: commands.Context[Tux],
    channel: SlowmodeChannel,
) -> None:
    """
    Display the current slowmode setting for a channel.

    Parameters
    ----------
    ctx : commands.Context[Tux]
        The command context
    channel : SlowmodeChannel
        The channel to check
    """
    try:
        # Check if this channel has a slowmode_delay attribute
        if not hasattr(channel, "slowmode_delay"):
            await ctx.send("This channel type doesn't support slowmode.", ephemeral=True)
            return

        delay = channel.slowmode_delay
        message = Slowmode._format_slowmode_message(delay, channel.mention)
        await ctx.send(message, ephemeral=True)
    except Exception as error:
        logger.error(f"Failed to get slowmode: {error}")
        await ctx.send(f"Failed to get slowmode: {error}", ephemeral=True)
_set_slowmode(ctx: commands.Context[Tux], channel: SlowmodeChannel, delay: str) -> None async

Set the slowmode delay for a channel.

Parameters:

Name Type Description Default
ctx Context[Tux]

The command context

required
channel SlowmodeChannel

The channel to modify

required
delay str

The delay string to parse

required
Source code in tux/cogs/moderation/slowmode.py
Python
async def _set_slowmode(
    self,
    ctx: commands.Context[Tux],
    channel: SlowmodeChannel,
    delay: str,
) -> None:
    """
    Set the slowmode delay for a channel.

    Parameters
    ----------
    ctx : commands.Context[Tux]
        The command context
    channel : SlowmodeChannel
        The channel to modify
    delay : str
        The delay string to parse
    """
    # Verify this channel supports slowmode
    if not self._channel_supports_slowmode(channel):
        await ctx.send("This channel type doesn't support slowmode.", ephemeral=True)
        return

    delay_seconds = self._parse_delay(delay)

    if delay_seconds is None:
        await ctx.send("Invalid delay format. Examples: `5`, `5s`, `2m`", ephemeral=True)
        return

    max_slowmode = 21600  # 6 hours, Discord's maximum
    if not (0 <= delay_seconds <= max_slowmode):
        await ctx.send(
            f"Slowmode delay must be between 0 and {max_slowmode} seconds (6 hours).",
            ephemeral=True,
        )
        return

    try:
        await channel.edit(slowmode_delay=delay_seconds)
        if delay_seconds == 0:
            message = f"Slowmode has been disabled in {channel.mention}."
        else:
            prefix = "Slowmode set to"
            message = (
                f"{prefix} {self._format_slowmode_message(delay_seconds, channel.mention).split('is')[1].strip()}"
            )
        await ctx.send(message, ephemeral=True)
        logger.info(f"{ctx.author} set slowmode to {delay_seconds}s in {channel}")

    except discord.Forbidden:
        await ctx.send(f"I don't have permission to change slowmode in {channel.mention}.", ephemeral=True)

    except discord.HTTPException as error:
        await ctx.send(f"Failed to set slowmode: {error}", ephemeral=True)
        logger.error(f"Failed to set slowmode: {error}")
_parse_delay(delay: str) -> int | None staticmethod

Parse a delay string into seconds.

Parameters:

Name Type Description Default
delay str

The delay string to parse (e.g., "5", "5s", "2m")

required

Returns:

Type Description
Optional[int]

The delay in seconds, or None if invalid format

Source code in tux/cogs/moderation/slowmode.py
Python
@staticmethod
def _parse_delay(delay: str) -> int | None:
    """
    Parse a delay string into seconds.

    Parameters
    ----------
    delay : str
        The delay string to parse (e.g., "5", "5s", "2m")

    Returns
    -------
    Optional[int]
        The delay in seconds, or None if invalid format
    """
    try:
        # Handle suffix formats
        delay = delay.lower().strip()

        if delay.endswith("s"):
            return int(delay[:-1])
        if delay.endswith("m"):
            return int(delay[:-1]) * 60
        if delay.endswith("h"):
            # sourcery skip: assign-if-exp, reintroduce-else
            return int(delay[:-1]) * 3600
        return int(delay)
    except ValueError:
        return None