Skip to content

tux.cogs.snippets.toggle_snippet_lock

Classes:

Name Description
ToggleSnippetLock

Functions:

Name Description
setup

Load the ToggleSnippetLock cog.

Classes

ToggleSnippetLock(bot: Tux)

Bases: SnippetsBaseCog

Methods:

Name Description
toggle_snippet_lock

Toggle the lock status of a snippet.

is_snippetbanned

Check if a user is currently snippet banned in a guild.

check_if_user_has_mod_override

Check if the user invoking the command has moderator permissions (PL >= configured level).

snippet_check

Check if a user is allowed to modify or delete a snippet.

send_snippet_error

Send a standardized snippet error embed.

Source code in tux/cogs/snippets/toggle_snippet_lock.py
Python
def __init__(self, bot: Tux) -> None:
    super().__init__(bot)
    self.toggle_snippet_lock.usage = generate_usage(self.toggle_snippet_lock)

Functions

toggle_snippet_lock(ctx: commands.Context[Tux], name: str) -> None async

Toggle the lock status of a snippet.

Only users with moderator permissions can use this command. Locked snippets cannot be edited or deleted by regular users. Attempts to DM the snippet author about the status change.

Parameters:

Name Type Description Default
ctx Context[Tux]

The context of the command.

required
name str

The name of the snippet to lock or unlock.

required
Source code in tux/cogs/snippets/toggle_snippet_lock.py
Python
@commands.command(
    name="togglesnippetlock",
    aliases=["tsl"],
)
@commands.guild_only()
@checks.has_pl(2)
async def toggle_snippet_lock(self, ctx: commands.Context[Tux], name: str) -> None:
    """Toggle the lock status of a snippet.

    Only users with moderator permissions can use this command.
    Locked snippets cannot be edited or deleted by regular users.
    Attempts to DM the snippet author about the status change.

    Parameters
    ----------
    ctx : commands.Context[Tux]
        The context of the command.
    name : str
        The name of the snippet to lock or unlock.
    """
    assert ctx.guild

    # Fetch the snippet, send error if not found
    snippet = await self._get_snippet_or_error(ctx, name)
    if not snippet:
        return

    # Toggle the lock status in the database
    try:
        status = await self.db.snippet.toggle_snippet_lock_by_id(snippet.snippet_id)
    except Exception as e:
        logger.error(f"Failed to toggle lock for snippet '{name}' (ID: {snippet.snippet_id}): {e}")
        await self.send_snippet_error(
            ctx,
            "An error occurred while trying to toggle the snippet lock. Please try again later.",
        )
        return
    else:  # Proceed only if try block succeeded
        if status is None:  # Should not happen if try succeeded, but added for safety/linter
            logger.error(
                f"Toggle lock for snippet '{name}' (ID: {snippet.snippet_id}) succeeded but returned None status.",
            )
            await self.send_snippet_error(
                ctx,
                "An unexpected issue occurred while toggling the snippet lock.",
            )
            return

        # Confirmation and logging
        lock_status_text = "locked" if status.locked else "unlocked"
        await ctx.send(
            f"Snippet `{name}` has been {lock_status_text}.",
            delete_after=CONST.DEFAULT_DELETE_AFTER,
            ephemeral=True,
        )
        logger.info(f"{ctx.author} {lock_status_text} snippet '{name}'.")

        # Attempt to notify the author via DM
        if author := self.bot.get_user(snippet.snippet_user_id):
            dm_message = (
                f"Your snippet `{snippet.snippet_name}` in server `{ctx.guild.name}` has been {lock_status_text}.\n\n"
                f"**What does this mean?**\n"
                f"If a snippet is locked, it cannot be edited or deleted by anyone other than moderators (like you perhaps!). "
                f"If unlocked, the original author can modify it again.\n\n"
                f"**Why?**\n"
                f"Snippets might be locked/unlocked by moderators for various reasons, often related to server utility or content stability. "
                f"If you believe this was done in error, please contact the server staff."
            )
            with contextlib.suppress(discord.Forbidden, discord.HTTPException):  # Catch potential DM errors
                await author.send(dm_message)
                logger.debug(f"Sent lock status DM to snippet author {author} for snippet '{name}'.")
is_snippetbanned(guild_id: int, user_id: int) -> bool async

Check if a user is currently snippet banned in a guild.

Parameters:

Name Type Description Default
guild_id int

The ID of the guild to check.

required
user_id int

The ID of the user to check.

required

Returns:

Type Description
bool

True if the user is snippet banned, False otherwise.

Source code in tux/cogs/snippets/toggle_snippet_lock.py
Python
@checks.has_pl(2)
async def toggle_snippet_lock(self, ctx: commands.Context[Tux], name: str) -> None:
    """Toggle the lock status of a snippet.

    Only users with moderator permissions can use this command.
    Locked snippets cannot be edited or deleted by regular users.
    Attempts to DM the snippet author about the status change.

    Parameters
    ----------
    ctx : commands.Context[Tux]
        The context of the command.
    name : str
        The name of the snippet to lock or unlock.
    """
    assert ctx.guild

    # Fetch the snippet, send error if not found
    snippet = await self._get_snippet_or_error(ctx, name)
    if not snippet:
        return

    # Toggle the lock status in the database
    try:
        status = await self.db.snippet.toggle_snippet_lock_by_id(snippet.snippet_id)
    except Exception as e:
        logger.error(f"Failed to toggle lock for snippet '{name}' (ID: {snippet.snippet_id}): {e}")
        await self.send_snippet_error(
            ctx,
            "An error occurred while trying to toggle the snippet lock. Please try again later.",
        )
        return
    else:  # Proceed only if try block succeeded
        if status is None:  # Should not happen if try succeeded, but added for safety/linter
            logger.error(
                f"Toggle lock for snippet '{name}' (ID: {snippet.snippet_id}) succeeded but returned None status.",
            )
            await self.send_snippet_error(
                ctx,
                "An unexpected issue occurred while toggling the snippet lock.",
            )
            return

        # Confirmation and logging
        lock_status_text = "locked" if status.locked else "unlocked"
        await ctx.send(
_create_snippets_list_embed(ctx: commands.Context[Tux], snippets: list[Snippet], total_snippets: int, search_query: str | None = None) -> discord.Embed

Create an embed for displaying a paginated list of snippets.

Parameters:

Name Type Description Default
ctx Context[Tux]

The context object.

required
snippets list[Snippet]

The list of snippets for the current page.

required
total_snippets int

The total number of snippets matching the query.

required
search_query str | None

The search query used, if any.

None

Returns:

Type Description
Embed

The generated embed.

Source code in tux/cogs/snippets/toggle_snippet_lock.py
Python
                delete_after=CONST.DEFAULT_DELETE_AFTER,
                ephemeral=True,
            )
            logger.info(f"{ctx.author} {lock_status_text} snippet '{name}'.")

            # Attempt to notify the author via DM
            if author := self.bot.get_user(snippet.snippet_user_id):
                dm_message = (
                    f"Your snippet `{snippet.snippet_name}` in server `{ctx.guild.name}` has been {lock_status_text}.\n\n"
                    f"**What does this mean?**\n"
                    f"If a snippet is locked, it cannot be edited or deleted by anyone other than moderators (like you perhaps!). "
                    f"If unlocked, the original author can modify it again.\n\n"
                    f"**Why?**\n"
                    f"Snippets might be locked/unlocked by moderators for various reasons, often related to server utility or content stability. "
                    f"If you believe this was done in error, please contact the server staff."
                )
                with contextlib.suppress(discord.Forbidden, discord.HTTPException):  # Catch potential DM errors
                    await author.send(dm_message)
                    logger.debug(f"Sent lock status DM to snippet author {author} for snippet '{name}'.")


async def setup(bot: Tux) -> None:
    """Load the ToggleSnippetLock cog."""
    await bot.add_cog(ToggleSnippetLock(bot))
check_if_user_has_mod_override(ctx: commands.Context[Tux]) -> bool async

Check if the user invoking the command has moderator permissions (PL >= configured level).

snippet_check(ctx: commands.Context[Tux], snippet_locked: bool = False, snippet_user_id: int = 0) -> tuple[bool, str] async

Check if a user is allowed to modify or delete a snippet.

Checks for moderator override, snippet bans, role restrictions, snippet lock status, and snippet ownership.

Parameters:

Name Type Description Default
ctx Context[Tux]

The context object.

required
snippet_locked bool

Whether the snippet is locked. Checked only if True. Defaults to False.

False
snippet_user_id int

The ID of the snippet's author. Checked only if non-zero. Defaults to 0.

0

Returns:

Type Description
tuple[bool, str]

A tuple containing a boolean indicating permission status and a reason string.

_get_snippet_or_error(ctx: commands.Context[Tux], name: str) -> Snippet | None async

Fetch a snippet by name and guild, sending an error embed if not found.

Parameters:

Name Type Description Default
ctx Context[Tux]

The context object.

required
name str

The name of the snippet to fetch.

required

Returns:

Type Description
Snippet | None

The fetched Snippet object, or None if not found.

send_snippet_error(ctx: commands.Context[Tux], description: str) -> None async

Send a standardized snippet error embed.

Parameters:

Name Type Description Default
ctx Context[Tux]

The context object.

required
description str

The error message description.

required

Functions

setup(bot: Tux) -> None async

Load the ToggleSnippetLock cog.

Source code in tux/cogs/snippets/toggle_snippet_lock.py
Python
async def setup(bot: Tux) -> None:
    """Load the ToggleSnippetLock cog."""
    await bot.add_cog(ToggleSnippetLock(bot))