From 52fe9c61a71859ffc15c634324a77e75c085833e Mon Sep 17 00:00:00 2001 From: petabyte-imo Date: Sat, 7 Sep 2024 17:06:05 +0100 Subject: [PATCH 1/7] Replaced all discord.Embed to start using tux.ui.embeds EmbedCreator --- tux/cogs/guild/config.py | 35 +++++++----- tux/cogs/info/info.py | 5 +- tux/cogs/moderation/__init__.py | 9 ++- tux/cogs/moderation/cases.py | 16 +++--- tux/cogs/services/starboard.py | 11 ++-- tux/cogs/utility/snippets.py | 98 +++++++++++++++++++-------------- tux/cogs/utility/timezones.py | 7 ++- tux/handlers/event.py | 4 +- tux/ui/embeds.py | 15 +++-- 9 files changed, 123 insertions(+), 77 deletions(-) diff --git a/tux/cogs/guild/config.py b/tux/cogs/guild/config.py index d3a9fe17..a2679e0c 100644 --- a/tux/cogs/guild/config.py +++ b/tux/cogs/guild/config.py @@ -6,10 +6,11 @@ from tux.bot import Tux from tux.database.controllers import DatabaseController -from tux.ui.embeds import EmbedCreator +from tux.ui.embeds import EmbedCreator, EmbedType from tux.ui.views.config import ConfigSetChannels, ConfigSetPrivateLogs, ConfigSetPublicLogs from tux.utils.constants import CONST + # TODO: Add onboarding setup to ensure all required channels, logs, and roles are set up # TODO: Figure out how to handle using our custom checks because the current checks would result in a lock out # TODO: Add a command to reset the guild config to default values @@ -183,10 +184,12 @@ async def config_get_roles( assert interaction.guild - embed = discord.Embed( + + embed = EmbedCreator.create_embed( title="Config - Roles", - color=discord.Color.blue(), - timestamp=discord.utils.utcnow(), + embed_type=EmbedType.INFO, + custom_color=discord.Color.blue(), + message_timestamp=discord.utils.utcnow(), ) jail_role_id = await self.db.get_jail_role_id(interaction.guild.id) @@ -213,10 +216,12 @@ async def config_get_perms( assert interaction.guild - embed = discord.Embed( + + embed = EmbedCreator.create_embed( + embed_type=EmbedType.INFO, + custom_color=discord.Color.blue(), title="Config - Permission Level Roles", - color=discord.Color.blue(), - timestamp=discord.utils.utcnow(), + message_timestamp=discord.utils.utcnow(), ) for i in range(8): @@ -245,10 +250,12 @@ async def config_get_channels( assert interaction.guild - embed = discord.Embed( + + embed = EmbedCreator.create_embed( title="Config - Channels", - color=discord.Color.blue(), - timestamp=discord.utils.utcnow(), + embed_type=EmbedType.INFO, + custom_color=discord.Color.blue(), + message_timestamp=discord.utils.utcnow(), ) jail_channel_id = await self.db.get_jail_channel_id(interaction.guild.id) @@ -283,10 +290,12 @@ async def config_get_logs( assert interaction.guild - embed = discord.Embed( + + embed = EmbedCreator.create_embed( title="Config - Logs", - color=discord.Color.blue(), - timestamp=discord.utils.utcnow(), + embed_type=EmbedType.INFO, + custom_color=discord.Color.blue(), + message_timestamp=discord.utils.utcnow(), ) join_log_id = await self.db.get_join_log_id(interaction.guild.id) diff --git a/tux/cogs/info/info.py b/tux/cogs/info/info.py index 6ab1ef50..ed320bb5 100644 --- a/tux/cogs/info/info.py +++ b/tux/cogs/info/info.py @@ -5,6 +5,7 @@ from reactionmenu import ViewButton, ViewMenu from tux.bot import Tux +from tux.ui.embeds import EmbedCreator, EmbedType class Info(commands.Cog): @@ -166,7 +167,9 @@ async def paginated_embed( chunk_size : int The size of each chunk for pagination. """ - embed: discord.Embed = discord.Embed(title=title, color=discord.Color.blurple()) + embed: discord.Embed = EmbedCreator.create_embed( + embed_type=EmbedType.INFO, title=title, custom_color=discord.Color.blurple() + ) chunks: list[list[str]] = list(self._chunks(iter(items), chunk_size)) if not chunks: diff --git a/tux/cogs/moderation/__init__.py b/tux/cogs/moderation/__init__.py index acc12975..9c45ac68 100644 --- a/tux/cogs/moderation/__init__.py +++ b/tux/cogs/moderation/__init__.py @@ -7,7 +7,7 @@ from prisma.enums import CaseType from tux.bot import Tux from tux.database.controllers import DatabaseController -from tux.ui.embeds import EmbedCreator +from tux.ui.embeds import EmbedCreator, EmbedType from tux.utils.constants import Constants as CONST @@ -17,6 +17,7 @@ def __init__(self, bot: Tux) -> None: self.db = DatabaseController() self.config = DatabaseController().guild_config + #TODO: Get rid of create_embed in the ModerationCogBase command as its only being used once and is replacable def create_embed( self, ctx: commands.Context[Tux], @@ -51,7 +52,11 @@ def create_embed( The embed for the moderation action. """ - embed = discord.Embed(color=color, timestamp=timestamp or ctx.message.created_at) + embed = EmbedCreator.create_embed( + embed_type=EmbedType.INFO, + custom_color=color, + message_timestamp=timestamp or ctx.message.created_at, + ) embed.set_author(name=title, icon_url=icon_url) embed.set_thumbnail(url=thumbnail_url) diff --git a/tux/cogs/moderation/cases.py b/tux/cogs/moderation/cases.py index 26d66f82..21d81313 100644 --- a/tux/cogs/moderation/cases.py +++ b/tux/cogs/moderation/cases.py @@ -6,7 +6,7 @@ from prisma.models import Case from prisma.types import CaseWhereInput from tux.bot import Tux -from tux.ui.embeds import EmbedCreator +from tux.ui.embeds import EmbedCreator, EmbedType from tux.utils import checks from tux.utils.constants import Constants as CONST from tux.utils.flags import CaseModifyFlags, CasesViewFlags, generate_usage @@ -276,10 +276,11 @@ async def _handle_case_response( ) embed.set_thumbnail(url=user.avatar) else: - embed = discord.Embed( + + embed = EmbedCreator.create_embed( + embed_type=EmbedType.ERROR, title=f"Case {action}", description="Failed to find case.", - color=CONST.EMBED_COLORS["ERROR"], ) await ctx.send(embed=embed, delete_after=30, ephemeral=True) @@ -293,10 +294,10 @@ async def _handle_case_list_response( menu = ViewMenu(ctx, menu_type=ViewMenu.TypeEmbed, all_can_click=True, delete_on_timeout=True) if not cases: - embed = discord.Embed( + embed = EmbedCreator.create_embed( + embed_type=EmbedType.ERROR, title="Cases", description="No cases found.", - color=CONST.EMBED_COLORS["ERROR"], ) await ctx.send(embed=embed, delete_after=30, ephemeral=True) return @@ -337,10 +338,11 @@ def _create_case_list_embed( cases: list[Case], total_cases: int, ) -> discord.Embed: - embed = discord.Embed( + + embed = EmbedCreator.create_embed( title=f"Total Cases ({total_cases})", description="", - color=CONST.EMBED_COLORS["CASE"], + embed_type=EmbedType.CASE, ) if ctx.guild: diff --git a/tux/cogs/services/starboard.py b/tux/cogs/services/starboard.py index 7d05c27a..60df8ca7 100644 --- a/tux/cogs/services/starboard.py +++ b/tux/cogs/services/starboard.py @@ -6,7 +6,7 @@ from tux.bot import Tux from tux.database.controllers.starboard import StarboardController, StarboardMessageController -from tux.ui.embeds import EmbedCreator +from tux.ui.embeds import EmbedCreator, EmbedType from tux.utils import checks @@ -263,11 +263,12 @@ async def create_or_update_starboard_message( if not starboard: return - embed = discord.Embed( - description=original_message.content, - color=discord.Color.gold(), - timestamp=original_message.created_at, + embed = EmbedCreator.create_embed( + embed_type=EmbedType.INFO, + custom_color=discord.Color.gold(), + message_timestamp=original_message.created_at, ) + embed.set_author( name=original_message.author.display_name, icon_url=original_message.author.avatar.url if original_message.author.avatar else None, diff --git a/tux/cogs/utility/snippets.py b/tux/cogs/utility/snippets.py index 9011a822..5843e57e 100644 --- a/tux/cogs/utility/snippets.py +++ b/tux/cogs/utility/snippets.py @@ -12,9 +12,8 @@ from prisma.models import Snippet from tux.bot import Tux from tux.database.controllers import CaseController, DatabaseController -from tux.ui.embeds import EmbedCreator +from tux.ui.embeds import EmbedCreator, EmbedType from tux.utils import checks -from tux.utils.constants import Constants as CONST class Snippets(commands.Cog): @@ -56,16 +55,9 @@ async def list_snippets(self, ctx: commands.Context[Tux]) -> None: # Remove snippets that are not in the current server snippets = [snippet for snippet in snippets if snippet.guild_id == ctx.guild.id] - # If there are no snippets, send an error message - if not snippets: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="No snippets found.", - ) - await ctx.send(embed=embed, delete_after=30) + # If there are no snippets, return + no_snippets = await self.no_snippets_found(ctx, snippets) + if no_snippets: return menu = ViewMenu(ctx, menu_type=ViewMenu.TypeEmbed) @@ -89,22 +81,9 @@ def _create_snippets_list_embed( snippets: list[Snippet], total_snippets: int, ) -> discord.Embed: - embed = discord.Embed( - title=f"Total Snippets ({total_snippets})", - description="", - color=CONST.EMBED_COLORS["DEFAULT"], - ) - - if ctx.guild: - embed.set_author(name=ctx.guild.name, icon_url=ctx.guild.icon) - footer_text, footer_icon_url = EmbedCreator.get_footer( - bot=ctx.bot, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - ) - embed.set_footer(text=footer_text, icon_url=footer_icon_url) - embed.timestamp = ctx.message.created_at + assert ctx.guild + assert ctx.guild.icon description = "```\n" @@ -114,9 +93,22 @@ def _create_snippets_list_embed( description += "```" - embed.description = description + footer_text, footer_icon_url = EmbedCreator.get_footer( + bot=ctx.bot, + user_name=ctx.author.name, + user_display_avatar=ctx.author.display_avatar.url, + ) - return embed + return EmbedCreator.create_embed( + embed_type=EmbedType.DEFAULT, + title=f"Total Snippets ({total_snippets})", + description=description, + custom_author_text=ctx.guild.name, + custom_author_icon_url=ctx.guild.icon.url, + message_timestamp=ctx.message.created_at, + custom_footer_text=footer_text, + custom_footer_icon_url=footer_icon_url, + ) @commands.command( name="topsnippets", @@ -138,16 +130,9 @@ async def top_snippets(self, ctx: commands.Context[Tux]) -> None: # find the top 10 snippets by uses snippets: list[Snippet] = await self.db.get_all_snippets_by_guild_id(ctx.guild.id) - # If there are no snippets, send an error message - if not snippets: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="No snippets found.", - ) - await ctx.send(embed=embed, delete_after=30) + # If there are no snippets, return + no_snippets = await self.no_snippets_found(ctx, snippets) + if no_snippets: return # sort the snippets by uses @@ -165,10 +150,11 @@ async def top_snippets(self, ctx: commands.Context[Tux]) -> None: text += "```" # only show top 10, no pagination - embed = discord.Embed( + embed = EmbedCreator.create_embed( + embed_type=EmbedType.DEFAULT, title="Top Snippets", description=text, - color=CONST.EMBED_COLORS["DEFAULT"], + hide_author=True, ) await ctx.send(embed=embed) @@ -626,6 +612,36 @@ async def toggle_snippet_lock(self, ctx: commands.Context[Tux], name: str) -> No await ctx.send("Snippet lock toggled.", delete_after=30, ephemeral=True) logger.info(f"{ctx.author} toggled the lock of the snippet with the name {name}.") + async def no_snippets_found(self, ctx: commands.Context[Tux], snippets: list[Snippet]) -> bool: + """ + Check if there are no snippets found. + + Parameters + ---------- + ctx : commands.Context[Tux] + The context object. + snippets : list[Snippet] + The list of snippets. + + Returns + ------- + True + If there are no snippets found. + And sends an error message to the channel. + False + If there are snippets found. + """ + if not snippets: + embed = EmbedCreator.create_embed( + bot=self.bot, + embed_type=EmbedCreator.ERROR, + user_name=ctx.author.name, + user_display_avatar=ctx.author.display_avatar.url, + description="No snippets found.", + ) + await ctx.send(embed=embed, delete_after=30) + return True + return False async def setup(bot: Tux) -> None: await bot.add_cog(Snippets(bot)) diff --git a/tux/cogs/utility/timezones.py b/tux/cogs/utility/timezones.py index 166840b4..dc3df023 100644 --- a/tux/cogs/utility/timezones.py +++ b/tux/cogs/utility/timezones.py @@ -6,6 +6,7 @@ from reactionmenu import Page, ViewButton, ViewMenu, ViewSelect from tux.bot import Tux +from tux.ui.embeds import EmbedCreator, EmbedType timezones = { "North America": [ @@ -108,7 +109,11 @@ async def timezones(self, ctx: commands.Context[Tux]) -> None: pages = [tz_list[i : i + 9] for i in range(0, len(tz_list), 9)] for page in pages: - embed = discord.Embed(title=f"Timezones in {continent}", color=discord.Color.blurple()) + embed = EmbedCreator.create_embed( + embed_type=EmbedType.INFO, + title=f"Timezones in {continent}", + custom_color=discord.Color.blurple(), + ) for flag, _country, tz_name, abbr, utc_offset in page: tz = pytz.timezone(tz_name) diff --git a/tux/handlers/event.py b/tux/handlers/event.py index c64204d6..00b8f7c6 100644 --- a/tux/handlers/event.py +++ b/tux/handlers/event.py @@ -4,6 +4,7 @@ from tux.bot import Tux from tux.database.controllers import DatabaseController from tux.utils.functions import is_harmful, strip_formatting +from tux.ui.embeds import EmbedCreator, EmbedType class EventHandler(commands.Cog): @@ -87,7 +88,8 @@ async def on_thread_create(self, thread: discord.Thread) -> None: else: msg = f"<:tux_notify:1274504953666474025> **New support thread created** - help is appreciated!\n{thread.mention} by {owner_mention}" - embed = discord.Embed(description=msg, color=discord.Color.random()) + embed = EmbedCreator.create_embed(embed_type=EmbedType.INFO, description=msg, custom_color=discord.Color.random(), hide_author=True) + general_chat = 1172245377395728467 channel = self.bot.get_channel(general_chat) diff --git a/tux/ui/embeds.py b/tux/ui/embeds.py index e52852c8..24d84755 100644 --- a/tux/ui/embeds.py +++ b/tux/ui/embeds.py @@ -44,7 +44,8 @@ def create_embed( custom_footer_icon_url: str | None = None, custom_author_text: str | None = None, custom_author_icon_url: str | None = None, - custom_color: int | None = None, + hide_author: bool = False, + custom_color: int | discord.Colour | None = None, ) -> discord.Embed: """ Create a customized Discord embed based on the specified type and parameters. @@ -63,7 +64,8 @@ def create_embed( custom_footer_icon_url (str | None): Overrides default footer icon if provided. custom_author_text (str | None): Overrides default author text if provided. custom_author_icon_url (str | None): Overrides default author icon if provided. - custom_color (int | None): Overrides default color for the embed type if provided. + hide_author (bool): If True, removes the author from the embed. + custom_color (int | Colour |None): Overrides default color for the embed type if provided. Note: Custom parameters (prefixed with 'custom_') override default values. @@ -84,10 +86,11 @@ def create_embed( embed.color = custom_color or type_settings[embed_type][0] - embed.set_author( - name=custom_author_text or type_settings[embed_type][2], - icon_url=custom_author_icon_url or type_settings[embed_type][1], - ) + if not hide_author: + embed.set_author( + name=custom_author_text or type_settings[embed_type][2], + icon_url=custom_author_icon_url or type_settings[embed_type][1], + ) if custom_footer_text: embed.set_footer(text=custom_footer_text, icon_url=custom_footer_icon_url) From 0a1025098652eceb04ab68b0b56d7ef8cb88b6ed Mon Sep 17 00:00:00 2001 From: petabyte-imo Date: Sat, 7 Sep 2024 18:29:52 +0100 Subject: [PATCH 2/7] Changed up some embeds to use the embed creator's arguments instead of methods, and also removed code repetition in snippets.py --- tux/cogs/fun/fact.py | 15 ++- tux/cogs/fun/xkcd.py | 4 +- tux/cogs/moderation/__init__.py | 19 +-- tux/cogs/moderation/cases.py | 22 ++-- tux/cogs/services/starboard.py | 12 +- tux/cogs/utility/query.py | 7 +- tux/cogs/utility/snippets.py | 198 ++++++-------------------------- tux/ui/embeds.py | 3 + tux/utils/exports.py | 7 +- 9 files changed, 75 insertions(+), 212 deletions(-) diff --git a/tux/cogs/fun/fact.py b/tux/cogs/fun/fact.py index 8c635dc5..12b135c3 100644 --- a/tux/cogs/fun/fact.py +++ b/tux/cogs/fun/fact.py @@ -53,14 +53,17 @@ async def fact(self, ctx: commands.Context[Tux]) -> None: user_display_avatar=ctx.author.display_avatar.url, title="Fun Fact", description=random.choice(self.facts), + custom_author_text="Click here to submit more facts here!", + custom_author_text_url="https://github.com/allthingslinux/tux/blob/main/tux/cogs/fun/fact.py", + custom_author_icon_url="https://github.com/allthingslinux/tux/blob/main/assets/emojis/tux_info.png?raw=true", ) - # set author - embed.set_author( - name="Submit more facts here!", - url="https://github.com/allthingslinux/tux/blob/main/tux/cogs/fun/fact.py", - icon_url="https://github.com/allthingslinux/tux/blob/main/assets/emojis/tux_info.png?raw=true", - ) + # # set author + # embed.set_author( + # name="Submit more facts here!", + # url="https://github.com/allthingslinux/tux/blob/main/tux/cogs/fun/fact.py", + # icon_url="https://github.com/allthingslinux/tux/blob/main/assets/emojis/tux_info.png?raw=true", + # ) await ctx.send(embed=embed) diff --git a/tux/cogs/fun/xkcd.py b/tux/cogs/fun/xkcd.py index 5d8740f9..f229d238 100644 --- a/tux/cogs/fun/xkcd.py +++ b/tux/cogs/fun/xkcd.py @@ -128,10 +128,10 @@ async def get_comic_and_embed( embed_type=EmbedCreator.INFO, title="", description=f"\n\n> {comic.description.strip()}" if comic.description else "", + custom_author_text=f"xkcd {comic.id} - {comic.title}", + image_url=comic.image_url, ) - embed.set_author(name=f"xkcd {comic.id} - {comic.title}") - embed.set_image(url=comic.image_url) ephemeral = False except xkcd.HttpError: diff --git a/tux/cogs/moderation/__init__.py b/tux/cogs/moderation/__init__.py index 9c45ac68..19cacd48 100644 --- a/tux/cogs/moderation/__init__.py +++ b/tux/cogs/moderation/__init__.py @@ -51,21 +51,22 @@ def create_embed( discord.Embed The embed for the moderation action. """ + footer_text, footer_icon_url = EmbedCreator.get_footer( + bot=self.bot, + user_name=ctx.author.name, + user_display_avatar=ctx.author.display_avatar.url, + ) embed = EmbedCreator.create_embed( embed_type=EmbedType.INFO, custom_color=color, message_timestamp=timestamp or ctx.message.created_at, + custom_author_text=title, + custom_author_icon_url=icon_url, + thumbnail_url=thumbnail_url, + custom_footer_text=footer_text, + custom_footer_icon_url=footer_icon_url, ) - embed.set_author(name=title, icon_url=icon_url) - embed.set_thumbnail(url=thumbnail_url) - - footer_text, footer_icon_url = EmbedCreator.get_footer( - bot=self.bot, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - ) - embed.set_footer(text=footer_text, icon_url=footer_icon_url) for name, value, inline in fields: embed.add_field(name=name, value=value, inline=inline) diff --git a/tux/cogs/moderation/cases.py b/tux/cogs/moderation/cases.py index 21d81313..14fca607 100644 --- a/tux/cogs/moderation/cases.py +++ b/tux/cogs/moderation/cases.py @@ -338,22 +338,24 @@ def _create_case_list_embed( cases: list[Case], total_cases: int, ) -> discord.Embed: - - embed = EmbedCreator.create_embed( - title=f"Total Cases ({total_cases})", - description="", - embed_type=EmbedType.CASE, - ) - - if ctx.guild: - embed.set_author(name=ctx.guild.name, icon_url=ctx.guild.icon) + assert ctx.guild + assert ctx.guild.icon footer_text, footer_icon_url = EmbedCreator.get_footer( bot=self.bot, user_name=ctx.author.name, user_display_avatar=ctx.author.display_avatar.url, ) - embed.set_footer(text=footer_text, icon_url=footer_icon_url) + + embed = EmbedCreator.create_embed( + title=f"Total Cases ({total_cases})", + description="", + embed_type=EmbedType.CASE, + custom_author_text=ctx.guild.name, + custom_author_icon_url=ctx.guild.icon.url, + custom_footer_text=footer_text, + custom_footer_icon_url=footer_icon_url, + ) for case in cases: self._add_case_to_embed(embed, case) diff --git a/tux/cogs/services/starboard.py b/tux/cogs/services/starboard.py index 60df8ca7..5c1a7c2e 100644 --- a/tux/cogs/services/starboard.py +++ b/tux/cogs/services/starboard.py @@ -267,17 +267,13 @@ async def create_or_update_starboard_message( embed_type=EmbedType.INFO, custom_color=discord.Color.gold(), message_timestamp=original_message.created_at, + custom_author_text=original_message.author.display_name, + custom_author_icon_url=original_message.author.avatar.url if original_message.author.avatar else None, + custom_footer_text=f"{reaction_count} {starboard.starboard_emoji}", + image_url=original_message.attachments[0].url if original_message.attachments else None, ) - embed.set_author( - name=original_message.author.display_name, - icon_url=original_message.author.avatar.url if original_message.author.avatar else None, - ) embed.add_field(name="Source", value=f"[Jump to message]({original_message.jump_url})") - embed.set_footer(text=f"{reaction_count} {starboard.starboard_emoji}") - - if original_message.attachments: - embed.set_image(url=original_message.attachments[0].url) starboard_message = await self.get_existing_starboard_message(starboard_channel, original_message) diff --git a/tux/cogs/utility/query.py b/tux/cogs/utility/query.py index f84164dd..e5a93d4d 100644 --- a/tux/cogs/utility/query.py +++ b/tux/cogs/utility/query.py @@ -107,6 +107,8 @@ async def query(self, ctx: commands.Context[Tux], *, search_term: str) -> None: user_display_avatar=ctx.author.display_avatar.url, title=f'Answer to "{search_term}"', description=f"{data['Abstract']}\n\nData from **{data['AbstractURL']}**", + custom_footer_text="Data via DuckDuckGo API.", + custom_footer_icon_url="https://duckduckgo.com/favicon.png", ) embed.set_author( @@ -115,11 +117,6 @@ async def query(self, ctx: commands.Context[Tux], *, search_term: str) -> None: icon_url=f"https://duckduckgo.com{data['Image']}" if data["Image"] else CONST.EMBED_ICONS["DEFAULT"], ) - embed.set_footer( - text="Data via DuckDuckGo API.", - icon_url="https://duckduckgo.com/favicon.png", - ) - if redirect: embed.add_field( name="Search Term Changed", diff --git a/tux/cogs/utility/snippets.py b/tux/cogs/utility/snippets.py index 5843e57e..9c41a8c6 100644 --- a/tux/cogs/utility/snippets.py +++ b/tux/cogs/utility/snippets.py @@ -56,10 +56,9 @@ async def list_snippets(self, ctx: commands.Context[Tux]) -> None: snippets = [snippet for snippet in snippets if snippet.guild_id == ctx.guild.id] # If there are no snippets, return - no_snippets = await self.no_snippets_found(ctx, snippets) - if no_snippets: + if not snippets: + await self.send_snippet_error(ctx, description="No snippets found.") return - menu = ViewMenu(ctx, menu_type=ViewMenu.TypeEmbed) snippets_per_page = 10 @@ -131,8 +130,8 @@ async def top_snippets(self, ctx: commands.Context[Tux]) -> None: snippets: list[Snippet] = await self.db.get_all_snippets_by_guild_id(ctx.guild.id) # If there are no snippets, return - no_snippets = await self.no_snippets_found(ctx, snippets) - if no_snippets: + if not snippets: + await self.send_snippet_error(ctx, description="No snippets found.") return # sort the snippets by uses @@ -182,39 +181,18 @@ async def delete_snippet(self, ctx: commands.Context[Tux], name: str) -> None: snippet = await self.db.get_snippet_by_name_and_guild_id(name, ctx.guild.id) if snippet is None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet not found.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Snippet not found.") return # check if the snippet is locked if snippet.locked: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="This snippet is locked and cannot be deleted. If you are a moderator you can use the `forcedeletesnippet` command.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="This snippet is locked and cannot be deleted. If you are a moderator you can use the `forcedeletesnippet` command.") return # Check if the author of the snippet is the same as the user who wants to delete it and if theres no author don't allow deletion author_id = snippet.snippet_user_id or 0 if author_id != ctx.author.id: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="You can only delete your own snippets.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="You can only delete your own snippets.") return await self.db.delete_snippet_by_id(snippet.snippet_id) @@ -246,14 +224,7 @@ async def force_delete_snippet(self, ctx: commands.Context[Tux], name: str) -> N snippet = await self.db.get_snippet_by_name_and_guild_id(name, ctx.guild.id) if snippet is None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet not found.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Snippet not found.") return await self.db.delete_snippet_by_id(snippet.snippet_id) @@ -283,30 +254,13 @@ async def get_snippet(self, ctx: commands.Context[Tux], name: str) -> None: snippet = await self.db.get_snippet_by_name_and_guild_id(name, ctx.guild.id) + # check if the name contains an underscore if "_" in name: - snippet = None # this is a bad fix, but it works for now - if snippet is None and "_" in name: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet not found. Did you mean to use `-` instead of `_`? Due to a recent change, `_` is no longer allowed in snippet names.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Did you mean to use `-` instead of `_`? Due to a recent change, `_` is no longer allowed in snippet names.") return if snippet is None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet not found.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="No snippets found.") return - - # increment the usage count of the snippet await self.db.increment_snippet_uses(snippet.snippet_id) # example text: @@ -341,14 +295,7 @@ async def get_snippet_info(self, ctx: commands.Context[Tux], name: str) -> None: snippet = await self.db.get_snippet_by_name_and_guild_id(name, ctx.guild.id) if snippet is None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet not found.", - ) - await ctx.send(embed=embed, delete_after=30) + await self.send_snippet_error(ctx, description="Snippet not found.") return author = self.bot.get_user(snippet.snippet_user_id) @@ -359,6 +306,7 @@ async def get_snippet_info(self, ctx: commands.Context[Tux], name: str) -> None: user_name=ctx.author.name, user_display_avatar=ctx.author.display_avatar.url, title="Snippet Information", + message_timestamp=snippet.snippet_created_at or datetime.datetime.fromtimestamp(0,datetime.UTC) ) embed.add_field(name="Name", value=snippet.snippet_name, inline=False) @@ -371,11 +319,6 @@ async def get_snippet_info(self, ctx: commands.Context[Tux], name: str) -> None: embed.add_field(name="Uses", value=snippet.uses, inline=False) embed.add_field(name="Locked", value="Yes" if snippet.locked else "No", inline=False) - embed.timestamp = snippet.snippet_created_at or datetime.datetime.fromtimestamp( - 0, - datetime.UTC, - ) - await ctx.send(embed=embed) @commands.command( @@ -404,14 +347,7 @@ async def create_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: args = arg.split(" ") if len(args) < 2: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Please provide a name and content for the snippet.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Please provide a name and content for the snippet.") return name = args[0] @@ -422,28 +358,14 @@ async def create_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: # Check if the snippet already exists if await self.db.get_snippet_by_name_and_guild_id(name, ctx.guild.id) is not None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet already exists.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Snippet already exists.") return # Check if the name is longer than 20 characters and includes non-alphanumeric characters (except -) rules = set(string.ascii_letters + string.digits + "-") if len(name) > 20 or any(char not in rules for char in name): - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet name must be alphanumeric (allows dashes and underscores) and less than 20 characters.", - ) - await ctx.send(embed=embed) + await self.send_snippet_error(ctx, description="Snippet name must be alphanumeric (allows dashes only) and less than 20 characters.") return await self.db.create_snippet( @@ -479,14 +401,7 @@ async def edit_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: args = arg.split(" ") if len(args) < 2: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Please provide a name and content for the snippet.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Please provide a name and content for the snippet.") return name = args[0] @@ -495,14 +410,7 @@ async def edit_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: snippet = await self.db.get_snippet_by_name_and_guild_id(name, ctx.guild.id) if snippet is None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet not found.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Snippet not found.") return if await self.is_snippetbanned(ctx.guild.id, ctx.author.id): @@ -518,28 +426,14 @@ async def edit_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: try: await checks.has_pl(2).predicate(ctx) except commands.CheckFailure: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="This snippet is locked and cannot be edited. If you are a moderator you can use the `forcedeletesnippet` command.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="This snippet is locked and cannot be edited. If you are a moderator you can use the `forcedeletesnippet` command.") return logger.info(f"{ctx.author} has the permission level to edit locked snippets.") # Check if the author of the snippet is the same as the user who wants to edit it and if theres no author don't allow editing author_id = snippet.snippet_user_id or 0 if author_id != ctx.author.id: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="You can only edit your own snippets.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="You can only edit your own snippets.") return await self.db.update_snippet_by_id( @@ -574,27 +468,13 @@ async def toggle_snippet_lock(self, ctx: commands.Context[Tux], name: str) -> No snippet = await self.db.get_snippet_by_name_and_guild_id(name, ctx.guild.id) if snippet is None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="Snippet not found.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, description="Snippet not found.") return status = await self.db.toggle_snippet_lock_by_id(snippet.snippet_id) if status is None: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="No return value from locking the snippet. It may still have been locked.", - ) - await ctx.send(embed=embed, delete_after=30, ephemeral=True) + await self.send_snippet_error(ctx, "No return value from locking the snippet. It may still have been locked.") return if author := self.bot.get_user(snippet.snippet_user_id): @@ -612,36 +492,22 @@ async def toggle_snippet_lock(self, ctx: commands.Context[Tux], name: str) -> No await ctx.send("Snippet lock toggled.", delete_after=30, ephemeral=True) logger.info(f"{ctx.author} toggled the lock of the snippet with the name {name}.") - async def no_snippets_found(self, ctx: commands.Context[Tux], snippets: list[Snippet]) -> bool: + async def send_snippet_error(self, ctx: commands.Context[Tux], description: str) -> None: """ - Check if there are no snippets found. + Send an error message to the channel if there are no snippets found. Parameters ---------- ctx : commands.Context[Tux] The context object. - snippets : list[Snippet] - The list of snippets. - - Returns - ------- - True - If there are no snippets found. - And sends an error message to the channel. - False - If there are snippets found. """ - if not snippets: - embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description="No snippets found.", - ) - await ctx.send(embed=embed, delete_after=30) - return True - return False - + embed = EmbedCreator.create_embed( + bot=self.bot, + embed_type=EmbedCreator.ERROR, + user_name=ctx.author.name, + user_display_avatar=ctx.author.display_avatar.url, + description=description, + ) + await ctx.send(embed=embed, delete_after=30) async def setup(bot: Tux) -> None: await bot.add_cog(Snippets(bot)) diff --git a/tux/ui/embeds.py b/tux/ui/embeds.py index 24d84755..8b1a4e95 100644 --- a/tux/ui/embeds.py +++ b/tux/ui/embeds.py @@ -43,6 +43,7 @@ def create_embed( custom_footer_text: str | None = None, custom_footer_icon_url: str | None = None, custom_author_text: str | None = None, + custom_author_text_url: str | None = None, custom_author_icon_url: str | None = None, hide_author: bool = False, custom_color: int | discord.Colour | None = None, @@ -63,6 +64,7 @@ def create_embed( custom_footer_text (str | None): Overrides default footer text if provided. custom_footer_icon_url (str | None): Overrides default footer icon if provided. custom_author_text (str | None): Overrides default author text if provided. + custom_author_text_url (str | None): Adds author URL if provided. custom_author_icon_url (str | None): Overrides default author icon if provided. hide_author (bool): If True, removes the author from the embed. custom_color (int | Colour |None): Overrides default color for the embed type if provided. @@ -90,6 +92,7 @@ def create_embed( embed.set_author( name=custom_author_text or type_settings[embed_type][2], icon_url=custom_author_icon_url or type_settings[embed_type][1], + url=custom_author_text_url, ) if custom_footer_text: diff --git a/tux/utils/exports.py b/tux/utils/exports.py index b02587de..94172dff 100644 --- a/tux/utils/exports.py +++ b/tux/utils/exports.py @@ -69,12 +69,7 @@ async def get_help_embed( return EmbedCreator.create_embed( embed_type=EmbedCreator.INFO, title=title, - description="Use any combination of the following flags to " - + f"export a list of {data_description} to a CSV file:" - + "\n```" - + "\n--all\n" - + "\n".join([f"--{flag}" for flag in valid_flags]) - + "\n```", + description=f"Use any combination of the following flags to export a list of {data_description} to a CSV file:\n```--all\n{'\n'.join([f'--{flag}' for flag in valid_flags])}```", ) From e70ba723589af0458ce5420b1571a4f31d8be4bc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Sep 2024 19:47:56 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tux/cogs/guild/config.py | 5 ----- tux/cogs/info/info.py | 2 +- tux/cogs/moderation/__init__.py | 2 +- tux/cogs/moderation/cases.py | 1 - tux/cogs/utility/snippets.py | 40 ++++++++++++++++++++++----------- tux/handlers/event.py | 7 +++--- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/tux/cogs/guild/config.py b/tux/cogs/guild/config.py index a2679e0c..404fa499 100644 --- a/tux/cogs/guild/config.py +++ b/tux/cogs/guild/config.py @@ -10,7 +10,6 @@ from tux.ui.views.config import ConfigSetChannels, ConfigSetPrivateLogs, ConfigSetPublicLogs from tux.utils.constants import CONST - # TODO: Add onboarding setup to ensure all required channels, logs, and roles are set up # TODO: Figure out how to handle using our custom checks because the current checks would result in a lock out # TODO: Add a command to reset the guild config to default values @@ -184,7 +183,6 @@ async def config_get_roles( assert interaction.guild - embed = EmbedCreator.create_embed( title="Config - Roles", embed_type=EmbedType.INFO, @@ -216,7 +214,6 @@ async def config_get_perms( assert interaction.guild - embed = EmbedCreator.create_embed( embed_type=EmbedType.INFO, custom_color=discord.Color.blue(), @@ -250,7 +247,6 @@ async def config_get_channels( assert interaction.guild - embed = EmbedCreator.create_embed( title="Config - Channels", embed_type=EmbedType.INFO, @@ -290,7 +286,6 @@ async def config_get_logs( assert interaction.guild - embed = EmbedCreator.create_embed( title="Config - Logs", embed_type=EmbedType.INFO, diff --git a/tux/cogs/info/info.py b/tux/cogs/info/info.py index ed320bb5..411a8e9d 100644 --- a/tux/cogs/info/info.py +++ b/tux/cogs/info/info.py @@ -168,7 +168,7 @@ async def paginated_embed( The size of each chunk for pagination. """ embed: discord.Embed = EmbedCreator.create_embed( - embed_type=EmbedType.INFO, title=title, custom_color=discord.Color.blurple() + embed_type=EmbedType.INFO, title=title, custom_color=discord.Color.blurple(), ) chunks: list[list[str]] = list(self._chunks(iter(items), chunk_size)) diff --git a/tux/cogs/moderation/__init__.py b/tux/cogs/moderation/__init__.py index 19cacd48..ca4f4d85 100644 --- a/tux/cogs/moderation/__init__.py +++ b/tux/cogs/moderation/__init__.py @@ -17,7 +17,7 @@ def __init__(self, bot: Tux) -> None: self.db = DatabaseController() self.config = DatabaseController().guild_config - #TODO: Get rid of create_embed in the ModerationCogBase command as its only being used once and is replacable + # TODO: Get rid of create_embed in the ModerationCogBase command as its only being used once and is replacable def create_embed( self, ctx: commands.Context[Tux], diff --git a/tux/cogs/moderation/cases.py b/tux/cogs/moderation/cases.py index 14fca607..137dcfe1 100644 --- a/tux/cogs/moderation/cases.py +++ b/tux/cogs/moderation/cases.py @@ -276,7 +276,6 @@ async def _handle_case_response( ) embed.set_thumbnail(url=user.avatar) else: - embed = EmbedCreator.create_embed( embed_type=EmbedType.ERROR, title=f"Case {action}", diff --git a/tux/cogs/utility/snippets.py b/tux/cogs/utility/snippets.py index 9c41a8c6..6ddbf126 100644 --- a/tux/cogs/utility/snippets.py +++ b/tux/cogs/utility/snippets.py @@ -80,7 +80,6 @@ def _create_snippets_list_embed( snippets: list[Snippet], total_snippets: int, ) -> discord.Embed: - assert ctx.guild assert ctx.guild.icon @@ -186,7 +185,10 @@ async def delete_snippet(self, ctx: commands.Context[Tux], name: str) -> None: # check if the snippet is locked if snippet.locked: - await self.send_snippet_error(ctx, description="This snippet is locked and cannot be deleted. If you are a moderator you can use the `forcedeletesnippet` command.") + await self.send_snippet_error( + ctx, + description="This snippet is locked and cannot be deleted. If you are a moderator you can use the `forcedeletesnippet` command.", + ) return # Check if the author of the snippet is the same as the user who wants to delete it and if theres no author don't allow deletion @@ -256,7 +258,10 @@ async def get_snippet(self, ctx: commands.Context[Tux], name: str) -> None: # check if the name contains an underscore if "_" in name: - await self.send_snippet_error(ctx, description="Did you mean to use `-` instead of `_`? Due to a recent change, `_` is no longer allowed in snippet names.") + await self.send_snippet_error( + ctx, + description="Did you mean to use `-` instead of `_`? Due to a recent change, `_` is no longer allowed in snippet names.", + ) return if snippet is None: await self.send_snippet_error(ctx, description="No snippets found.") @@ -306,7 +311,7 @@ async def get_snippet_info(self, ctx: commands.Context[Tux], name: str) -> None: user_name=ctx.author.name, user_display_avatar=ctx.author.display_avatar.url, title="Snippet Information", - message_timestamp=snippet.snippet_created_at or datetime.datetime.fromtimestamp(0,datetime.UTC) + message_timestamp=snippet.snippet_created_at or datetime.datetime.fromtimestamp(0, datetime.UTC), ) embed.add_field(name="Name", value=snippet.snippet_name, inline=False) @@ -365,7 +370,9 @@ async def create_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: rules = set(string.ascii_letters + string.digits + "-") if len(name) > 20 or any(char not in rules for char in name): - await self.send_snippet_error(ctx, description="Snippet name must be alphanumeric (allows dashes only) and less than 20 characters.") + await self.send_snippet_error( + ctx, description="Snippet name must be alphanumeric (allows dashes only) and less than 20 characters.", + ) return await self.db.create_snippet( @@ -426,7 +433,10 @@ async def edit_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: try: await checks.has_pl(2).predicate(ctx) except commands.CheckFailure: - await self.send_snippet_error(ctx, description="This snippet is locked and cannot be edited. If you are a moderator you can use the `forcedeletesnippet` command.") + await self.send_snippet_error( + ctx, + description="This snippet is locked and cannot be edited. If you are a moderator you can use the `forcedeletesnippet` command.", + ) return logger.info(f"{ctx.author} has the permission level to edit locked snippets.") @@ -474,7 +484,9 @@ async def toggle_snippet_lock(self, ctx: commands.Context[Tux], name: str) -> No status = await self.db.toggle_snippet_lock_by_id(snippet.snippet_id) if status is None: - await self.send_snippet_error(ctx, "No return value from locking the snippet. It may still have been locked.") + await self.send_snippet_error( + ctx, "No return value from locking the snippet. It may still have been locked.", + ) return if author := self.bot.get_user(snippet.snippet_user_id): @@ -502,12 +514,14 @@ async def send_snippet_error(self, ctx: commands.Context[Tux], description: str) The context object. """ embed = EmbedCreator.create_embed( - bot=self.bot, - embed_type=EmbedCreator.ERROR, - user_name=ctx.author.name, - user_display_avatar=ctx.author.display_avatar.url, - description=description, - ) + bot=self.bot, + embed_type=EmbedCreator.ERROR, + user_name=ctx.author.name, + user_display_avatar=ctx.author.display_avatar.url, + description=description, + ) await ctx.send(embed=embed, delete_after=30) + + async def setup(bot: Tux) -> None: await bot.add_cog(Snippets(bot)) diff --git a/tux/handlers/event.py b/tux/handlers/event.py index 00b8f7c6..b583a1ce 100644 --- a/tux/handlers/event.py +++ b/tux/handlers/event.py @@ -3,8 +3,8 @@ from tux.bot import Tux from tux.database.controllers import DatabaseController -from tux.utils.functions import is_harmful, strip_formatting from tux.ui.embeds import EmbedCreator, EmbedType +from tux.utils.functions import is_harmful, strip_formatting class EventHandler(commands.Cog): @@ -88,8 +88,9 @@ async def on_thread_create(self, thread: discord.Thread) -> None: else: msg = f"<:tux_notify:1274504953666474025> **New support thread created** - help is appreciated!\n{thread.mention} by {owner_mention}" - embed = EmbedCreator.create_embed(embed_type=EmbedType.INFO, description=msg, custom_color=discord.Color.random(), hide_author=True) - + embed = EmbedCreator.create_embed( + embed_type=EmbedType.INFO, description=msg, custom_color=discord.Color.random(), hide_author=True, + ) general_chat = 1172245377395728467 channel = self.bot.get_channel(general_chat) From 8671cbf8c0cb54af8382d4dbe2d9bcb821b575fc Mon Sep 17 00:00:00 2001 From: wlinator Date: Sat, 7 Sep 2024 15:54:44 -0400 Subject: [PATCH 4/7] Pre-commit fixed code --- tux/cogs/info/info.py | 4 +++- tux/cogs/utility/snippets.py | 6 ++++-- tux/handlers/event.py | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tux/cogs/info/info.py b/tux/cogs/info/info.py index 411a8e9d..b00be5d4 100644 --- a/tux/cogs/info/info.py +++ b/tux/cogs/info/info.py @@ -168,7 +168,9 @@ async def paginated_embed( The size of each chunk for pagination. """ embed: discord.Embed = EmbedCreator.create_embed( - embed_type=EmbedType.INFO, title=title, custom_color=discord.Color.blurple(), + embed_type=EmbedType.INFO, + title=title, + custom_color=discord.Color.blurple(), ) chunks: list[list[str]] = list(self._chunks(iter(items), chunk_size)) diff --git a/tux/cogs/utility/snippets.py b/tux/cogs/utility/snippets.py index 6ddbf126..90cfcdfd 100644 --- a/tux/cogs/utility/snippets.py +++ b/tux/cogs/utility/snippets.py @@ -371,7 +371,8 @@ async def create_snippet(self, ctx: commands.Context[Tux], *, arg: str) -> None: if len(name) > 20 or any(char not in rules for char in name): await self.send_snippet_error( - ctx, description="Snippet name must be alphanumeric (allows dashes only) and less than 20 characters.", + ctx, + description="Snippet name must be alphanumeric (allows dashes only) and less than 20 characters.", ) return @@ -485,7 +486,8 @@ async def toggle_snippet_lock(self, ctx: commands.Context[Tux], name: str) -> No if status is None: await self.send_snippet_error( - ctx, "No return value from locking the snippet. It may still have been locked.", + ctx, + "No return value from locking the snippet. It may still have been locked.", ) return diff --git a/tux/handlers/event.py b/tux/handlers/event.py index b583a1ce..4f5a068d 100644 --- a/tux/handlers/event.py +++ b/tux/handlers/event.py @@ -89,7 +89,10 @@ async def on_thread_create(self, thread: discord.Thread) -> None: msg = f"<:tux_notify:1274504953666474025> **New support thread created** - help is appreciated!\n{thread.mention} by {owner_mention}" embed = EmbedCreator.create_embed( - embed_type=EmbedType.INFO, description=msg, custom_color=discord.Color.random(), hide_author=True, + embed_type=EmbedType.INFO, + description=msg, + custom_color=discord.Color.random(), + hide_author=True, ) general_chat = 1172245377395728467 From dde70c009b0786e4e0819b7313df7a2720cffe1d Mon Sep 17 00:00:00 2001 From: wlinator Date: Sat, 7 Sep 2024 15:57:42 -0400 Subject: [PATCH 5/7] feat: Improve EmbedCreator by adding option to hide timestamp --- tux/ui/embeds.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tux/ui/embeds.py b/tux/ui/embeds.py index 8b1a4e95..e3937e5d 100644 --- a/tux/ui/embeds.py +++ b/tux/ui/embeds.py @@ -45,8 +45,9 @@ def create_embed( custom_author_text: str | None = None, custom_author_text_url: str | None = None, custom_author_icon_url: str | None = None, - hide_author: bool = False, custom_color: int | discord.Colour | None = None, + hide_author: bool = False, + hide_timestamp: bool = False, ) -> discord.Embed: """ Create a customized Discord embed based on the specified type and parameters. @@ -107,7 +108,8 @@ def create_embed( if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) - embed.timestamp = message_timestamp or discord.utils.utcnow() + if not hide_timestamp: + embed.timestamp = message_timestamp or discord.utils.utcnow() except Exception as e: logger.debug("Error in create_embed", exc_info=e) From 76ab9a23baf7bba92213b5eceb2840343fe57d7e Mon Sep 17 00:00:00 2001 From: petabyte-imo Date: Sat, 7 Sep 2024 21:41:19 +0100 Subject: [PATCH 6/7] Added a few more --- tux/cogs/info/info.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/tux/cogs/info/info.py b/tux/cogs/info/info.py index b00be5d4..19aa9aa5 100644 --- a/tux/cogs/info/info.py +++ b/tux/cogs/info/info.py @@ -11,7 +11,7 @@ class Info(commands.Cog): def __init__(self, bot: Tux) -> None: self.bot = bot - + @commands.guild_only() @commands.hybrid_group(name="info", aliases=["i"], usage="info ") async def info(self, ctx: commands.Context[Tux]) -> None: """ @@ -25,7 +25,7 @@ async def info(self, ctx: commands.Context[Tux]) -> None: if ctx.invoked_subcommand is None: await ctx.send_help("info") - + @commands.guild_only() @info.command(name="server", aliases=["s"], usage="info server") async def server(self, ctx: commands.Context[Tux]) -> None: """ @@ -38,14 +38,18 @@ async def server(self, ctx: commands.Context[Tux]) -> None: """ guild = ctx.guild assert guild + assert guild.icon embed: discord.Embed = ( - discord.Embed( + EmbedCreator.create_embed( + embed_type=EmbedType.INFO, title=guild.name, description=guild.description or "No description available.", - color=discord.Color.blurple(), + custom_color=discord.Color.blurple(), + custom_author_text="Server Information", + custom_author_icon_url=guild.icon.url, + custom_footer_text=f"ID: {guild.id} | Created: {guild.created_at.strftime('%B %d, %Y')}", ) - .set_author(name="Server Information", icon_url=guild.icon) .add_field(name="Owner", value=str(guild.owner.mention) if guild.owner else "Unknown") .add_field(name="Vanity URL", value=guild.vanity_url_code or "None") .add_field(name="Boosts", value=guild.premium_subscription_count) @@ -58,11 +62,10 @@ async def server(self, ctx: commands.Context[Tux]) -> None: .add_field(name="Humans", value=sum(not member.bot for member in guild.members)) .add_field(name="Bots", value=sum(member.bot for member in guild.members)) .add_field(name="Bans", value=len([entry async for entry in guild.bans(limit=2000)])) - .set_footer(text=f"ID: {guild.id} | Created: {guild.created_at.strftime('%B %d, %Y')}") ) await ctx.send(embed=embed) - + @commands.guild_only() @info.command(name="member", aliases=["m", "user", "u"], usage="info member [member]") async def member(self, ctx: commands.Context[Tux], member: discord.Member) -> None: """ @@ -75,15 +78,15 @@ async def member(self, ctx: commands.Context[Tux], member: discord.Member) -> No member : discord.Member The member to get information about. """ + user = await self.bot.fetch_user(member.id) embed: discord.Embed = ( - discord.Embed( + EmbedCreator.create_embed( + embed_type=EmbedType.INFO, title=member.display_name, + custom_color=discord.Color.blurple(), description="Here is some information about the member.", - color=discord.Color.blurple(), - ) - .set_thumbnail(url=member.display_avatar.url) - .set_image( - url=(await self.bot.fetch_user(member.id)).banner, # Fetched member's banner + thumbnail_url=member.display_avatar.url, + image_url=user.banner.url if user.banner else None, ) .add_field(name="Bot?", value="✅" if member.bot else "❌", inline=False) .add_field(name="Username", value=member.name, inline=False) @@ -106,7 +109,7 @@ async def member(self, ctx: commands.Context[Tux], member: discord.Member) -> No ) await ctx.send(embed=embed) - + @commands.guild_only() @info.command(name="roles", aliases=["r"], usage="info roles") async def roles(self, ctx: commands.Context[Tux]) -> None: """ From 76d07157a8149876a52a99df1c70998e104ad9ad Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Sep 2024 20:41:30 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tux/cogs/info/info.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tux/cogs/info/info.py b/tux/cogs/info/info.py index 19aa9aa5..c4fd3db0 100644 --- a/tux/cogs/info/info.py +++ b/tux/cogs/info/info.py @@ -11,6 +11,7 @@ class Info(commands.Cog): def __init__(self, bot: Tux) -> None: self.bot = bot + @commands.guild_only() @commands.hybrid_group(name="info", aliases=["i"], usage="info ") async def info(self, ctx: commands.Context[Tux]) -> None: @@ -25,6 +26,7 @@ async def info(self, ctx: commands.Context[Tux]) -> None: if ctx.invoked_subcommand is None: await ctx.send_help("info") + @commands.guild_only() @info.command(name="server", aliases=["s"], usage="info server") async def server(self, ctx: commands.Context[Tux]) -> None: @@ -65,6 +67,7 @@ async def server(self, ctx: commands.Context[Tux]) -> None: ) await ctx.send(embed=embed) + @commands.guild_only() @info.command(name="member", aliases=["m", "user", "u"], usage="info member [member]") async def member(self, ctx: commands.Context[Tux], member: discord.Member) -> None: @@ -109,6 +112,7 @@ async def member(self, ctx: commands.Context[Tux], member: discord.Member) -> No ) await ctx.send(embed=embed) + @commands.guild_only() @info.command(name="roles", aliases=["r"], usage="info roles") async def roles(self, ctx: commands.Context[Tux]) -> None: