GoldyBot

πŸ’™ Goldy Bot V4 - BIG and Modern rewrite of Goldy Bot V3

Copyright (C) 2022 - Dev Goldy


Powered by Nextcord Pypi Badge Python Badge Docs Badge

 1"""
 2πŸ’™ Goldy Bot V4 - BIG and Modern rewrite of Goldy Bot V3
 3
 4Copyright (C) 2022 - Dev Goldy
 5
 6----------------------------
 7.. include:: ../docs_template/README.md
 8"""
 9
10import sys
11import nextcord
12import asyncio
13import nest_asyncio
14
15from .objects import *
16from .errors import *
17
18from . import database
19from . import files, paths, logging, goldy, cache, token, settings, config, info, modules, system, assets
20from . import internal_modules, ext, utility, objects
21from .ext.events import *
22
23from nextcord.ext.commands import Context
24
25# Functions
26log = logging.print_and_log
27"""Shortcut of ``GoldyBot.logging.log``"""
28
29# Function Decorators
30command = ext.commands.command
31"""Shortcut of object from ``GoldyBot.ext.commands``"""
32cmd = command
33"""Alias of object from ``GoldyBot.ext.commands``"""
34
35# Class Inheritors
36Extension = ext.extensions.Extension
37"""Shortcut of object from ``GoldyBot.ext.extensions``"""
38
39setattr(sys.modules[__name__], 'Extenstion', Extension) # Stops Goldy Bot extensions made before the dev21 update from crashing because of my STUPID typo.
40
41# Classes
42Goldy = goldy.Goldy
43"""Shortcut of object from ``GoldyBot.goldy``"""
44Database = database.Database
45"""Shortcut of ``GoldyBot.database.Database``"""
46Embed = utility.goldy.embed.Embed
47"""Shortcut of object from ``GoldyBot.utility.goldy.embed``"""
48GuildEvent = utility.guild_events.GuildEvent
49"""Shortcut of object from ``GoldyBot.utility.guild_events.GuildEvent``"""
50File = files.File
51"""Shortcut of object from ``GoldyBot.files.File``"""
52WebFile = files.WebFile
53"""Shortcut of object from ``GoldyBot.files.WebFile``"""
54
55# Async Loop
56async_loop = asyncio.get_event_loop()
57"""
58Goldy Bot's async loop. You can use this to run async methods in non async functions.
59Like this ``async_loop.run_until_complete(async_function())``
60"""
61nest_asyncio.apply(async_loop)
62
63# Colours
64Colours = utility.goldy.colours.Colours
65"""Shortcut of object from ``GoldyBot.utility.goldy.colours``"""
66
67Colors = utility.goldy.colours.Colors
68"""Alias of ``GoldyBot.Colours``"""
69
70# Stops Goldy Bot extensions made before the dev24 update from crashing. ('Colours' used to be all lowercase in previous versions.)
71setattr(sys.modules[__name__], 'colours', Colours) 
72setattr(sys.modules[__name__], 'colors', Colors) 
73
74# Hearts
75Hearts = utility.goldy.hearts.Hearts
76"""Shortcut of object from ``GoldyBot.utility.goldy.hearts``"""
77
78# Goldy Bot Currencies
79Currencies = utility.goldy.currencies.Currencies
80"""Shortcut of object from ``GoldyBot.utility.goldy.currencies``"""
81
82# User Input
83user_input = utility.user_input
84"""Shortcut of module ``GoldyBot.utility.user_input``"""
def log(importance_level=None, text=None, no_traceback=False):
 12def print_and_log(importance_level=None, text=None, no_traceback=False):
 13    """Goldy Bot's Print statement. PLEASE use this statement instead of the usual 'print()'."""
 14    if text == None: # Just makes a new line.
 15        if importance_level == None:
 16            print("")
 17            path_to_log = write_to_log("")
 18            return path_to_log
 19
 20        if isinstance(importance_level, GoldyBot.errors.GoldyBotError):
 21            time = get_time_and_date("time")
 22            context = ("({}) [ERROR] {}".format(time, text))
 23            print(f"\u001b[31m{context} \n{traceback.format_exc()}\u001b[0m") #Red
 24            write_to_log(f"{context}\n\n{traceback.format_exc()}")
 25            return
 26
 27        else:
 28            time = get_time_and_date("time")
 29            context = ("({}) {}".format(time, importance_level))
 30
 31            print(f"\u001b[37m{context}\u001b[0m")
 32            
 33            path_to_log = write_to_log(context)
 34            return path_to_log
 35
 36    if not text == None:
 37        if importance_level == None:
 38            time = get_time_and_date("time")
 39            context = ("({}) {}".format(time, text))
 40
 41            print(f"\u001b[37m{context}\u001b[0m")
 42            write_to_log(context)
 43            return
 44
 45        if importance_level.upper() == 'INFO':
 46            time = get_time_and_date("time")
 47            context = ("({}) [INFO] {}".format(time, text))
 48
 49            print(f"\u001b[36m{context}\u001b[0m") # Blue
 50            write_to_log(context)
 51            return
 52
 53        if importance_level.upper() == 'INFO_2':
 54            time = get_time_and_date("time")
 55            context = ("({}) [INFO] {}".format(time, text))
 56
 57            print(f"\u001b[32m{context}\u001b[0m") # Green
 58            write_to_log(context)
 59            return
 60
 61        if importance_level.upper() == 'INFO_3':
 62            time = get_time_and_date("time")
 63            context = ("({}) [INFO] {}".format(time, text))
 64
 65            print(f"\u001b[38;5;51m{context}\u001b[0m") # Clay
 66            write_to_log(context)
 67            return
 68
 69        if importance_level.upper() == 'INFO_4':
 70            time = get_time_and_date("time")
 71            context = ("({}) [INFO] {}".format(time, text))
 72
 73            print(f"\u001b[38;5;200m{context}\u001b[0m") # Purple
 74            write_to_log(context)
 75            return
 76
 77        if importance_level.upper() == 'INFO_5':
 78            time = get_time_and_date("time")
 79            context = ("({}) [INFO] {}".format(time, text))
 80
 81            print(f"\u001b[38;5;139m{context}\u001b[0m") # Pink Grey
 82            write_to_log(context)
 83            return
 84
 85        if importance_level.upper() == 'WARN':
 86            time = get_time_and_date("time")
 87            context = ("({}) [WARN] {}".format(time, text))
 88            
 89            if not no_traceback:
 90                print(f"\u001b[33m{context}\u001b[0m") #Yellow
 91            write_to_log(f"{context}\n\n{traceback.format_exc()}")
 92            return
 93
 94
 95        if importance_level.upper() == 'ERROR':
 96            time = get_time_and_date("time")
 97            context = ("({}) [ERROR] {}".format(time, text))
 98            if not no_traceback:
 99                print(f"\u001b[31m{context} \n{traceback.format_exc()}\u001b[0m") #Red
100            write_to_log(f"{context}\n\n{traceback.format_exc()}")
101            return
102
103        if importance_level.upper() == 'APP_NAME':
104            context = (text)
105
106            print(f"\u001b[36m{context}\u001b[0m")
107            write_to_log(context)
108            return
def command( command_name: str = None, required_roles: list = [], help_des: str = None, hidden=False, slash_cmd_only=False, normal_cmd_only=False, slash_options: Dict[str, nextcord.application_command.SlashOption] = {}):
 13def command(command_name:str=None, required_roles:list=[], help_des:str=None, hidden=False, slash_cmd_only=False, normal_cmd_only=False, slash_options:Dict[str, nextcord.SlashOption]={}):
 14    """
 15    Add a command to Goldy Bot with this decorator.
 16    
 17    ---------------
 18    ### ***``Example:``***
 19
 20    This is how you create a command in GoldyBot. πŸ˜€
 21
 22    ```python
 23    @GoldyBot.command()
 24    async def uwu(ctx):
 25        await ctx.send(f'Hi, {ctx.author.mention}! UwU!')
 26    ```
 27    """
 28    def decorate(func):
 29        def inner(func, command_name, required_roles, help_des, hidden, slash_cmd_only, normal_cmd_only, slash_options) -> GoldyBot.objects.command.Command:
 30            func:function = func
 31            
 32            goldy_command = GoldyBot.objects.command.Command(func, command_name=command_name, required_roles=required_roles, slash_options=slash_options, help_des=help_des, hidden=hidden)
 33            print(goldy_command.params)
 34
 35            if command_name == None: command_name = goldy_command.code_name
 36
 37            toggle_slash_cmd = True
 38            toggle_normal_cmd = True
 39
 40            if slash_cmd_only == True: toggle_normal_cmd = False
 41            if normal_cmd_only == True: toggle_slash_cmd = False
 42
 43            #  Add command to nextcord.
 44            #============================
 45            # Grab client object from cache.
 46            client:commands.Bot = GoldyBot.cache.main_cache_dict["client"]
 47            
 48            # Get command's arguments.
 49            params = goldy_command.params
 50
 51            # Create command usage embed.
 52            command_usage_args = f"!{command_name}"
 53            for param in params[1:]:
 54                command_usage_args += (" {" + param + "}")
 55
 56            command_usage_embed = GoldyBot.utility.goldy.embed.Embed(title=GoldyBot.utility.msgs.bot.CommandUsage.Embed.title)
 57            command_usage_embed.set_thumbnail(url=GoldyBot.utility.msgs.bot.CommandUsage.Embed.thumbnail)
 58
 59            no_perms_embed = GoldyBot.utility.goldy.embed.Embed(title=GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.title)
 60            no_perms_embed.color = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.colour
 61            no_perms_embed.set_thumbnail(url=GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.thumbnail)
 62
 63            guild_not_registered_embed = GoldyBot.utility.goldy.embed.Embed(title=GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.title)
 64            guild_not_registered_embed.color = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.colour
 65            guild_not_registered_embed.set_thumbnail(url=GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.thumbnail)
 66
 67            # Preparing to add command.
 68            # Checking if this command is in an extension.
 69            is_in_extension = goldy_command.in_extension
 70            class_ = goldy_command.extension
 71
 72            if not params[0] == "ctx": # Check if command has 'ctx' as first argument.
 73                GoldyBot.logging.log("warn", f"Failed to load the command '{command_name}', it must contain 'ctx' as it's first argument!")
 74                return None
 75
 76            # Add command.
 77            #----------------
 78            if toggle_normal_cmd:
 79                GoldyBot.logging.log(f"[{MODULE_NAME}] [{command_name.upper()}] Creating normal command...")
 80                if is_in_extension == True: # Run in EXTENSION!
 81                    @client.command(name=command_name, help_message=help_des)
 82                    async def command_(ctx=params[0], *params):
 83                        command_usage_embed.description = GoldyBot.utility.msgs.bot.CommandUsage.Embed.des.format(ctx.author.mention, command_usage_args)
 84
 85                        #Run command.
 86                        try:
 87                            if goldy_command.allowed_to_run(ctx):
 88                                await func(class_, ctx, *params)
 89                                GoldyBot.logging.log(f"[{MODULE_NAME}] The command '{goldy_command.code_name}' was executed.")
 90                        
 91                        except TypeError as e: 
 92                            if not goldy_command.any_args_missing(params): # Command Arguments are missing.
 93                                message = await ctx.send(embed=command_usage_embed)
 94                                await asyncio.sleep(15)
 95                                await message.delete()                    
 96
 97                            else: # Then it's an actual error.
 98                                GoldyBot.logging.log("error", e)
 99
100                        except MemberHasNoPermsForCommand:
101                            if hidden == False:
102                                no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention)
103                                message = await ctx.send(embed=no_perms_embed)
104                                await asyncio.sleep(15)
105                                await message.delete()
106
107                        except GuildNotRegistered:
108                            if hidden == False:
109                                guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention)
110                                message = await ctx.send(embed=guild_not_registered_embed)
111                                await asyncio.sleep(15)
112                                await message.delete()
113                                
114                        except Exception as e:
115                            GoldyBot.logging.log("error", e)
116
117                else: # Run as NORMAL command!
118                    @client.command(name=command_name, help_message=help_des)
119                    async def command_(ctx=params[0], *params):
120                        command_usage_embed.description = GoldyBot.utility.msgs.bot.CommandUsage.Embed.des.format(ctx.author.mention, command_usage_args)
121
122                        # Run command.
123                        try: 
124                            if goldy_command.allowed_to_run(ctx):
125                                await func(ctx, *params)
126                                GoldyBot.logging.log(f"[{MODULE_NAME}] The command '{goldy_command.code_name}' was executed.")
127                        
128                        except TypeError as e:
129                            if not goldy_command.any_args_missing(params): # Command Arguments are missing.
130                                message = await ctx.send(embed=command_usage_embed)
131                                await asyncio.sleep(15)
132                                await message.delete()
133
134                            else: # Then it's an actual error.
135                                GoldyBot.logging.log("error", e)
136
137                        except MemberHasNoPermsForCommand:
138                            if hidden == False:
139                                message = await ctx.send(embed=no_perms_embed)
140                                await asyncio.sleep(6)
141                                await message.delete()
142
143                        except GuildNotRegistered:
144                            if hidden == False:
145                                message = await ctx.send(embed=guild_not_registered_embed)
146                                await asyncio.sleep(15)
147                                await message.delete()
148
149                        except Exception as e:
150                            GoldyBot.logging.log("error", e)
151                GoldyBot.logging.log(f"[{MODULE_NAME}] [{command_name.upper()}] Normal command created!")
152
153            # Add slash command
154            #--------------------
155            if toggle_slash_cmd:
156                GoldyBot.logging.log(f"[{MODULE_NAME}] [{command_name.upper()}] Creating slash command...")
157                goldy_command.create_slash()
158            GoldyBot.logging.log("info_3", f"[{MODULE_NAME}] Command '{command_name}' has been loaded.")
159
160            return goldy_command
161
162        return inner(func, command_name, required_roles, help_des, hidden, slash_cmd_only, normal_cmd_only, slash_options)
163
164    return decorate

Shortcut of object from GoldyBot.ext.commands

def cmd( command_name: str = None, required_roles: list = [], help_des: str = None, hidden=False, slash_cmd_only=False, normal_cmd_only=False, slash_options: Dict[str, nextcord.application_command.SlashOption] = {}):
 13def command(command_name:str=None, required_roles:list=[], help_des:str=None, hidden=False, slash_cmd_only=False, normal_cmd_only=False, slash_options:Dict[str, nextcord.SlashOption]={}):
 14    """
 15    Add a command to Goldy Bot with this decorator.
 16    
 17    ---------------
 18    ### ***``Example:``***
 19
 20    This is how you create a command in GoldyBot. πŸ˜€
 21
 22    ```python
 23    @GoldyBot.command()
 24    async def uwu(ctx):
 25        await ctx.send(f'Hi, {ctx.author.mention}! UwU!')
 26    ```
 27    """
 28    def decorate(func):
 29        def inner(func, command_name, required_roles, help_des, hidden, slash_cmd_only, normal_cmd_only, slash_options) -> GoldyBot.objects.command.Command:
 30            func:function = func
 31            
 32            goldy_command = GoldyBot.objects.command.Command(func, command_name=command_name, required_roles=required_roles, slash_options=slash_options, help_des=help_des, hidden=hidden)
 33            print(goldy_command.params)
 34
 35            if command_name == None: command_name = goldy_command.code_name
 36
 37            toggle_slash_cmd = True
 38            toggle_normal_cmd = True
 39
 40            if slash_cmd_only == True: toggle_normal_cmd = False
 41            if normal_cmd_only == True: toggle_slash_cmd = False
 42
 43            #  Add command to nextcord.
 44            #============================
 45            # Grab client object from cache.
 46            client:commands.Bot = GoldyBot.cache.main_cache_dict["client"]
 47            
 48            # Get command's arguments.
 49            params = goldy_command.params
 50
 51            # Create command usage embed.
 52            command_usage_args = f"!{command_name}"
 53            for param in params[1:]:
 54                command_usage_args += (" {" + param + "}")
 55
 56            command_usage_embed = GoldyBot.utility.goldy.embed.Embed(title=GoldyBot.utility.msgs.bot.CommandUsage.Embed.title)
 57            command_usage_embed.set_thumbnail(url=GoldyBot.utility.msgs.bot.CommandUsage.Embed.thumbnail)
 58
 59            no_perms_embed = GoldyBot.utility.goldy.embed.Embed(title=GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.title)
 60            no_perms_embed.color = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.colour
 61            no_perms_embed.set_thumbnail(url=GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.thumbnail)
 62
 63            guild_not_registered_embed = GoldyBot.utility.goldy.embed.Embed(title=GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.title)
 64            guild_not_registered_embed.color = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.colour
 65            guild_not_registered_embed.set_thumbnail(url=GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.thumbnail)
 66
 67            # Preparing to add command.
 68            # Checking if this command is in an extension.
 69            is_in_extension = goldy_command.in_extension
 70            class_ = goldy_command.extension
 71
 72            if not params[0] == "ctx": # Check if command has 'ctx' as first argument.
 73                GoldyBot.logging.log("warn", f"Failed to load the command '{command_name}', it must contain 'ctx' as it's first argument!")
 74                return None
 75
 76            # Add command.
 77            #----------------
 78            if toggle_normal_cmd:
 79                GoldyBot.logging.log(f"[{MODULE_NAME}] [{command_name.upper()}] Creating normal command...")
 80                if is_in_extension == True: # Run in EXTENSION!
 81                    @client.command(name=command_name, help_message=help_des)
 82                    async def command_(ctx=params[0], *params):
 83                        command_usage_embed.description = GoldyBot.utility.msgs.bot.CommandUsage.Embed.des.format(ctx.author.mention, command_usage_args)
 84
 85                        #Run command.
 86                        try:
 87                            if goldy_command.allowed_to_run(ctx):
 88                                await func(class_, ctx, *params)
 89                                GoldyBot.logging.log(f"[{MODULE_NAME}] The command '{goldy_command.code_name}' was executed.")
 90                        
 91                        except TypeError as e: 
 92                            if not goldy_command.any_args_missing(params): # Command Arguments are missing.
 93                                message = await ctx.send(embed=command_usage_embed)
 94                                await asyncio.sleep(15)
 95                                await message.delete()                    
 96
 97                            else: # Then it's an actual error.
 98                                GoldyBot.logging.log("error", e)
 99
100                        except MemberHasNoPermsForCommand:
101                            if hidden == False:
102                                no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention)
103                                message = await ctx.send(embed=no_perms_embed)
104                                await asyncio.sleep(15)
105                                await message.delete()
106
107                        except GuildNotRegistered:
108                            if hidden == False:
109                                guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention)
110                                message = await ctx.send(embed=guild_not_registered_embed)
111                                await asyncio.sleep(15)
112                                await message.delete()
113                                
114                        except Exception as e:
115                            GoldyBot.logging.log("error", e)
116
117                else: # Run as NORMAL command!
118                    @client.command(name=command_name, help_message=help_des)
119                    async def command_(ctx=params[0], *params):
120                        command_usage_embed.description = GoldyBot.utility.msgs.bot.CommandUsage.Embed.des.format(ctx.author.mention, command_usage_args)
121
122                        # Run command.
123                        try: 
124                            if goldy_command.allowed_to_run(ctx):
125                                await func(ctx, *params)
126                                GoldyBot.logging.log(f"[{MODULE_NAME}] The command '{goldy_command.code_name}' was executed.")
127                        
128                        except TypeError as e:
129                            if not goldy_command.any_args_missing(params): # Command Arguments are missing.
130                                message = await ctx.send(embed=command_usage_embed)
131                                await asyncio.sleep(15)
132                                await message.delete()
133
134                            else: # Then it's an actual error.
135                                GoldyBot.logging.log("error", e)
136
137                        except MemberHasNoPermsForCommand:
138                            if hidden == False:
139                                message = await ctx.send(embed=no_perms_embed)
140                                await asyncio.sleep(6)
141                                await message.delete()
142
143                        except GuildNotRegistered:
144                            if hidden == False:
145                                message = await ctx.send(embed=guild_not_registered_embed)
146                                await asyncio.sleep(15)
147                                await message.delete()
148
149                        except Exception as e:
150                            GoldyBot.logging.log("error", e)
151                GoldyBot.logging.log(f"[{MODULE_NAME}] [{command_name.upper()}] Normal command created!")
152
153            # Add slash command
154            #--------------------
155            if toggle_slash_cmd:
156                GoldyBot.logging.log(f"[{MODULE_NAME}] [{command_name.upper()}] Creating slash command...")
157                goldy_command.create_slash()
158            GoldyBot.logging.log("info_3", f"[{MODULE_NAME}] Command '{command_name}' has been loaded.")
159
160            return goldy_command
161
162        return inner(func, command_name, required_roles, help_des, hidden, slash_cmd_only, normal_cmd_only, slash_options)
163
164    return decorate

Alias of object from GoldyBot.ext.commands

class Extension:
  7class Extension(object):
  8    """
  9    The base class for a Goldy Bot extension.
 10
 11    ---------------
 12    ### ***``Example:``***
 13
 14    This is how you set up an extension in a GoldyBot module. 😍
 15
 16    ```python
 17    class YourExtension(GoldyBot.Extension):
 18        def __init__(self, package_module=None):
 19            super().__init__(self, package_module_name=package_module)
 20
 21        def loader(self):
 22
 23            @GoldyBot.command()
 24            async def uwu(self:YourExtension, ctx):
 25                await ctx.send(f'Hi, {ctx.author.mention}! UwU!')
 26
 27    def load():
 28        YourExtension(package_module_name=__name__)
 29        pass
 30    ```
 31    """
 32
 33    def __init__(self, class_object, package_module_name:str=None):
 34        """Tells Goldy Bot to Load this class as an extension."""
 35        self.class_object:object = class_object
 36        self.module_name_ = package_module_name
 37        self.ignored_extensions_list = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)).read("ignored_extensions")
 38        
 39        try:
 40            if not self.code_name in self.ignored_extensions_list:
 41                # Cache it.
 42                #------------
 43                try:
 44                    if self.module.is_internal_module:
 45                        GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"] = {}
 46                        GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["commands"] = []
 47                        GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["object"] = self
 48                    else:
 49                        GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"] = {}
 50                        GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["commands"] = []
 51                        GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["object"] = self
 52                except AttributeError:
 53                    GoldyBot.logging.log("error", f"""[{MODULE_NAME}] Did you specify the module name when loading this extension. Looks like the module '{self.module_name}' did not get loaded by Goldy Bot. 
 54                    Perhaps this is a package module and you forgot to specify the module name when loading this extension.\n""")
 55                    
 56                    GoldyBot.Goldy().stop(f"I think you forgot to specify the module name when loading the '{self.code_name}' extension.")
 57
 58                GoldyBot.logging.log(f"[{self.code_name}] Loading my commands...")
 59                self.loader() # Load commands.
 60
 61            else:
 62                GoldyBot.logging.log("info", f"[{class_object.__class__.__name__}] Not loading commands as this extension is ignored.")
 63
 64        except TypeError as e:
 65            what_is_incorrect = None
 66
 67            if self.ignored_extensions_list == None: what_is_incorrect = "ignored_extensions"
 68
 69            raise GoldyBot.errors.ConfigIsIncorrect(e, what_is_incorrect)
 70
 71        # Setting all variable shortcuts.
 72        #-----------------------------------
 73        self.client:GoldyBot.nextcord.Client = GoldyBot.cache.main_cache_dict["client"]
 74        self.database:GoldyBot.database.Database = GoldyBot.cache.main_cache_dict["database"]
 75
 76        self.FindGuilds = GoldyBot.cache.FindGuilds()
 77
 78        self.msg = GoldyBot.utility.msgs
 79
 80    @property
 81    def code_name(self):
 82        return self.class_object.__class__.__name__
 83
 84    @property
 85    def module_name(self):
 86        """Returns the name of the module this extension is being called from. This is much faster than grabbing the name with ``module().name``."""
 87        if self.module_name_ == None:
 88            return self.class_object.__module__
 89        else:
 90            return self.module_name_
 91
 92    @property
 93    def module(self) -> GoldyBot.modules.Module:
 94        return GoldyBot.cache.FindModules().find_object_by_module_name(self.module_name)
 95
 96    def loader(self):
 97        """The extension's command loader. This is what Goldy Bot uses to load your commands in an extension."""
 98        pass
 99
100    def get_object(self):
101        """Returns the actual class object of the extension."""
102        return self.class_object

Shortcut of object from GoldyBot.ext.extensions

Extension(class_object, package_module_name: str = None)
33    def __init__(self, class_object, package_module_name:str=None):
34        """Tells Goldy Bot to Load this class as an extension."""
35        self.class_object:object = class_object
36        self.module_name_ = package_module_name
37        self.ignored_extensions_list = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)).read("ignored_extensions")
38        
39        try:
40            if not self.code_name in self.ignored_extensions_list:
41                # Cache it.
42                #------------
43                try:
44                    if self.module.is_internal_module:
45                        GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"] = {}
46                        GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["commands"] = []
47                        GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["object"] = self
48                    else:
49                        GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"] = {}
50                        GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["commands"] = []
51                        GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.code_name}"]["object"] = self
52                except AttributeError:
53                    GoldyBot.logging.log("error", f"""[{MODULE_NAME}] Did you specify the module name when loading this extension. Looks like the module '{self.module_name}' did not get loaded by Goldy Bot. 
54                    Perhaps this is a package module and you forgot to specify the module name when loading this extension.\n""")
55                    
56                    GoldyBot.Goldy().stop(f"I think you forgot to specify the module name when loading the '{self.code_name}' extension.")
57
58                GoldyBot.logging.log(f"[{self.code_name}] Loading my commands...")
59                self.loader() # Load commands.
60
61            else:
62                GoldyBot.logging.log("info", f"[{class_object.__class__.__name__}] Not loading commands as this extension is ignored.")
63
64        except TypeError as e:
65            what_is_incorrect = None
66
67            if self.ignored_extensions_list == None: what_is_incorrect = "ignored_extensions"
68
69            raise GoldyBot.errors.ConfigIsIncorrect(e, what_is_incorrect)
70
71        # Setting all variable shortcuts.
72        #-----------------------------------
73        self.client:GoldyBot.nextcord.Client = GoldyBot.cache.main_cache_dict["client"]
74        self.database:GoldyBot.database.Database = GoldyBot.cache.main_cache_dict["database"]
75
76        self.FindGuilds = GoldyBot.cache.FindGuilds()
77
78        self.msg = GoldyBot.utility.msgs

Tells Goldy Bot to Load this class as an extension.

code_name
module_name

Returns the name of the module this extension is being called from. This is much faster than grabbing the name with module().name.

def loader(self):
96    def loader(self):
97        """The extension's command loader. This is what Goldy Bot uses to load your commands in an extension."""
98        pass

The extension's command loader. This is what Goldy Bot uses to load your commands in an extension.

def get_object(self):
100    def get_object(self):
101        """Returns the actual class object of the extension."""
102        return self.class_object

Returns the actual class object of the extension.

class Goldy:
12class Goldy(object):
13    """πŸ’› Goldy herself. More precisely the main class to control the whole of the Bot."""
14    def __init__(self):
15        self.nextcord_thread:threading.Thread = None
16
17    def start(self):
18        """
19        Awakens Goldy Bot! πŸ‘€πŸ’‘β°
20        ---------------
21        ### ***``Example:``***
22
23        ```python
24        import GoldyBot
25
26        goldy = GoldyBot.Goldy()
27
28        goldy.start()
29        ```
30        """
31        GoldyBot.log("warn", f"[{MODULE_NAME}] Goldy Bot is awakening...")
32
33        file_setup() # Run file setup.
34        
35        # Fixes some weird as fu#k bug when stopping the bot on windows.
36        if GoldyBot.system.platform.system() == 'Windows':
37            GoldyBot.asyncio.set_event_loop_policy(GoldyBot.asyncio.WindowsSelectorEventLoopPolicy())
38
39        print("")
40
41        # Start goldy input console.
42        input_thread = threading.Thread(target=input_loop)
43        input_thread.setDaemon(True)
44        input_thread.start()
45
46        # Start V4
47        from . import bot
48        self.nextcord_thread = threading.Thread(target=bot.start)
49        self.nextcord_thread.setDaemon(True)
50        self.nextcord_thread.start()
51
52        # Cache goldy class.
53        GoldyBot.cache.main_cache_dict["goldy_class"] = self
54
55        try: self.nextcord_thread.join()
56        except KeyboardInterrupt: pass # Stops KeyboardInterrupt traceback.
57
58    async def setup(self, client:nextcord.Client):
59        """Notifies Goldy Bot that the client is ready and it can do it's setup."""
60
61        #  Run setup on all allowed guilds.
62        #------------------------------
63        for guild in client.guilds:
64            goldy_bot_guild = GoldyBot.utility.guilds.guild.Guild(guild)
65
66            if goldy_bot_guild.is_allowed:
67                await goldy_bot_guild.setup()
68
69        #  Check if the config files have been edited for the guilds.
70        not_edited_config_guilds = []
71        for guild_ in GoldyBot.cache.main_cache_dict["guilds"]:
72            guild:GoldyBot.utility.guilds.guild.Guild = GoldyBot.cache.main_cache_dict["guilds"][guild_]["object"]
73
74            if not guild.has_config_been_edited:
75                not_edited_config_guilds.append(guild.code_name)
76
77        if not not_edited_config_guilds == []:
78            self.stop(reason=f"Guild configs MUST be edited! These guilds have not had their config's edited: {not_edited_config_guilds}")
79
80        GoldyBot.logging.log(f"[{MODULE_NAME}] Guilds Setup Done!")
81
82    def stop(self, reason="Unknown"):
83        """Safely shutdowns Goldy Bot and stops her from performing anymore actions, incase you know, things get weird. 😳"""
84
85        GoldyBot.log("warn", f"[{MODULE_NAME}] Goldy is Shuting down...")
86        GoldyBot.log("info", f"[{MODULE_NAME}] Here's the reason why I was requested to shutdown for >>> {reason}")
87
88        GoldyBot.cache.main_cache_dict["bot_stop"] = True
89
90        sys.exit(reason)

Shortcut of object from GoldyBot.goldy

Goldy()
14    def __init__(self):
15        self.nextcord_thread:threading.Thread = None
def start(self):
17    def start(self):
18        """
19        Awakens Goldy Bot! πŸ‘€πŸ’‘β°
20        ---------------
21        ### ***``Example:``***
22
23        ```python
24        import GoldyBot
25
26        goldy = GoldyBot.Goldy()
27
28        goldy.start()
29        ```
30        """
31        GoldyBot.log("warn", f"[{MODULE_NAME}] Goldy Bot is awakening...")
32
33        file_setup() # Run file setup.
34        
35        # Fixes some weird as fu#k bug when stopping the bot on windows.
36        if GoldyBot.system.platform.system() == 'Windows':
37            GoldyBot.asyncio.set_event_loop_policy(GoldyBot.asyncio.WindowsSelectorEventLoopPolicy())
38
39        print("")
40
41        # Start goldy input console.
42        input_thread = threading.Thread(target=input_loop)
43        input_thread.setDaemon(True)
44        input_thread.start()
45
46        # Start V4
47        from . import bot
48        self.nextcord_thread = threading.Thread(target=bot.start)
49        self.nextcord_thread.setDaemon(True)
50        self.nextcord_thread.start()
51
52        # Cache goldy class.
53        GoldyBot.cache.main_cache_dict["goldy_class"] = self
54
55        try: self.nextcord_thread.join()
56        except KeyboardInterrupt: pass # Stops KeyboardInterrupt traceback.

Awakens Goldy Bot! πŸ‘€πŸ’‘β°

Example:

import GoldyBot

goldy = GoldyBot.Goldy()

goldy.start()
async def setup(self, client: nextcord.client.Client):
58    async def setup(self, client:nextcord.Client):
59        """Notifies Goldy Bot that the client is ready and it can do it's setup."""
60
61        #  Run setup on all allowed guilds.
62        #------------------------------
63        for guild in client.guilds:
64            goldy_bot_guild = GoldyBot.utility.guilds.guild.Guild(guild)
65
66            if goldy_bot_guild.is_allowed:
67                await goldy_bot_guild.setup()
68
69        #  Check if the config files have been edited for the guilds.
70        not_edited_config_guilds = []
71        for guild_ in GoldyBot.cache.main_cache_dict["guilds"]:
72            guild:GoldyBot.utility.guilds.guild.Guild = GoldyBot.cache.main_cache_dict["guilds"][guild_]["object"]
73
74            if not guild.has_config_been_edited:
75                not_edited_config_guilds.append(guild.code_name)
76
77        if not not_edited_config_guilds == []:
78            self.stop(reason=f"Guild configs MUST be edited! These guilds have not had their config's edited: {not_edited_config_guilds}")
79
80        GoldyBot.logging.log(f"[{MODULE_NAME}] Guilds Setup Done!")

Notifies Goldy Bot that the client is ready and it can do it's setup.

def stop(self, reason='Unknown'):
82    def stop(self, reason="Unknown"):
83        """Safely shutdowns Goldy Bot and stops her from performing anymore actions, incase you know, things get weird. 😳"""
84
85        GoldyBot.log("warn", f"[{MODULE_NAME}] Goldy is Shuting down...")
86        GoldyBot.log("info", f"[{MODULE_NAME}] Here's the reason why I was requested to shutdown for >>> {reason}")
87
88        GoldyBot.cache.main_cache_dict["bot_stop"] = True
89
90        sys.exit(reason)

Safely shutdowns Goldy Bot and stops her from performing anymore actions, incase you know, things get weird. 😳

class Database:
 11class Database():
 12    """Goldy Bot's class to interface with a Mongo Database."""
 13    def __init__(self, database_token_url:str):
 14        self.database_token_url = database_token_url
 15        self.loop = asyncio.get_event_loop()
 16
 17        config = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON))
 18
 19        try:
 20            if not database_token_url.lower() in ["none", "null"]: 
 21                # Initializing MongoDB database
 22                self.client:pymongo.MongoClient = motor.motor_asyncio.AsyncIOMotorClient(self.database_token_url, serverSelectionTimeoutMS=2000)
 23                self.loop.run_until_complete(self.client.server_info())
 24                self.database = self.client[config.read("database_name")]
 25
 26                # Cache database class.
 27                GoldyBot.cache.main_cache_dict["database"] = self
 28
 29                GoldyBot.logging.log("info_2", f"[{MODULE_NAME}] [CONNECTED]")
 30            
 31            else:
 32                GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] [DATABASE DISABLED]")
 33                GoldyBot.logging.log("info_3", f"[{MODULE_NAME}] Database is disabled because '{database_token_url}' was entered.")
 34
 35        except Exception:
 36            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Couldn't connect to Database! Check the database URL you entered.")
 37            GoldyBot.Goldy().stop("Couldn't connect to Database! Check the database URL you entered.")
 38
 39    async def insert(self, collection:str, data) -> bool:
 40        """Tells database to insert the data provided into a collection."""
 41        await self.database[collection].insert_one(data)
 42        GoldyBot.logging.log(f"[{MODULE_NAME}] Inserted '{data}' into '{collection}.'")
 43        return True
 44
 45    async def edit(self, collection:str, query, data:dict) -> bool:
 46        """Tells database to find and edit a document with the data provided in a collection."""
 47        await self.database[collection].update_one(query, {"$set": data})
 48        GoldyBot.logging.log(f"[{MODULE_NAME}] Edited '{query}' into '{data}.'")
 49        return True
 50
 51    async def remove(self, collection:str, data) -> bool:
 52        """Tells database to find and delete a copy of this data from the collection."""
 53        await self.database[collection].delete_one(data)
 54        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Deleted '{data}' from '{collection}.'")
 55        return True
 56
 57    async def find(self, collection:str, query, key:str, max_to_find=50) -> List[dict]:
 58        """Searches for documents with the query."""
 59        try:
 60            document_list = []
 61            cursor = self.database[collection].find(query).sort(key)
 62
 63            for document in await cursor.to_list(max_to_find):
 64                document_list.append(document)
 65
 66            return document_list
 67        except KeyError as e:
 68            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
 69            return None
 70
 71    async def find_all(self, collection:str, max_to_find=100) -> List[dict] | None:
 72        """Finds and returns all documents in a collection. This took me a day to make! 😞"""
 73        try:
 74            document_list = []
 75            cursor = self.database[collection].find().sort('_id')
 76
 77            for document in await cursor.to_list(max_to_find):
 78                document_list.append(document)
 79
 80            return document_list
 81        except KeyError as e:
 82            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
 83            return None
 84
 85    async def get_collection(self, collection):
 86        """Returns cursor of the following collection."""
 87        return self.database[collection]
 88
 89    async def list_collection_names(self) -> List[str]:
 90        """Returns list of all collection names."""
 91        return await self.database.list_collection_names()
 92
 93    async def find_one(self, collection:str, query:dict) -> (dict | None):
 94        """Tells database to search for and return specific data from a collection."""
 95        data = await self.database[collection].find_one(query)
 96
 97        if not data == None:
 98            GoldyBot.logging.log(f"[{MODULE_NAME}] Found '{query}' in '{collection}.'")
 99            return data
100        else:
101            GoldyBot.logging.log(f"[{MODULE_NAME}] '{query}' was not found in '{collection}.'")
102            return None
103        
104    async def create_collection(self, collection_name:str, data):
105        await self.database[collection_name].insert_one(data)
106        GoldyBot.logging.log(f"[{MODULE_NAME}] Database collection '{collection_name}' created.")
107
108    async def delete_collection(self, collection_name:str):
109        await self.database[collection_name].drop()
110        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Database collection '{collection_name}' dropped.")
111
112    def new_instance(self, database_name:str):
113        """Starts a new database instance the efficient way. πŸ‘"""
114        class NewDatabase(Database):
115            def __init__(self, database_self:Database):
116                self.database = database_self.client[database_name]
117
118        return NewDatabase(self)
Database(database_token_url: str)
13    def __init__(self, database_token_url:str):
14        self.database_token_url = database_token_url
15        self.loop = asyncio.get_event_loop()
16
17        config = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON))
18
19        try:
20            if not database_token_url.lower() in ["none", "null"]: 
21                # Initializing MongoDB database
22                self.client:pymongo.MongoClient = motor.motor_asyncio.AsyncIOMotorClient(self.database_token_url, serverSelectionTimeoutMS=2000)
23                self.loop.run_until_complete(self.client.server_info())
24                self.database = self.client[config.read("database_name")]
25
26                # Cache database class.
27                GoldyBot.cache.main_cache_dict["database"] = self
28
29                GoldyBot.logging.log("info_2", f"[{MODULE_NAME}] [CONNECTED]")
30            
31            else:
32                GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] [DATABASE DISABLED]")
33                GoldyBot.logging.log("info_3", f"[{MODULE_NAME}] Database is disabled because '{database_token_url}' was entered.")
34
35        except Exception:
36            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Couldn't connect to Database! Check the database URL you entered.")
37            GoldyBot.Goldy().stop("Couldn't connect to Database! Check the database URL you entered.")
async def insert(self, collection: str, data) -> bool:
39    async def insert(self, collection:str, data) -> bool:
40        """Tells database to insert the data provided into a collection."""
41        await self.database[collection].insert_one(data)
42        GoldyBot.logging.log(f"[{MODULE_NAME}] Inserted '{data}' into '{collection}.'")
43        return True

Tells database to insert the data provided into a collection.

async def edit(self, collection: str, query, data: dict) -> bool:
45    async def edit(self, collection:str, query, data:dict) -> bool:
46        """Tells database to find and edit a document with the data provided in a collection."""
47        await self.database[collection].update_one(query, {"$set": data})
48        GoldyBot.logging.log(f"[{MODULE_NAME}] Edited '{query}' into '{data}.'")
49        return True

Tells database to find and edit a document with the data provided in a collection.

async def remove(self, collection: str, data) -> bool:
51    async def remove(self, collection:str, data) -> bool:
52        """Tells database to find and delete a copy of this data from the collection."""
53        await self.database[collection].delete_one(data)
54        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Deleted '{data}' from '{collection}.'")
55        return True

Tells database to find and delete a copy of this data from the collection.

async def find(self, collection: str, query, key: str, max_to_find=50) -> List[dict]:
57    async def find(self, collection:str, query, key:str, max_to_find=50) -> List[dict]:
58        """Searches for documents with the query."""
59        try:
60            document_list = []
61            cursor = self.database[collection].find(query).sort(key)
62
63            for document in await cursor.to_list(max_to_find):
64                document_list.append(document)
65
66            return document_list
67        except KeyError as e:
68            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
69            return None

Searches for documents with the query.

async def find_all(self, collection: str, max_to_find=100) -> Optional[List[dict]]:
71    async def find_all(self, collection:str, max_to_find=100) -> List[dict] | None:
72        """Finds and returns all documents in a collection. This took me a day to make! 😞"""
73        try:
74            document_list = []
75            cursor = self.database[collection].find().sort('_id')
76
77            for document in await cursor.to_list(max_to_find):
78                document_list.append(document)
79
80            return document_list
81        except KeyError as e:
82            GoldyBot.logging.log("error", f"[{MODULE_NAME}] Could not find the collection '{collection}'!")
83            return None

Finds and returns all documents in a collection. This took me a day to make! 😞

async def get_collection(self, collection):
85    async def get_collection(self, collection):
86        """Returns cursor of the following collection."""
87        return self.database[collection]

Returns cursor of the following collection.

async def list_collection_names(self) -> List[str]:
89    async def list_collection_names(self) -> List[str]:
90        """Returns list of all collection names."""
91        return await self.database.list_collection_names()

Returns list of all collection names.

async def find_one(self, collection: str, query: dict) -> dict | None:
 93    async def find_one(self, collection:str, query:dict) -> (dict | None):
 94        """Tells database to search for and return specific data from a collection."""
 95        data = await self.database[collection].find_one(query)
 96
 97        if not data == None:
 98            GoldyBot.logging.log(f"[{MODULE_NAME}] Found '{query}' in '{collection}.'")
 99            return data
100        else:
101            GoldyBot.logging.log(f"[{MODULE_NAME}] '{query}' was not found in '{collection}.'")
102            return None

Tells database to search for and return specific data from a collection.

async def create_collection(self, collection_name: str, data):
104    async def create_collection(self, collection_name:str, data):
105        await self.database[collection_name].insert_one(data)
106        GoldyBot.logging.log(f"[{MODULE_NAME}] Database collection '{collection_name}' created.")
async def delete_collection(self, collection_name: str):
108    async def delete_collection(self, collection_name:str):
109        await self.database[collection_name].drop()
110        GoldyBot.logging.log("INFO_5", f"[{MODULE_NAME}] Database collection '{collection_name}' dropped.")
def new_instance(self, database_name: str):
112    def new_instance(self, database_name:str):
113        """Starts a new database instance the efficient way. πŸ‘"""
114        class NewDatabase(Database):
115            def __init__(self, database_self:Database):
116                self.database = database_self.client[database_name]
117
118        return NewDatabase(self)

Starts a new database instance the efficient way. πŸ‘

class Embed(nextcord.embeds.Embed):
4class Embed(nextcord.Embed):
5    """Class used to create an embed in Goldy Bot."""
6    pass

Shortcut of object from GoldyBot.utility.goldy.embed

class GuildEvent:
  9class GuildEvent():
 10    """This class allows you to control a guild event."""
 11    def __init__(self, ctx, name:str, description:str, entity_type:GoldyBot.nextcord.ScheduledEventEntityType, start_time:datetime, end_time:datetime=None, 
 12        channel:GoldyBot.Channel=None, metadata:GoldyBot.nextcord.EntityMetadata = None, image:GoldyBot.File=None, reason:str="Becauwse WatAshi said uwu and bawked, that's why i dow thiws"):
 13
 14        self.ctx = ctx
 15        self.guild:GoldyBot.utility.guilds.guild.Guild = GoldyBot.cache.FindGuilds().find_object_by_id(ctx.guild.id)
 16
 17        self._name = name
 18        self._description = description
 19        self._entity_type = entity_type
 20        self._start_time = start_time
 21        self._end_time = end_time
 22        self._channel = channel
 23        self._metadata = metadata
 24        self._image = image
 25        self._reason = reason
 26
 27        self.scheduled_event:GoldyBot.nextcord.ScheduledEvent = None
 28
 29        if self.guild == None:
 30            raise GoldyBot.errors.GoldyBotError("Guild is none. Guild does not exist in cache for some reason uwu.")
 31
 32    #TODO: Added more methods like e.g delete() and edit() method.
 33
 34    @property
 35    def name(self) -> str:
 36        """The name of the guild event."""
 37        return self._name
 38
 39    @property
 40    def description(self) -> str:
 41        """The description of the guild event."""
 42        return self._description
 43
 44    @property
 45    def entity_type(self) -> GoldyBot.nextcord.ScheduledEventEntityType:
 46        """The entity type of the guild."""
 47        return self._entity_type
 48
 49    @property
 50    def start_time(self) -> datetime:
 51        """Returns the start time and date of the event in datetime object."""
 52        return self._start_time
 53
 54    @property
 55    def end_time(self) -> datetime|None:
 56        """Returns the end time and date of the event in datetime object."""
 57        return self._end_time
 58
 59    @property
 60    def channel(self) -> GoldyBot.channel.Channel:
 61        """Returns the channel of this event."""
 62        return self._channel
 63
 64    @property
 65    def metadata(self) -> GoldyBot.nextcord.EntityMetadata:
 66        return self._metadata
 67
 68    @property
 69    def image(self) -> GoldyBot.File:
 70        return self._image
 71
 72    @property
 73    def reason(self) -> str:
 74        """Returns the set reasoning of this event, if none a sussy default message is returned instead."""
 75        return self._reason
 76
 77
 78    async def create(self) -> GoldyBot.nextcord.ScheduledEvent|None:
 79        """Creates the ⭐ fancy guild event."""
 80
 81        if self.entity_type == GoldyBot.nextcord.ScheduledEventEntityType.external:
 82            if self.end_time is None:
 83                GoldyBot.log("error", f"[{MODULE_NAME}] End time is required for external events. end_time was None.")
 84                return None
 85            
 86            if self.metadata is None:
 87                GoldyBot.log("error", f"[{MODULE_NAME}] Location is required on metadata for external events.")
 88                return None
 89
 90
 91        self.scheduled_event = await self.guild.nextcord_guild_object.create_scheduled_event(
 92            name=self.name, description=self.name, entity_type=self.entity_type, start_time=self.start_time, 
 93            end_time=(lambda end_time: GoldyBot.nextcord.utils.MISSING if end_time is None else end_time)(self.end_time), 
 94            channel=(lambda channel: GoldyBot.nextcord.utils.MISSING if channel is None else channel.channel)(self.channel),
 95            metadata=(lambda metadata: GoldyBot.nextcord.utils.MISSING if metadata is None else metadata)(self.metadata), 
 96            image=GoldyBot.nextcord.File(self.image.get_file()), reason=self.reason # I think this was not working...
 97        )
 98
 99        GoldyBot.logging.log("info_2", f"[{MODULE_NAME}] Created guild event in '{self.channel.display_name}'.")
100
101        return self.scheduled_event

Shortcut of object from GoldyBot.utility.guild_events.GuildEvent

GuildEvent( ctx, name: str, description: str, entity_type: nextcord.enums.ScheduledEventEntityType, start_time: datetime.datetime, end_time: datetime.datetime = None, channel: GoldyBot.objects.channel.Channel = None, metadata: nextcord.scheduled_events.EntityMetadata = None, image: GoldyBot.File = None, reason: str = "Becauwse WatAshi said uwu and bawked, that's why i dow thiws")
11    def __init__(self, ctx, name:str, description:str, entity_type:GoldyBot.nextcord.ScheduledEventEntityType, start_time:datetime, end_time:datetime=None, 
12        channel:GoldyBot.Channel=None, metadata:GoldyBot.nextcord.EntityMetadata = None, image:GoldyBot.File=None, reason:str="Becauwse WatAshi said uwu and bawked, that's why i dow thiws"):
13
14        self.ctx = ctx
15        self.guild:GoldyBot.utility.guilds.guild.Guild = GoldyBot.cache.FindGuilds().find_object_by_id(ctx.guild.id)
16
17        self._name = name
18        self._description = description
19        self._entity_type = entity_type
20        self._start_time = start_time
21        self._end_time = end_time
22        self._channel = channel
23        self._metadata = metadata
24        self._image = image
25        self._reason = reason
26
27        self.scheduled_event:GoldyBot.nextcord.ScheduledEvent = None
28
29        if self.guild == None:
30            raise GoldyBot.errors.GoldyBotError("Guild is none. Guild does not exist in cache for some reason uwu.")
name: str

The name of the guild event.

description: str

The description of the guild event.

entity_type: nextcord.enums.ScheduledEventEntityType

The entity type of the guild.

start_time: datetime.datetime

Returns the start time and date of the event in datetime object.

end_time: datetime.datetime | None

Returns the end time and date of the event in datetime object.

Returns the channel of this event.

metadata: nextcord.scheduled_events.EntityMetadata
image: GoldyBot.File
reason: str

Returns the set reasoning of this event, if none a sussy default message is returned instead.

async def create(self) -> nextcord.scheduled_events.ScheduledEvent | None:
 78    async def create(self) -> GoldyBot.nextcord.ScheduledEvent|None:
 79        """Creates the ⭐ fancy guild event."""
 80
 81        if self.entity_type == GoldyBot.nextcord.ScheduledEventEntityType.external:
 82            if self.end_time is None:
 83                GoldyBot.log("error", f"[{MODULE_NAME}] End time is required for external events. end_time was None.")
 84                return None
 85            
 86            if self.metadata is None:
 87                GoldyBot.log("error", f"[{MODULE_NAME}] Location is required on metadata for external events.")
 88                return None
 89
 90
 91        self.scheduled_event = await self.guild.nextcord_guild_object.create_scheduled_event(
 92            name=self.name, description=self.name, entity_type=self.entity_type, start_time=self.start_time, 
 93            end_time=(lambda end_time: GoldyBot.nextcord.utils.MISSING if end_time is None else end_time)(self.end_time), 
 94            channel=(lambda channel: GoldyBot.nextcord.utils.MISSING if channel is None else channel.channel)(self.channel),
 95            metadata=(lambda metadata: GoldyBot.nextcord.utils.MISSING if metadata is None else metadata)(self.metadata), 
 96            image=GoldyBot.nextcord.File(self.image.get_file()), reason=self.reason # I think this was not working...
 97        )
 98
 99        GoldyBot.logging.log("info_2", f"[{MODULE_NAME}] Created guild event in '{self.channel.display_name}'.")
100
101        return self.scheduled_event

Creates the ⭐ fancy guild event.

class File:
15class File(object):
16    """Goldy Bot's File Handler."""
17    def __init__(self, path):
18        self.file_path = path
19
20        if self.exists() == False:
21            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] Umm, that file doesn't exist, so I'm going to create it myself.")
22            self.create()
23
24    def read(self) -> Any|None:
25        """Commands Goldy to return the value of a file."""
26        try:
27            with self.get_file() as file:
28                file_context = file.read()
29                GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've read the file '{self.file_path}'.")
30                return file_context
31
32        except Exception as e:
33            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] Oops, I Couldn't read the file '{self.file_path}', so I'm returning 'None'. \nError --> {e}")
34            return None
35
36    def write(self, value) -> None:
37        """Commands Goldy to write to the file with the following value."""
38        try:
39            # Try to edit value of file.
40            with self.get_file() as file:
41                file.seek(0)
42                file.write(str(value))
43                file.truncate()
44
45            GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've written to '{self.file_path}'.")
46        
47        except Exception:
48            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] I Couldn't edit '{self.file_path}' with the value '{value}'!")
49
50    def create(self) -> None:
51        """Commands Goldy to create a file or directory."""
52        if self.file_path[-1] == "/": # Create directory.
53            os.mkdir(self.file_path)
54            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a directory at '{self.file_path}'.")
55        else: # Create file.
56            open(self.file_path, "a+")
57            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a file at '{self.file_path}'.")
58
59    def delete(self) -> None:
60        """Commands Goldy to delete this file."""
61        if self.file_path[-1] == "/": # Delete as directly.
62            os.rmdir(self.file_path)
63            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the directory at '{self.file_path}'.")
64        else: # Delete as file.
65            os.remove(self.file_path)
66            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the file at '{self.file_path}'.")
67        
68
69    def exists(self) -> bool:
70        """Checks if the file exists."""
71        if os.path.exists(self.file_path):
72            return True
73        else:
74            return False
75
76    def get_file(self, mode="r+") -> IO:
77        """Commands Goldy to open the file."""
78        if mode == "wb": return open(self.file_path, mode) # For writing binary.
79
80        return open(self.file_path, mode, encoding='utf-8')

Shortcut of object from GoldyBot.File

File(path)
17    def __init__(self, path):
18        self.file_path = path
19
20        if self.exists() == False:
21            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] Umm, that file doesn't exist, so I'm going to create it myself.")
22            self.create()
def read(self) -> Optional[Any]:
24    def read(self) -> Any|None:
25        """Commands Goldy to return the value of a file."""
26        try:
27            with self.get_file() as file:
28                file_context = file.read()
29                GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've read the file '{self.file_path}'.")
30                return file_context
31
32        except Exception as e:
33            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] Oops, I Couldn't read the file '{self.file_path}', so I'm returning 'None'. \nError --> {e}")
34            return None

Commands Goldy to return the value of a file.

def write(self, value) -> None:
36    def write(self, value) -> None:
37        """Commands Goldy to write to the file with the following value."""
38        try:
39            # Try to edit value of file.
40            with self.get_file() as file:
41                file.seek(0)
42                file.write(str(value))
43                file.truncate()
44
45            GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've written to '{self.file_path}'.")
46        
47        except Exception:
48            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] I Couldn't edit '{self.file_path}' with the value '{value}'!")

Commands Goldy to write to the file with the following value.

def create(self) -> None:
50    def create(self) -> None:
51        """Commands Goldy to create a file or directory."""
52        if self.file_path[-1] == "/": # Create directory.
53            os.mkdir(self.file_path)
54            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a directory at '{self.file_path}'.")
55        else: # Create file.
56            open(self.file_path, "a+")
57            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a file at '{self.file_path}'.")

Commands Goldy to create a file or directory.

def delete(self) -> None:
59    def delete(self) -> None:
60        """Commands Goldy to delete this file."""
61        if self.file_path[-1] == "/": # Delete as directly.
62            os.rmdir(self.file_path)
63            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the directory at '{self.file_path}'.")
64        else: # Delete as file.
65            os.remove(self.file_path)
66            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the file at '{self.file_path}'.")

Commands Goldy to delete this file.

def exists(self) -> bool:
69    def exists(self) -> bool:
70        """Checks if the file exists."""
71        if os.path.exists(self.file_path):
72            return True
73        else:
74            return False

Checks if the file exists.

def get_file(self, mode='r+') -> <class 'IO'>:
76    def get_file(self, mode="r+") -> IO:
77        """Commands Goldy to open the file."""
78        if mode == "wb": return open(self.file_path, mode) # For writing binary.
79
80        return open(self.file_path, mode, encoding='utf-8')

Commands Goldy to open the file.

class WebFile:
 82class WebFile():
 83    """A web file is a class that partially inherits the GoldyBot.File() class but instead of taking in file path it takes in a URL of a file on the web."""
 84    def __init__(self, url:str, download_to_disk:bool=False, time_until_deletion:int|float=10):
 85        self._url = url
 86        self._download_to_disk = download_to_disk
 87        self._time_until_deletion = time_until_deletion
 88        self._request = requests.get(self._url, stream=True)
 89        self._request.raw.decode_content = True # Content-Encoding
 90
 91        self.file_path = self._url
 92
 93        self._file_object = io.BytesIO(self._request.content)
 94
 95        # Getting file name.
 96        try:
 97            self._file_object.name = re.findall("filename=(.+)", self._request.headers['Content-Disposition'])[0]
 98
 99        except KeyError: # If fail to get file name then fallback to default.
100            GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Failed to find the web file's file name so I'm giving it a default name.")
101
102            content_type = self._request.headers['Content-Type']
103            self._file_object.name = f"uwu_file.{content_type[content_type.index('/')+1:]}"
104
105        # Download to disk temporary if 'download_to_disk' is True.
106        if download_to_disk:
107            self.download_to_disk(self._time_until_deletion)
108
109    @property
110    def url(self) -> str:
111        """Returns url of file."""
112        return self._url
113
114    @property
115    def downloaded_to_disk(self) -> bool:
116        """Has this file been downloaded to disk."""
117        return self._download_to_disk
118
119    @property
120    def file_name(self) -> str:
121        """Returns name of file."""
122        return self._file_object.name
123
124    @property
125    def raw_bytes(self) -> bytes:
126        """Returns πŸ₯©raw bytes of file. Sometimes this is more preferred by other libraries."""
127        return self._request.content
128
129    def download_to_disk(self, time_until_deletion:int|float=10) -> None:
130        """Downloads file to disk temporary. The file deletes itself by default in 5 seconds."""
131        File("./temp/") # Create temp folder.
132        
133        self.temp_file = File(f"./temp/{self._file_object.name}")
134
135        with self.temp_file.get_file(mode="wb") as file:
136            file.seek(0)
137            file.write(self._file_object.getvalue())
138            file.truncate()
139            file.close()
140
141        def delete_file_later(): time.sleep(time_until_deletion); self.temp_file.delete()
142
143        threading.Thread(target=delete_file_later).start()
144
145    def get_file(self) -> io.BytesIO|str:
146        """Returns file IO object but if 'download_to_disk' is True this will return the temporary path to the file."""
147        if self.downloaded_to_disk:
148            return f"./temp/{self._file_object.name}"
149        else:
150            return self._file_object
151    
152    # Inheriting read method from GoldyBot.File class.
153    read:Callable[[], Any|None] = File.__dict__["read"]
154    """Commands Goldy to return the value of a file."""

Shortcut of object from GoldyBot.WebFile

WebFile( url: str, download_to_disk: bool = False, time_until_deletion: int | float = 10)
 84    def __init__(self, url:str, download_to_disk:bool=False, time_until_deletion:int|float=10):
 85        self._url = url
 86        self._download_to_disk = download_to_disk
 87        self._time_until_deletion = time_until_deletion
 88        self._request = requests.get(self._url, stream=True)
 89        self._request.raw.decode_content = True # Content-Encoding
 90
 91        self.file_path = self._url
 92
 93        self._file_object = io.BytesIO(self._request.content)
 94
 95        # Getting file name.
 96        try:
 97            self._file_object.name = re.findall("filename=(.+)", self._request.headers['Content-Disposition'])[0]
 98
 99        except KeyError: # If fail to get file name then fallback to default.
100            GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Failed to find the web file's file name so I'm giving it a default name.")
101
102            content_type = self._request.headers['Content-Type']
103            self._file_object.name = f"uwu_file.{content_type[content_type.index('/')+1:]}"
104
105        # Download to disk temporary if 'download_to_disk' is True.
106        if download_to_disk:
107            self.download_to_disk(self._time_until_deletion)
url: str

Returns url of file.

downloaded_to_disk: bool

Has this file been downloaded to disk.

file_name: str

Returns name of file.

raw_bytes: bytes

Returns πŸ₯©raw bytes of file. Sometimes this is more preferred by other libraries.

def download_to_disk(self, time_until_deletion: int | float = 10) -> None:
129    def download_to_disk(self, time_until_deletion:int|float=10) -> None:
130        """Downloads file to disk temporary. The file deletes itself by default in 5 seconds."""
131        File("./temp/") # Create temp folder.
132        
133        self.temp_file = File(f"./temp/{self._file_object.name}")
134
135        with self.temp_file.get_file(mode="wb") as file:
136            file.seek(0)
137            file.write(self._file_object.getvalue())
138            file.truncate()
139            file.close()
140
141        def delete_file_later(): time.sleep(time_until_deletion); self.temp_file.delete()
142
143        threading.Thread(target=delete_file_later).start()

Downloads file to disk temporary. The file deletes itself by default in 5 seconds.

def get_file(self) -> _io.BytesIO | str:
145    def get_file(self) -> io.BytesIO|str:
146        """Returns file IO object but if 'download_to_disk' is True this will return the temporary path to the file."""
147        if self.downloaded_to_disk:
148            return f"./temp/{self._file_object.name}"
149        else:
150            return self._file_object

Returns file IO object but if 'download_to_disk' is True this will return the temporary path to the file.

def read(self) -> Optional[Any]:
24    def read(self) -> Any|None:
25        """Commands Goldy to return the value of a file."""
26        try:
27            with self.get_file() as file:
28                file_context = file.read()
29                GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've read the file '{self.file_path}'.")
30                return file_context
31
32        except Exception as e:
33            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] Oops, I Couldn't read the file '{self.file_path}', so I'm returning 'None'. \nError --> {e}")
34            return None

Commands Goldy to return the value of a file.

async_loop = <ProactorEventLoop running=False closed=False debug=False>

Goldy Bot's async loop. You can use this to run async methods in non async functions. Like this async_loop.run_until_complete(async_function())

class Colours:
 8class Colours:
 9    """Hardcoded GoldyBot colour codes. These can be used in Embeds and stuff."""
10    AKI_PINK = 0xFF1493
11    AKI_ORANGE = 0xF4900C
12    AKI_RED = 0xff0051
13    AKI_BLUE = 0X75E6DA
14    BLUE = 0x3061f2
15    GREEN = 0x00FF00
16    LIME_GREEN = 0x8AFF65
17    YELLOW = 0xffff4d
18    PURPLE = 0xFF00FF
19    RED = 0xFF0000
20    GREY = 0x3B3B3B
21    WHITE = 0xFFFFFF
22
23    DISCORD_EMBED_INVISIBLE = 0x2F3136
24    """Makes the embed colour the same as the background essentially giving the embed a transparent colour."""
25    
26    def custom_colour(self, rgb:tuple=None, hex:int|str=None) -> Literal|int:
27        """
28        Method to create custom colour with rgb or hex values.
29        (WARNING: Hex is currently not supported, if hex is entered value of ``WHITE`` will be returned.)
30        """
31        if not rgb == None:
32            if isinstance(rgb, tuple):
33                return nextcord.Colour.from_rgb(rgb[0], rgb[1], rgb[2]).value
34
35        return self.WHITE
36    
37    def get_colour_from_image(self, image_file:GoldyBot.files.File, quality:int=5) -> Literal|int:
38        """Returns most common colour from any image."""
39
40        if isinstance(image_file, GoldyBot.WebFile): # It's a web file.
41            image_file:GoldyBot.WebFile
42            return self.custom_colour(
43                rgb=ColorThief(image_file.get_file()).get_color(quality)
44            )
45
46        else: # It's a normal file.
47            return self.custom_colour(
48                rgb=ColorThief(image_file.file_path).get_color(quality)
49            )

Shortcut of object from GoldyBot.utility.goldy.colours

Colours()
AKI_PINK = 16716947
AKI_ORANGE = 16027660
AKI_RED = 16711761
AKI_BLUE = 7726810
BLUE = 3170802
GREEN = 65280
LIME_GREEN = 9109349
YELLOW = 16777037
PURPLE = 16711935
RED = 16711680
GREY = 3881787
WHITE = 16777215
DISCORD_EMBED_INVISIBLE = 3092790

Makes the embed colour the same as the background essentially giving the embed a transparent colour.

def custom_colour(self, rgb: tuple = None, hex: int | str = None) -> 'Literal | int':
26    def custom_colour(self, rgb:tuple=None, hex:int|str=None) -> Literal|int:
27        """
28        Method to create custom colour with rgb or hex values.
29        (WARNING: Hex is currently not supported, if hex is entered value of ``WHITE`` will be returned.)
30        """
31        if not rgb == None:
32            if isinstance(rgb, tuple):
33                return nextcord.Colour.from_rgb(rgb[0], rgb[1], rgb[2]).value
34
35        return self.WHITE

Method to create custom colour with rgb or hex values. (WARNING: Hex is currently not supported, if hex is entered value of WHITE will be returned.)

def get_colour_from_image( self, image_file: GoldyBot.File, quality: int = 5) -> 'Literal | int':
37    def get_colour_from_image(self, image_file:GoldyBot.files.File, quality:int=5) -> Literal|int:
38        """Returns most common colour from any image."""
39
40        if isinstance(image_file, GoldyBot.WebFile): # It's a web file.
41            image_file:GoldyBot.WebFile
42            return self.custom_colour(
43                rgb=ColorThief(image_file.get_file()).get_color(quality)
44            )
45
46        else: # It's a normal file.
47            return self.custom_colour(
48                rgb=ColorThief(image_file.file_path).get_color(quality)
49            )

Returns most common colour from any image.

class Colors(GoldyBot.Colours):
51class Colors(Colours):
52    pass
Colors()
class Hearts:
 6class Hearts:
 7    """πŸ–€ A class of Goldy Bot's lovely hearts. 🀍"""
 8    BLACK = HEARTS[0]
 9    WHITE = HEARTS[1]
10    BLUE = HEARTS[2]
11    GREEN = HEARTS[3]
12    PURPLE = HEARTS[4]
13    BROWN = HEARTS[5]
14    ORANGE = HEARTS[6]
15    RED = HEARTS[7]
16    YELLOW = HEARTS[8]
17
18    def random() -> str:
19        """Returns a random coloured heart. πŸ’›πŸ’œπŸ’™"""
20        return random.choice(HEARTS)

Shortcut of object from GoldyBot.utility.goldy.hearts

Hearts()
BLACK = 'πŸ–€'
WHITE = '🀍'
BLUE = 'πŸ’™'
GREEN = 'πŸ’š'
PURPLE = 'πŸ’œ'
BROWN = '🀎'
ORANGE = '🧑'
RED = '❀️'
YELLOW = 'πŸ’›'
def random() -> str:
18    def random() -> str:
19        """Returns a random coloured heart. πŸ’›πŸ’œπŸ’™"""
20        return random.choice(HEARTS)

Returns a random coloured heart. πŸ’›πŸ’œπŸ’™

class Currencies:
4class Currencies:
5    """All the main Goldy Bot Currencies classes."""
6
7    GoldyCredits = currency.GoldyCredits

Shortcut of object from GoldyBot.utility.goldy.currencies

Currencies()
class Currencies.GoldyCredits(GoldyBot.objects.currency.Currency):
53class GoldyCredits(Currency):
54    """The main Goldy Bot currency."""
55    def __init__(self):
56        super().__init__("goldCoins", "Goldy Credits")

The main Goldy Bot currency.