From 22baec434d121ac6f5fc86fda5cd9a001ba24c27 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 5 Jun 2025 21:40:58 +0000 Subject: [PATCH] Restore logging view components --- cogs/logging_cog.py | 113 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 23 deletions(-) diff --git a/cogs/logging_cog.py b/cogs/logging_cog.py index 13299b2..1c83276 100644 --- a/cogs/logging_cog.py +++ b/cogs/logging_cog.py @@ -1,5 +1,6 @@ import discord from discord.ext import commands, tasks +from discord import ui import datetime import asyncio import aiohttp # Added for webhook sending @@ -54,6 +55,78 @@ class LoggingCog(commands.Cog): else: asyncio.create_task(self.start_audit_log_poller_when_ready()) # Keep this for initial start + class LogView(ui.LayoutView): + """Simple view for log messages with helper methods.""" + + def __init__( + self, + bot: commands.Bot, + title: str, + description: str, + color: discord.Color, + author: Optional[discord.abc.User], + footer: Optional[str], + ): + super().__init__(timeout=None) + self.container = ui.Container(accent_colour=color) + self.add_item(self.container) + + self.header = ui.Section( + accessory=( + ui.Thumbnail(media=author.display_avatar.url) + if author + else ui.Button(label="\u200b", disabled=True) + ) + ) + self.header.add_item(ui.TextDisplay(f"**{title}**")) + if description: + self.header.add_item(ui.TextDisplay(description)) + self.container.add_item(self.header) + + # Placeholder for future field sections. They are inserted before + # the separator when the first field is added. + self._field_sections: list[ui.Section] = [] + + self.separator = ui.Separator(spacing=discord.SeparatorSpacing.small) + + footer_text = footer or f"Bot ID: {bot.user.id}" + ( + f" | User ID: {author.id}" if author else "" + ) + self.footer_display = ui.TextDisplay(footer_text) + + self.container.add_item(self.separator) + self.container.add_item(self.footer_display) + + # --- Compatibility helpers --- + def add_field(self, name: str, value: str, inline: bool = False): + """Mimic Embed.add_field by appending a bolded name/value line.""" + if not self._field_sections or len(self._field_sections[-1].children) >= 3: + section = ui.Section(accessory=ui.Button(label="\u200b", disabled=True)) + self._insert_field_section(section) + self._field_sections.append(section) + self._field_sections[-1].add_item(ui.TextDisplay(f"**{name}:** {value}")) + + def _insert_field_section(self, section: ui.Section) -> None: + """Insert a field section before the footer separator.""" + self.container.remove_item(self.separator) + self.container.remove_item(self.footer_display) + self.container.add_item(section) + self.container.add_item(self.separator) + self.container.add_item(self.footer_display) + + def set_footer(self, text: str): + """Mimic Embed.set_footer by replacing the footer text display.""" + self.footer_display.content = text + + def set_author(self, name: str, icon_url: Optional[str] = None): + """Mimic Embed.set_author by adjusting the header section.""" + self.header.clear_items() + if icon_url: + self.header.accessory = ui.Thumbnail(media=icon_url) + else: + self.header.accessory = ui.Button(label="\u200b", disabled=True) + self.header.add_item(ui.TextDisplay(name)) + def _user_display(self, user: Union[discord.Member, discord.User]) -> str: """Return display name, username and ID string for a user.""" display = user.display_name if isinstance(user, discord.Member) else user.name @@ -109,8 +182,8 @@ class LoggingCog(commands.Cog): await self.session.close() log.info("aiohttp ClientSession closed for LoggingCog.") - async def _send_log_embed(self, guild: discord.Guild, embed: discord.Embed) -> None: - """Sends the log embed via the configured webhook for the guild.""" + async def _send_log_embed(self, guild: discord.Guild, embed: ui.LayoutView) -> None: + """Sends the log view via the configured webhook for the guild.""" if not self.session or self.session.closed: log.error(f"aiohttp session not available or closed in LoggingCog for guild {guild.id}. Cannot send log.") return @@ -122,9 +195,13 @@ class LoggingCog(commands.Cog): return try: - webhook = discord.Webhook.from_url(webhook_url, session=self.session) + webhook = discord.Webhook.from_url( + webhook_url, + session=self.session, + client=self.bot, + ) await webhook.send( - embed=embed, + view=embed, username=f"{self.bot.user.name} Logs", avatar_url=self.bot.user.display_avatar.url, ) @@ -152,23 +229,13 @@ class LoggingCog(commands.Cog): color: discord.Color = discord.Color.blue(), author: Optional[Union[discord.User, discord.Member]] = None, footer: Optional[str] = None, - ) -> discord.Embed: - """Creates a standardized embed for logging.""" - embed = discord.Embed(title=title, description=description, color=color) - if author: - embed.set_author(name=author.display_name, icon_url=author.display_avatar.url) - if footer: - embed.set_footer(text=footer) - else: - footer_text = f"Bot ID: {self.bot.user.id}" - if author: - footer_text += f" | User ID: {author.id}" - embed.set_footer(text=footer_text) - return embed + ) -> ui.LayoutView: + """Creates a standardized log view.""" + return self.LogView(self.bot, title, description, color, author, footer) def _add_id_footer( self, - embed: discord.Embed, + embed: ui.LayoutView, obj: Union[ discord.Member, discord.User, @@ -183,10 +250,10 @@ class LoggingCog(commands.Cog): ) -> None: """Adds an ID to the footer text if possible.""" target_id = obj_id or (obj.id if obj else None) - if target_id: - existing_footer = embed.footer.text if embed.footer else "" + if target_id and hasattr(embed, "footer_display"): + existing_footer = embed.footer_display.content or "" separator = " | " if existing_footer else "" - embed.set_footer(text=f"{existing_footer}{separator}{id_name}: {target_id}") + embed.footer_display.content = f"{existing_footer}{separator}{id_name}: {target_id}" async def _check_log_enabled(self, guild_id: int, event_key: str) -> bool: """Checks if logging is enabled for a specific event key in a guild.""" @@ -271,13 +338,13 @@ class LoggingCog(commands.Cog): await ctx.send(f"✅ Successfully configured logging to send messages to {channel.mention} via the new webhook `{new_webhook.name}`.") # Test send (optional) try: - test_embed = self._create_log_embed( + test_view = self._create_log_embed( "✅ Logging Setup Complete", f"Logs will now be sent to this channel via the webhook `{new_webhook.name}`.", color=discord.Color.green(), ) await new_webhook.send( - embed=test_embed, + view=test_view, username=webhook_name, avatar_url=self.bot.user.display_avatar.url, )