diff options
-rw-r--r-- | arthur/config.py | 1 | ||||
-rw-r--r-- | arthur/exts/kubernetes/pods.py | 53 | ||||
-rw-r--r-- | arthur/pagination.py | 63 | ||||
-rw-r--r-- | pyproject.toml | 2 |
4 files changed, 93 insertions, 26 deletions
diff --git a/arthur/config.py b/arthur/config.py index 146db73..bb88838 100644 --- a/arthur/config.py +++ b/arthur/config.py @@ -27,6 +27,7 @@ class Config( guild_id: int = 267624335836053506 devops_channel_id: int = 675756741417369640 sentry_dsn: str = "" + trashcan: str = "<:trashcan:637136429717389331>" GIT_SHA = environ.get("GIT_SHA", "development") diff --git a/arthur/exts/kubernetes/pods.py b/arthur/exts/kubernetes/pods.py index 0a82fb9..bab3f79 100644 --- a/arthur/exts/kubernetes/pods.py +++ b/arthur/exts/kubernetes/pods.py @@ -3,6 +3,7 @@ import zoneinfo from datetime import datetime +import discord import humanize from discord.ext import commands from kubernetes_asyncio.client.rest import ApiException @@ -12,6 +13,7 @@ from tabulate import tabulate from arthur.apis.kubernetes import pods from arthur.bot import KingArthur from arthur.config import CONFIG +from arthur.pagination import LinePaginator from arthur.utils import generate_error_message MAX_MESSAGE_LENGTH = 2000 @@ -46,9 +48,10 @@ class Pods(commands.Cog): pod_list = await pods.list_pods(namespace) if len(pod_list.items) == 0: - return await ctx.send( + await ctx.send( generate_error_message(description="No pods found, check the namespace exists.") ) + return tables = [[]] @@ -95,7 +98,7 @@ class Pods(commands.Cog): for table in tables: await ctx.send(tabulate_pod_data(table)) - return None + return @pods_cmd.command(name="logs", aliases=["log", "tail"]) @commands.check(lambda ctx: ctx.channel.id == CONFIG.devops_channel_id) @@ -116,46 +119,46 @@ class Pods(commands.Cog): pod_names = [pod_name] if pod_names is None: - return await ctx.send( + await ctx.send( generate_error_message(description="No pods found for the provided deployment.") ) + return for pod in pod_names: try: logs = await pods.tail_pod(namespace, pod, lines=lines) except ApiException as e: if e.status == 404: # noqa: PLR2004, 404 is a known error - return await ctx.send( + await ctx.send( generate_error_message( description="Pod or namespace not found, check the name." ) ) - return await ctx.send(generate_error_message(description=str(e))) + return + await ctx.send(generate_error_message(description=str(e))) + return if len(logs) == 0: - return await ctx.send( - generate_error_message(description="No logs found for the pod.") - ) + await ctx.send(generate_error_message(description="No logs found for the pod.")) + return - truncated = False + logs = logs.splitlines() - if len(logs) > MAX_MESSAGE_LENGTH - 100: - truncated = True - while len(logs) > MAX_MESSAGE_LENGTH - 100: - logs = logs[: logs.rfind("\n")] - - message = f"**Logs for pod `{pod}` in namespace `{namespace}`**\n" - - if truncated: - message += "`[Logs truncated]`\n" - - message += "```" - message += logs - message += "```" - - await ctx.send(message) + logs_embed = discord.Embed( + title=f"**Logs for pod `{pod}` in namespace `{namespace}`**", + colour=discord.Colour.blue(), + ) + await LinePaginator.paginate( + lines=logs, + ctx=ctx, + max_size=MAX_MESSAGE_LENGTH, + empty=False, + embed=logs_embed, + prefix="```\n", + suffix="```", + ) - return None + return async def setup(bot: KingArthur) -> None: diff --git a/arthur/pagination.py b/arthur/pagination.py new file mode 100644 index 0000000..8db0ade --- /dev/null +++ b/arthur/pagination.py @@ -0,0 +1,63 @@ +from collections.abc import Sequence + +import discord +from discord.ext.commands import Context +from pydis_core.utils.pagination import LinePaginator as _LinePaginator, PaginationEmojis + +from arthur.config import CONFIG + + +class LinePaginator(_LinePaginator): + """ + A class that aids in paginating code blocks for Discord messages. + + See the super class's docs for more info. + """ + + @classmethod + async def paginate( + cls, + lines: list[str], + ctx: Context | discord.Interaction, + embed: discord.Embed, + prefix: str = "", + suffix: str = "", + max_lines: int | None = None, + max_size: int = 500, + scale_to_size: int = 4000, + restrict_to_user: discord.User | None = None, + timeout: int = 300, + footer_text: str | None = None, + url: str | None = None, + allowed_roles: Sequence[int] | None = None, + *, + reply: bool = False, + empty: bool = True, + exception_on_empty_embed: bool = False, + ) -> discord.Message | None: + """ + Use a paginator and set of reactions to provide pagination over a set of lines. + + Acts as a wrapper for the super class' `paginate` method to provide the pagination emojis by default. + + Consult the super class's `paginate` method for detailed information. + """ + return await super().paginate( + pagination_emojis=PaginationEmojis(delete=CONFIG.trashcan), + lines=lines, + ctx=ctx, + embed=embed, + prefix=prefix, + suffix=suffix, + max_lines=max_lines, + max_size=max_size, + scale_to_size=scale_to_size, + empty=empty, + restrict_to_user=restrict_to_user, + timeout=timeout, + footer_text=footer_text, + url=url, + exception_on_empty_embed=exception_on_empty_embed, + reply=reply, + allowed_roles=allowed_roles, + ) diff --git a/pyproject.toml b/pyproject.toml index ffa79cd..b5653b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,7 @@ ignore = [ "S311", "SIM102", "SIM108", "PD", - "PLR6301", + "PLR0913", "PLR0917", "PLR6301", # Rules suggested to be ignored when using ruff format "COM812", "D206", "E111", "E114", "E117", "E501", "ISC001", "Q000", "Q001", "Q002", "Q003", "W191", |