GoldyBot
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``"""
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
Shortcut of GoldyBot.logging.log
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
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
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
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.
Returns the name of the module this extension is being called from. This is much faster than grabbing the name with module().name
.
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
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.
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.
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. π³
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)
Shortcut of GoldyBot.database.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.")
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.
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.
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.
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.
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! π
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.
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.
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.
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. π
Shortcut of object from GoldyBot.utility.goldy.embed
Inherited Members
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
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.")
Returns the set reasoning of this event, if none a sussy default message is returned instead.
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.
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
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.
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.
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.
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.
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
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)
Returns π₯©raw bytes of file. Sometimes this is more preferred by other libraries.
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.
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.
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.
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())
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
Makes the embed colour the same as the background essentially giving the embed a transparent colour.
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.)
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.
Alias of GoldyBot.Colours
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
4class Currencies: 5 """All the main Goldy Bot Currencies classes.""" 6 7 GoldyCredits = currency.GoldyCredits
Shortcut of object from GoldyBot.utility.goldy.currencies
53class GoldyCredits(Currency): 54 """The main Goldy Bot currency.""" 55 def __init__(self): 56 super().__init__("goldCoins", "Goldy Credits")
The main Goldy Bot currency.