From 558d71f62465b4e08f194d01b26a53d291ee2f95 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 18:58:33 +0530 Subject: [PATCH 01/26] Remove all instances of the old EmbedEngine system --- cogs/utils.py | 28 +--------------------------- framework/isobot/embedengine.py | 25 ------------------------- 2 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 framework/isobot/embedengine.py diff --git a/cogs/utils.py b/cogs/utils.py index 067ae9d8..1c00db01 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -10,7 +10,7 @@ import time import datetime from api import auth -from framework.isobot import currency, embedengine, commands as cmds +from framework.isobot import currency, commands as cmds from framework.isobot.db import levelling from discord import option, ApplicationContext from discord.commands import SlashCommandGroup @@ -70,32 +70,6 @@ async def repo(self, ctx: ApplicationContext): ) await ctx.respond(embed=localembed) - @commands.slash_command( - name="embedbuilder", - description="Builds a custom embed however you want." - ) - @option(name="title", description="The title of the embed", type=str) - @option(name="description", description="The body of the embed", type=str) - @option(name="image_url", description="The main image you want to show for the embed (URL ONLY)", type=str, default=None) - @option(name="thumbnail_url", description="The thumbnail image you want to show for the embed (URL ONLY)", type=str, default=None) - @option(name="color", description="The embed's accent color (Use -1 for random color)", type=int, default=None) - @option(name="footer_text", description="The text at the footer of the embed", type=str, default=None) - @option(name="footer_icon_url", description="The icon you want to show in the embed's footer (URL ONLY)", type=str, default=None) - async def embedbuilder(self, ctx: ApplicationContext, title: str, description: str, image_url: str = None, thumbnail_url: str = None, color: int = None, footer_text: str = None, footer_icon_url: str = None): - """Builds a custom embed however you want.""" - await ctx.respond("Embed Built!", ephemeral=True) - await ctx.channel.send( - embed=embedengine.embed( - title, - description, - image=image_url, - thumbnail=thumbnail_url, - color=color, - footer_text=footer_text, - footer_img=footer_icon_url - ) - ) - @commands.slash_command( name='whoami', description='Shows information on a user.' diff --git a/framework/isobot/embedengine.py b/framework/isobot/embedengine.py deleted file mode 100644 index 9ddf9368..00000000 --- a/framework/isobot/embedengine.py +++ /dev/null @@ -1,25 +0,0 @@ -"""The library used for designing and outputting Discord embeds.""" - -import discord - -def embed(title: str, desc: str, *, image: str = None, thumbnail: str = None, color:int=None, footer_text: str = None, footer_img: str = None): - """Designs a Discord embed. - ----------------------------------------------------------- - The color argument is completely optional. - - If a color is set, it will return the embed in that color only. - - If the color is set as "rand", then it will return the embed with a random color. - - If a color is not set, it will appear as Discord's blurple embed color. - """ - if color == -1: color = discord.Color.random() - elif color == None: color = discord.Color.blurple() - local_embed = discord.Embed( - title=title, - description=desc, - colour=color - ) - if image is not None: local_embed.set_image(url=image) - if thumbnail is not None: local_embed.set_thumbnail(url=thumbnail) - if footer_text is not None and footer_img is not None: local_embed.set_footer(text=footer_text, icon_url=footer_img) - elif footer_text is not None: local_embed.set_footer(text=footer_text) - elif footer_img is not None: local_embed.set_footer(icon_url=footer_img) - return local_embed From bc14cfc36e16612cd7afd370f05e80ae062d53f9 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:01:07 +0530 Subject: [PATCH 02/26] Add `embeds` to the list of generatable databases --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 7c4421ba..ae75da3e 100644 --- a/main.py +++ b/main.py @@ -53,6 +53,7 @@ def initial_setup(): "presence", "user_data", "weather", + "embeds", "isobank/accounts", "isobank/auth" ] From 82e25a654cf622fefbe95455e766384688eb49d4 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:02:05 +0530 Subject: [PATCH 03/26] Create embeds database management module in framework --- framework/isobot/db/embeds.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 framework/isobot/db/embeds.py diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py new file mode 100644 index 00000000..06b14342 --- /dev/null +++ b/framework/isobot/db/embeds.py @@ -0,0 +1,19 @@ +# Imports +import json +from framework.isobot.colors import Colors as colors + +# Functions +class Automod(): + """Initializes the EmbedEngine database system.""" + def __init__(self): + print(f"[framework/db/Automod] {colors.green}Embeds db library initialized.{colors.end}") + + def load(self) -> dict: + """Fetches and returns the latest data from the items database.""" + with open("database/embeds.json", 'r', encoding="utf8") as f: db = json.load(f) + return db + + def save(self, data: dict) -> int: + """Dumps all cached data to your local machine.""" + with open("database/embeds.json", 'w+', encoding="utf8") as f: json.dump(data, f) + return 0 From 602b29726d92460bf5601fe6006ece2b5b035f5b Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:02:48 +0530 Subject: [PATCH 04/26] Add import for `embeds` database framework module in `cogs.utils` --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index 1c00db01..8bb11f07 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -11,7 +11,7 @@ import datetime from api import auth from framework.isobot import currency, commands as cmds -from framework.isobot.db import levelling +from framework.isobot.db import levelling, embeds from discord import option, ApplicationContext from discord.commands import SlashCommandGroup from discord.ext import commands From f887c755ab676a4d3adc4f6207d58a18de2da588 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:05:10 +0530 Subject: [PATCH 05/26] Fix docstring for `Embeds` class --- framework/isobot/db/embeds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 06b14342..9804ef05 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -4,7 +4,7 @@ # Functions class Automod(): - """Initializes the EmbedEngine database system.""" + """Initializes the Embed database system.""" def __init__(self): print(f"[framework/db/Automod] {colors.green}Embeds db library initialized.{colors.end}") From 540ea22b07f2818171535127d6e5f0635c94e65f Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:05:22 +0530 Subject: [PATCH 06/26] Fix up a few typos --- framework/isobot/db/embeds.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 9804ef05..a29f7120 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -3,13 +3,13 @@ from framework.isobot.colors import Colors as colors # Functions -class Automod(): +class Embeds(): """Initializes the Embed database system.""" def __init__(self): - print(f"[framework/db/Automod] {colors.green}Embeds db library initialized.{colors.end}") + print(f"[framework/db/Embeds] {colors.green}Embeds db library initialized.{colors.end}") def load(self) -> dict: - """Fetches and returns the latest data from the items database.""" + """Fetches and returns the latest data from the embeds database.""" with open("database/embeds.json", 'r', encoding="utf8") as f: db = json.load(f) return db From 306a131b4b88e8d13105e492c04b766a58f28dc0 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:12:49 +0530 Subject: [PATCH 07/26] Add `get_embeds_list()` to fetch a `dict` of all the set-up embeds in a specific server --- framework/isobot/db/embeds.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index a29f7120..c81f77da 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -1,5 +1,6 @@ # Imports import json +from typing_extensions import Union from framework.isobot.colors import Colors as colors # Functions @@ -17,3 +18,8 @@ def save(self, data: dict) -> int: """Dumps all cached data to your local machine.""" with open("database/embeds.json", 'w+', encoding="utf8") as f: json.dump(data, f) return 0 + + def get_embeds_list(self, server_id: Union[str, int]) -> dict: + """Fetches a `dict` of all the added embeds in the specified server.\n\nReturns an empty `dict` if none are set up.""" + embeds = self.load() + return embeds[str(server_id)] From 4894dcf5fafa9d94b8ca021f8276c11c2e1d098d Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 20:57:53 +0530 Subject: [PATCH 08/26] Add import for testing generation of embeds --- framework/isobot/db/embeds.py | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index c81f77da..4fc6b007 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -1,5 +1,6 @@ # Imports import json +import discord from typing_extensions import Union from framework.isobot.colors import Colors as colors From d1cbeb868cba6ded312f55826ca91efae8b15694 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 20:58:48 +0530 Subject: [PATCH 09/26] Add `generate_embed()` to create new embeds for a server --- framework/isobot/db/embeds.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 4fc6b007..d54150cf 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -24,3 +24,37 @@ def get_embeds_list(self, server_id: Union[str, int]) -> dict: """Fetches a `dict` of all the added embeds in the specified server.\n\nReturns an empty `dict` if none are set up.""" embeds = self.load() return embeds[str(server_id)] + + def generate_embed( + self, + server_id: Union[str, int], + embed_name: str, + *, + title: str = None, + description: str = None, + color: int = None, + timestamp_enabled: bool = False, + title_url: str = None, + image_url: str = None, + thumbnail: str = None + + ) -> int: + """Generates an embed for the specified server using the given embed data.\n\nReturns `0` if successful, returns `1` if an embed with the same embed name already exists.""" + embeds = self.load() + + if embed_name not in embeds[str(server_id)].keys(): + embeds[str(server_id)][embed_name] = { + "title": title, + "description": description, + # "color": # TODO: Fina a way to implement colors into the embeds + "timestamp_enabled": timestamp_enabled, + "title_url": title_url, + "image_url": image_url, + "thumbnail": thumbnail, + "fields": [], + "author": {}, + "footer": {} + } + self.save(embeds) + return 0 + else: return 1 From 07403e9ecb8b89838394d081ab7b308989b8d047 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 20:59:09 +0530 Subject: [PATCH 10/26] Add `delete_embed()` to delete existing embeds from a server --- framework/isobot/db/embeds.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index d54150cf..d9bb1363 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -58,3 +58,12 @@ def generate_embed( self.save(embeds) return 0 else: return 1 + + def delete_embed(self, server_id: Union[str, int], embed_name: str) -> int: + """Deletes an existing embed from the specified server's embeds list.\n\nReturns `0` if successful, returns `1` if the embed does not exist.""" + embeds = self.load() + if embed_name in embeds[str(server_id)].keys(): + del embeds[str(server_id)][embed_name] + self.save(embeds) + return 0 + else: return 1 From b1053e9ccae8b15f57e38e8785ee0bebb61f6204 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:00:02 +0530 Subject: [PATCH 11/26] Make some more functions for further customization of existing server embeds --- framework/isobot/db/embeds.py | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index d9bb1363..99b2b0a8 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -67,3 +67,63 @@ def delete_embed(self, server_id: Union[str, int], embed_name: str) -> int: self.save(embeds) return 0 else: return 1 + + def add_embed_field( + self, + server_id: Union[str, int], + embed_name: str, + name: str, + value: str, + inline: bool = False + ) -> int: + """Adds a new field to an already existing embed.\n\nReturns `0` if successful, returns `1` if the embed does not exist.""" + embeds = self.load() + if embed_name in embeds[str(server_id)].keys(): + list(embeds[str(server_id)][embed_name]["fields"]).append( + { + "name": name, + "value": value, + "inline": inline + } + ) + self.save(embeds) + return 0 + else: return 1 + + def add_embed_footer( + self, + server_id: Union[str, int], + embed_name: str, + text: str, + icon_url: str = None + ) -> int: + """Adds a footer to an already existing embed.\n\nReturns `0` if successful, returns `1` if the embed does not exist.""" + embeds = self.load() + if embed_name in embeds[str(server_id)].keys(): + embeds[str(server_id)][embed_name]["footer"] = { + "text": text, + "icon_url": icon_url + } + self.save(embeds) + return 0 + else: return 1 + + def add_embed_author( + self, + server_id: Union[str, int], + embed_name: str, + name: str, + url: str = None, + icon_url: str = None + ): + """Adds the author field to an already existing embed.\n\nReturns `0` if successful, returns `1` if the embed does not exist.""" + embeds = self.load() + if embed_name in embeds[str(server_id)].keys(): + embeds[str(server_id)][embed_name]["author"] = { + "name": name, + "url": url, + "icon_url": icon_url + } + self.save(embeds) + return 0 + else: return 1 From 396da22790067a3ec1d4a13443dbd1d671f217e3 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:00:34 +0530 Subject: [PATCH 12/26] Add todo list to track embed system features --- framework/isobot/db/embeds.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 99b2b0a8..ad7c26ef 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -127,3 +127,16 @@ def add_embed_author( self.save(embeds) return 0 else: return 1 + + +# TODO: Add the following functions for the embeds: +# - title (done) +# - description (done) +# - url (done) +# - colour +# - timestamp (done) +# - footer (done) +# - image (done) +# - thumbnail (done) +# - author (done) +# - fields (done) From 656112c20756399c117bb8ff80765169e6b3ce37 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 28 Oct 2024 22:34:30 +0530 Subject: [PATCH 13/26] Add framework module to check for valid hex code input values --- framework/types.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 framework/types.py diff --git a/framework/types.py b/framework/types.py new file mode 100644 index 00000000..987629fb --- /dev/null +++ b/framework/types.py @@ -0,0 +1,5 @@ +"""An NKA Framework Module to check and verify various datatypes used across systems.""" + +def is_hex_color_code(num) -> bool: + """Checks whether an integer is a valid hexadecimal code.\n\nReturns `True` if valid, returns `False` if invalid.""" + return isinstance(num, int) and 0x000000 <= num <= 0xFFFFFF From d88a9a7f3839f3eab246571ac2e2ce6eae081f42 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 28 Oct 2024 22:37:23 +0530 Subject: [PATCH 14/26] Add hex colors support for new embed generation --- framework/isobot/db/embeds.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index ad7c26ef..97e38514 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -1,6 +1,7 @@ # Imports import json import discord +import framework.types from typing_extensions import Union from framework.isobot.colors import Colors as colors @@ -39,14 +40,18 @@ def generate_embed( thumbnail: str = None ) -> int: - """Generates an embed for the specified server using the given embed data.\n\nReturns `0` if successful, returns `1` if an embed with the same embed name already exists.""" + """Generates an embed for the specified server using the given embed data.\n\nReturns `0` if successful, returns `1` if an embed with the same embed name already exists, returns `2` if the specified embed color is not a valid hex code.""" embeds = self.load() if embed_name not in embeds[str(server_id)].keys(): + # Check whether color code is a valid value or not + if color not in [-1, 0] or not framework.types.is_hex_color_code(color): + return 2 + embeds[str(server_id)][embed_name] = { "title": title, "description": description, - # "color": # TODO: Fina a way to implement colors into the embeds + "color": color, # -1 = random color, None = no color, hex code = custom color "timestamp_enabled": timestamp_enabled, "title_url": title_url, "image_url": image_url, From 3de66011196ebb9bdd4e0fbf0b50026fd5711f56 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 28 Oct 2024 22:38:48 +0530 Subject: [PATCH 15/26] Add `build_embed()` function to build embeds from a specified server's embed data --- framework/isobot/db/embeds.py | 49 ++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 97e38514..93bad6da 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -1,6 +1,7 @@ # Imports import json import discord +import datetime import framework.types from typing_extensions import Union from framework.isobot.colors import Colors as colors @@ -64,6 +65,48 @@ def generate_embed( return 0 else: return 1 + def build_embed(self, server_id: Union[str, int], embed_name: str) -> discord.Embed: + """Builds a Discord embed from the specified server's embed data, and returns it as `discord.Embed`.\n\nReturns `1` if the embeds does not exist.""" + embeds = self.load() + if embed_name in embeds[str(server_id)].keys(): + embed_data = embeds[str(server_id)][embed_name] + + if embed_data["title"] == None: title = discord.Embed.Empty + if embed_data["description"] == None: description = discord.Embed.Empty + if embed_data["color"] == None: color = discord.Embed.Empty + if embed_data["title_url"] == None: title_url = discord.Embed.Empty + if embed_data["image_url"] == None: image_url = discord.Embed.Empty + if embed_data["thumbnail"] == None: thumbnail = discord.Embed.Empty + + embed = discord.Embed( + title=title, + description=description, + color = discord.Color.random() if embed_data["color"] == -1 else embed_data["color"], + url=title_url, + timestamp = datetime.datetime.utcnow() if embed_data["timestamp_enabled"] else discord.Embed.Empty + ) + embed.set_image(url=image_url) + embed.set_thumbnail(url=thumbnail) + + for field in embed_data["fields"]: + embed.add_field( + name=embed_data["fields"][field]["name"], + value=embed_data["fields"][field]["value"], + inline=embed_data["fields"][field]["inline"] + ) + + if embed_data["author"] != {}: + if embed_data["author"]["url"] == None: author_url = discord.Embed.Empty + if embed_data["author"]["icon_url"] == None: author_icon_url = discord.Embed.Empty + embed.set_author(name=embed_data["author"]["name"], url=author_url, icon_url=author_icon_url) + + if embed_data["footer"] != {}: + if embed_data["footer"]["icon_url"] == None: footer_icon_url = discord.Embed.Empty + embed.set_footer(text=embed_data["footer"]["text"], icon_url=footer_icon_url) + + return embed # Returning the embed data as output + else: return 1 + def delete_embed(self, server_id: Union[str, int], embed_name: str) -> int: """Deletes an existing embed from the specified server's embeds list.\n\nReturns `0` if successful, returns `1` if the embed does not exist.""" embeds = self.load() @@ -138,10 +181,14 @@ def add_embed_author( # - title (done) # - description (done) # - url (done) -# - colour +# - colour (done) # - timestamp (done) # - footer (done) # - image (done) # - thumbnail (done) # - author (done) # - fields (done) + +# TODO: Add following features: +# - Add embed build function (done) +# - Add colours support for embeds (done) From 579f3affbc9ebdbb686b46c1f35fccabbe1e2295 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Mon, 28 Oct 2024 22:39:22 +0530 Subject: [PATCH 16/26] Remove all completed todo lists --- framework/isobot/db/embeds.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 93bad6da..74d9b6cc 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -175,20 +175,3 @@ def add_embed_author( self.save(embeds) return 0 else: return 1 - - -# TODO: Add the following functions for the embeds: -# - title (done) -# - description (done) -# - url (done) -# - colour (done) -# - timestamp (done) -# - footer (done) -# - image (done) -# - thumbnail (done) -# - author (done) -# - fields (done) - -# TODO: Add following features: -# - Add embed build function (done) -# - Add colours support for embeds (done) From fde25e56023977f1ef52d95dd6b7d72ec9fd7fb5 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 29 Oct 2024 21:53:54 +0530 Subject: [PATCH 17/26] Add a bunch of `/embeds` commands for managing custom server embeds --- cogs/utils.py | 191 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index 8bb11f07..45433668 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -11,7 +11,7 @@ import datetime from api import auth from framework.isobot import currency, commands as cmds -from framework.isobot.db import levelling, embeds +from framework.isobot.db import levelling, embeds as _embeds from discord import option, ApplicationContext from discord.commands import SlashCommandGroup from discord.ext import commands @@ -22,6 +22,7 @@ currency = currency.CurrencyAPI("database/currency.json", "logs/currency.log") levelling = levelling.Levelling() _commands = cmds.Commands() +_embeds = _embeds.Embeds() # openai.api_key = os.getenv("chatgpt_API_KEY") openai.api_key = auth.ext_token('chatgpt') chatgpt_conversation = dict() @@ -342,6 +343,194 @@ async def serverinfo(self, ctx: ApplicationContext): ) await ctx.respond(embed=localembed) + # Server Embed System Manager Commands + embed_system = SlashCommandGroup("embeds", "Commands used to add, edit and remove custom bot embeds for server-wide use.") + + # TODO: Add commands for managing server embeds + + @embed_system.command( + name="create", + description="Create a new custom embed for the server." + ) + @commands.guild_only() + @option(name="embed_name", description="What do you want your embed's name to be?") + @option(name="title", description="Set a title for your embed", type=str, default=None) + @option(name="description", description="Set a description for your embed", type=str, default=None) + @option(name="color", description="Format: 0x{replace with hex code} (-1 = random color)", type=int, default=None) + @option(name="timestamp_enabled", description="Choose whether to display timestamps on the embed or not", type=bool, default=False) + @option(name="title_url", description="Attach a url to your embed title (https:// only)", type=str, default=None) + @option(name="image_url", description="Add an image to your embed (https:// only)", type=str, default=None) + @option(name="thumbnail", description="Add a thumbnail image to your embed (https:// only)", type=str, default=None) + async def embeds_create(self, ctx: ApplicationContext, embed_name: str, title: str = None, description: str = None, color: int = None, timestamp_enabled: bool = False, title_url: str = None, image_url: str = None, thumbnail: str = None): + """Create a new custom embed for the server.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond( + "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", + ephemeral=True + ) + _embeds.generate_embed( + server_id=ctx.guild.id, + embed_name=embed_name, + title=title, + description=description, + color=color, + timestamp_enabled=timestamp_enabled, + title_url=title_url, + image_url=image_url, + thumbnail=thumbnail + ) + await ctx.respond( + f"## :white_check_mark: Embed Successfully Created.\nThe name of this custom embed is `{embed_name}`. You can use this embed name to reference this custom embed in other commands.\n\nHere's a preview of your new embed:", + embed=_embeds.build_embed(ctx.guild.id, embed_name) + ) + + @embed_system.command( + name="delete", + description="Delete a custom embed from the server." + ) + @commands.guild_only() + @option(name="embed_name", description="The specific embed you want to delete.", type=str) + async def embeds_delete(self, ctx: ApplicationContext, embed_name: str): + """Delete a custom embed from the server.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond( + "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", + ephemeral=True + ) + result_code = _embeds.delete_embed(ctx.guild.id, embed_name=embed_name) + if result_code == 1: + localembed = discord.Embed( + title=":x: Failed to delete embed", + description=f"This server does not have an embed with the name `{embed_name}`.", + color=discord.Color.red() + ) + return await ctx.respond(embed=localembed, ephemeral=True) + else: + localembed = discord.Embed( + title=":white_check_mark: Custom embed successfully deleted", + description=f"The custom server embed `{embed_name}` has been deleted.\n\nMake sure to remove any references of this embed from any other serverconfig features in the bot.", + color=discord.Color.green() + ) + return await ctx.respond(embed=localembed) + + @embed_system.command( + name="list", + description="View a list of all the custom embeds in this server." + ) + @commands.guild_only() + async def embeds_list(self, ctx: ApplicationContext): + """View a list of all the custom embeds in this server.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond( + "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", + ephemeral=True + ) + embeds_list = _embeds.get_embeds_list() + num = 0 + parsed_output = str() + for embed in embeds_list.keys(): + num += 1 + parsed_output += f"{num}. `{embed}`\n" + if parsed_output == "": + parsed_output = "*Nothing to see here...*" + localembed = discord.Embed( + title=f"Custom Server Embeds for **{ctx.guild.name}**", + description=parsed_output + ) + await ctx.respond(embed=localembed) + + @embed_system.command( + name="add_embed_field", + description="Appends a new field to an existing server embed." + ) + @commands.guild_only() + @option(name="embed_name", description="The server embed to which you want to add the field.", type=str) + @option(name="name", description="The name of the field.", type=str) + @option(name="value", description="The value of the field.", type=str) + @option(name="inline", description="Whether you want the field to be in-line or not.", type=bool, default=False) + async def embeds_add_embed_field(self, ctx: ApplicationContext, embed_name: str, name: str, value: str, inline: bool = False): + """Appends a new field to an existing server embed.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond( + "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", + ephemeral=True + ) + result_code = _embeds.add_embed_field(ctx.guild.id, embed_name=embed_name, name=name, value=value, inline=inline) + if result_code == 1: + localembed = discord.Embed( + title=":x: Failed to add new field to embed", + description=f"This server does not have an embed with the name `{embed_name}`.", + color=discord.Color.red() + ) + return await ctx.respond(embed=localembed, ephemeral=True) + else: + localembed = _embeds.build_embed(ctx.guild.id, embed_name=embed_name) + await ctx.respond(f"## :white_check_mark: New field successfully added to server embed `{embed_name}\nHere's a preview of your modified embed:`", embed=localembed) + + @embed_system.command( + name="add_embed_author", + description="Add or replace the author section of an existing server embed." + ) + @commands.guild_only() + @option(name="embed_name", description="The server embed to which you want to add the author", type=str) + @option(name="author_name", description="The name of the author.", type=str) + @option(name="url", description="Attach a url to the author name. (https:// only)", type=str, default=None) + @option(name="icon_url", description="Add an icon next to the author (https:// only)", type=str, default=None) + async def embeds_add_embed_author(self, ctx: ApplicationContext, embed_name: str, author_name: str, url: str = None, icon_url: str = None): + """Add or replace the author section of an existing server embed.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond( + "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", + ephemeral=True + ) + result_code = _embeds.add_embed_author(ctx.guild.id, embed_name=embed_name, name=author_name, url=url, icon_url=icon_url) + if result_code == 1: + localembed = discord.Embed( + title=":x: Failed to add author to embed", + description=f"This server does not have an embed with the name `{embed_name}`.", + color=discord.Color.red() + ) + return await ctx.respond(embed=localembed, ephemeral=True) + else: + localembed = _embeds.build_embed(ctx.guild.id, embed_name=embed_name) + await ctx.respond(f"## :white_check_mark: Author section successfully added to server embed `{embed_name}\nHere's a preview of your modified embed:`", embed=localembed) + + @embed_system.command( + name="add_embed_footer", + description="Add or replace the footer of an existing server embed." + ) + @commands.guild_only() + @option(name="embed_name", description="The server embed to which you want to add the author", type=str) + @option(name="text", description="The text you want to display in the footer.", type=str) + @option(name="icon_url", description="Add an icon in the footer of the embed. (https:// only)", type=str, default=None) + async def embeds_add_embed_author(self, ctx: ApplicationContext, embed_name: str, text: str, icon_url: str = None): + """Add or replace the footer of an existing server embed.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond( + "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", + ephemeral=True + ) + result_code = _embeds.add_embed_footer(ctx.guild.id, embed_name=embed_name, text=text, icon_url=icon_url) + if result_code == 1: + localembed = discord.Embed( + title=":x: Failed to add footer to embed", + description=f"This server does not have an embed with the name `{embed_name}`.", + color=discord.Color.red() + ) + return await ctx.respond(embed=localembed, ephemeral=True) + else: + localembed = _embeds.build_embed(ctx.guild.id, embed_name=embed_name) + await ctx.respond(f"## :white_check_mark: Footer section successfully added to server embed `{embed_name}\nHere's a preview of your modified embed:`", embed=localembed) + + # TODO: Make the following bot commands: + # - create new embed (done) + # - delete embed (done) + # - show embeds list (done) + # - add embed field (done) + # - add embed author (done) + # - add embed footer (done) + + # Isobot Command Registry Management System commandmanager = SlashCommandGroup("commandmanager", "Manage isobot's command registry.") @commandmanager.command( From 2660a36b6892fc0180bf6830f199500cf6daa6d8 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 29 Oct 2024 21:54:38 +0530 Subject: [PATCH 18/26] Remove a completed todo list --- cogs/utils.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cogs/utils.py b/cogs/utils.py index 45433668..4c937d96 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -522,14 +522,6 @@ async def embeds_add_embed_author(self, ctx: ApplicationContext, embed_name: str localembed = _embeds.build_embed(ctx.guild.id, embed_name=embed_name) await ctx.respond(f"## :white_check_mark: Footer section successfully added to server embed `{embed_name}\nHere's a preview of your modified embed:`", embed=localembed) - # TODO: Make the following bot commands: - # - create new embed (done) - # - delete embed (done) - # - show embeds list (done) - # - add embed field (done) - # - add embed author (done) - # - add embed footer (done) - # Isobot Command Registry Management System commandmanager = SlashCommandGroup("commandmanager", "Manage isobot's command registry.") From 1a499cc7377685622a5829621455f4df54a18f55 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Tue, 29 Oct 2024 22:03:30 +0530 Subject: [PATCH 19/26] Remove resolved todo comment --- cogs/utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cogs/utils.py b/cogs/utils.py index 4c937d96..3f6d2931 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -346,8 +346,6 @@ async def serverinfo(self, ctx: ApplicationContext): # Server Embed System Manager Commands embed_system = SlashCommandGroup("embeds", "Commands used to add, edit and remove custom bot embeds for server-wide use.") - # TODO: Add commands for managing server embeds - @embed_system.command( name="create", description="Create a new custom embed for the server." From fb5d8f43ca3f4c2c8808a8b83946dfa93c6b4b5f Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:03:53 +0530 Subject: [PATCH 20/26] Remove old unused piece of code --- cogs/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index 3f6d2931..8d2b7944 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -23,7 +23,6 @@ levelling = levelling.Levelling() _commands = cmds.Commands() _embeds = _embeds.Embeds() -# openai.api_key = os.getenv("chatgpt_API_KEY") openai.api_key = auth.ext_token('chatgpt') chatgpt_conversation = dict() _presence = Presence() From e95ca6f562e339e9e4544274ab8be3e59bfa1e03 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:38:44 +0530 Subject: [PATCH 21/26] Add a missing argument to `get_embeds_list()` --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index 8d2b7944..72d86bd8 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -422,7 +422,7 @@ async def embeds_list(self, ctx: ApplicationContext): "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", ephemeral=True ) - embeds_list = _embeds.get_embeds_list() + embeds_list = _embeds.get_embeds_list(ctx.guild.id) num = 0 parsed_output = str() for embed in embeds_list.keys(): From 7ab10e2fc8b1222e66e070e0fa438282b7aabbaf Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:40:00 +0530 Subject: [PATCH 22/26] Add framework db module function to generate missing data keys for server ids --- framework/isobot/db/embeds.py | 11 +++++++++++ main.py | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 74d9b6cc..0847e4b7 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -22,6 +22,15 @@ def save(self, data: dict) -> int: with open("database/embeds.json", 'w+', encoding="utf8") as f: json.dump(data, f) return 0 + def generate_server_key(self, server_id: Union[str, int]) -> int: + """Creates a new data key for the specified server in the embeds database.\n\nReturns `0` if successful, returns `1` if the server already exists in the database.""" + embeds = self.load() + if str(server_id) not in embeds.keys(): + embeds[str(server_id)] = {} + self.save() + return 0 + return 1 + def get_embeds_list(self, server_id: Union[str, int]) -> dict: """Fetches a `dict` of all the added embeds in the specified server.\n\nReturns an empty `dict` if none are set up.""" embeds = self.load() @@ -43,6 +52,8 @@ def generate_embed( ) -> int: """Generates an embed for the specified server using the given embed data.\n\nReturns `0` if successful, returns `1` if an embed with the same embed name already exists, returns `2` if the specified embed color is not a valid hex code.""" embeds = self.load() + + self.generate_server_key(server_id) if embed_name not in embeds[str(server_id)].keys(): # Check whether color code is a valid value or not diff --git a/main.py b/main.py index ae75da3e..9202b0d3 100644 --- a/main.py +++ b/main.py @@ -13,7 +13,7 @@ from random import randint from framework.isobot import currency, colors, settings, commands as _commands from framework.isobot.shop import ShopData -from framework.isobot.db import levelling, items, userdata, automod, weather, warnings, presence as _presence, serverconfig +from framework.isobot.db import levelling, items, userdata, automod, weather, warnings, presence as _presence, serverconfig, embeds from discord import ApplicationContext, option from discord.ext import commands from cogs.isocoin import create_isocoin_key @@ -123,6 +123,7 @@ def initial_setup(): automod = automod.Automod() _presence = _presence.Presence() weather = weather.Weather() +embeds = embeds.Embeds() _commands = _commands.Commands() shop_data = ShopData("config/shop.json") @@ -246,6 +247,7 @@ async def on_message(ctx): try: automod.generate(ctx.guild.id) serverconfig.generate(ctx.guild.id) + embeds.generate_server_key(ctx.guild.id) warningsdb.generate(ctx.guild.id, ctx.author.id) except AttributeError: pass From 8a48dd1b41074cd58eb7130217d93477796a12d1 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:41:34 +0530 Subject: [PATCH 23/26] Add another missing argument --- framework/isobot/db/embeds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index 0847e4b7..c3e624f8 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -27,7 +27,7 @@ def generate_server_key(self, server_id: Union[str, int]) -> int: embeds = self.load() if str(server_id) not in embeds.keys(): embeds[str(server_id)] = {} - self.save() + self.save(embeds) return 0 return 1 From 560701dc2493c01f3c731d8bb306955cef7febda Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:09:42 +0530 Subject: [PATCH 24/26] Fix a few minor bugs here and there --- cogs/utils.py | 5 +++-- framework/isobot/db/embeds.py | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/cogs/utils.py b/cogs/utils.py index 72d86bd8..c9e65407 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -376,9 +376,10 @@ async def embeds_create(self, ctx: ApplicationContext, embed_name: str, title: s image_url=image_url, thumbnail=thumbnail ) + new_embed = _embeds.build_embed(ctx.guild.id, embed_name) await ctx.respond( f"## :white_check_mark: Embed Successfully Created.\nThe name of this custom embed is `{embed_name}`. You can use this embed name to reference this custom embed in other commands.\n\nHere's a preview of your new embed:", - embed=_embeds.build_embed(ctx.guild.id, embed_name) + embed=new_embed ) @embed_system.command( @@ -462,7 +463,7 @@ async def embeds_add_embed_field(self, ctx: ApplicationContext, embed_name: str, return await ctx.respond(embed=localembed, ephemeral=True) else: localembed = _embeds.build_embed(ctx.guild.id, embed_name=embed_name) - await ctx.respond(f"## :white_check_mark: New field successfully added to server embed `{embed_name}\nHere's a preview of your modified embed:`", embed=localembed) + await ctx.respond(f"## :white_check_mark: New field successfully added to server embed `{embed_name}`\nHere's a preview of your modified embed:", embed=localembed) @embed_system.command( name="add_embed_author", diff --git a/framework/isobot/db/embeds.py b/framework/isobot/db/embeds.py index c3e624f8..7979a81a 100644 --- a/framework/isobot/db/embeds.py +++ b/framework/isobot/db/embeds.py @@ -57,8 +57,8 @@ def generate_embed( if embed_name not in embeds[str(server_id)].keys(): # Check whether color code is a valid value or not - if color not in [-1, 0] or not framework.types.is_hex_color_code(color): - return 2 + #if color not in [-1, 0] or not framework.types.is_hex_color_code(color): + # return 2 embeds[str(server_id)][embed_name] = { "title": title, @@ -82,6 +82,12 @@ def build_embed(self, server_id: Union[str, int], embed_name: str) -> discord.Em if embed_name in embeds[str(server_id)].keys(): embed_data = embeds[str(server_id)][embed_name] + title = embed_data["title"] + description = embed_data["description"] + color = embed_data["color"] + title_url = embed_data["title_url"] + image_url = embed_data["image_url"] + thumbnail = embed_data["thumbnail"] if embed_data["title"] == None: title = discord.Embed.Empty if embed_data["description"] == None: description = discord.Embed.Empty if embed_data["color"] == None: color = discord.Embed.Empty @@ -92,7 +98,7 @@ def build_embed(self, server_id: Union[str, int], embed_name: str) -> discord.Em embed = discord.Embed( title=title, description=description, - color = discord.Color.random() if embed_data["color"] == -1 else embed_data["color"], + color = discord.Color.random() if embed_data["color"] == -1 else color, url=title_url, timestamp = datetime.datetime.utcnow() if embed_data["timestamp_enabled"] else discord.Embed.Empty ) @@ -101,12 +107,14 @@ def build_embed(self, server_id: Union[str, int], embed_name: str) -> discord.Em for field in embed_data["fields"]: embed.add_field( - name=embed_data["fields"][field]["name"], - value=embed_data["fields"][field]["value"], - inline=embed_data["fields"][field]["inline"] + name=field["name"], + value=field["value"], + inline=field["inline"] ) if embed_data["author"] != {}: + author_url = embed_data["author"]["url"] + author_icon_url = embed_data["author"]["icon_url"] if embed_data["author"]["url"] == None: author_url = discord.Embed.Empty if embed_data["author"]["icon_url"] == None: author_icon_url = discord.Embed.Empty embed.set_author(name=embed_data["author"]["name"], url=author_url, icon_url=author_icon_url) @@ -138,7 +146,7 @@ def add_embed_field( """Adds a new field to an already existing embed.\n\nReturns `0` if successful, returns `1` if the embed does not exist.""" embeds = self.load() if embed_name in embeds[str(server_id)].keys(): - list(embeds[str(server_id)][embed_name]["fields"]).append( + embeds[str(server_id)][embed_name]["fields"].append( { "name": name, "value": value, From 6f27b8e26d960cc9a6dfae2bac39e8c1513a35dd Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:17:58 +0530 Subject: [PATCH 25/26] Add `/embeds view` to allow users to quickly view server embeds --- cogs/utils.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cogs/utils.py b/cogs/utils.py index c9e65407..b60ec27a 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -435,8 +435,28 @@ async def embeds_list(self, ctx: ApplicationContext): title=f"Custom Server Embeds for **{ctx.guild.name}**", description=parsed_output ) + localembed.set_footer(text="Run \"/embeds view \" to get a preview of an embed.") await ctx.respond(embed=localembed) + @embed_system( + name="view", + description="See a preview of an existing custom embed in the server." + ) + @commands.guild_only() + @option(name="embed_name", description="The server embed that you want to view.", type=str) + async def embeds_view(self, ctx: ApplicationContext, embed_name: str): + """See a preview of an existing custom embed in the server.""" + if not ctx.author.guild_permissions.manage_messages: + return await ctx.respond( + "You can't use this command! You need the `Manage Messages` permission in this server to run this command.", + ephemeral=True + ) + embed_preview = _embeds.build_embed(ctx.guild.id, embed_name=embed_name) + await ctx.respond( + f"Here's a preview of the server embed `{embed_name}`:", + embed=embed_preview + ) + @embed_system.command( name="add_embed_field", description="Appends a new field to an existing server embed." From f1ece4b4dc9172ebfea732ecfa871fbd3ea8f5a5 Mon Sep 17 00:00:00 2001 From: snipe <72265661+notsniped@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:20:32 +0530 Subject: [PATCH 26/26] Add a missing piece of code to command header --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index b60ec27a..4e022658 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -438,7 +438,7 @@ async def embeds_list(self, ctx: ApplicationContext): localembed.set_footer(text="Run \"/embeds view \" to get a preview of an embed.") await ctx.respond(embed=localembed) - @embed_system( + @embed_system.command( name="view", description="See a preview of an existing custom embed in the server." )