GoldyBot.objects
1from . import command, member, role, slash, channel, currency 2 3Command = command.Command 4"""""" 5Member = member.Member 6"""""" 7Role = role.Role 8"""""" 9InteractionToCtx = slash.InteractionToCtx 10"""""" 11Channel = channel.Channel 12"""""" 13Currency = currency.Currency 14"""""" 15 16""" 17class GoldyBotObjectInterfaceBaseClass(): 18 '''Most GoldyBot objects inherent from this class to have similar programming interface. Don't worry about this class. 19"""
30class Command(Embeds): 31 def __init__(self, func, command_object:nextcord.BaseApplicationCommand | commands.Command=None, command_name=None, 32 required_roles:list=[], slash_options:dict={}, help_des:str=None, hidden:bool=False, 33 parent_cmd:Command=None 34 ): 35 """Generates goldy bot command object with command function object.""" 36 self.func:function = func 37 self.command = command_object 38 """Nextcord command object.""" 39 40 if command_name == None: 41 self.command_name = self.func.__name__ 42 else: 43 self.command_name = command_name 44 self.required_roles_ = required_roles 45 self.slash_options_ = slash_options 46 self.params_ = list(self.func.__code__.co_varnames) 47 self.params_amount_ = self.func.__code__.co_argcount 48 self.help_des_ = help_des 49 self.is_hidden_ = hidden 50 51 self.parent_cmd_ = parent_cmd 52 53 self.in_extension_ = False 54 55 if self.params[0] == "self": 56 self.in_extension_ = True 57 self.params_.pop(0) 58 59 # Add command to extension in cache. 60 if self.in_extension: 61 if self.module.is_internal_module: 62 GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].append(self) 63 else: 64 GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].append(self) 65 else: 66 GoldyBot.cache.main_cache_dict["internal_modules"]["goldy"]["extensions"]["core"]["commands"].append(self) 67 68 super().__init__() 69 70 @property 71 def code_name(self) -> str: 72 """Returns code name of command.""" 73 return self.command_name 74 75 @property 76 def params(self) -> list: 77 """Returns list of function parameters.""" 78 if self.in_extension: 79 return self.params_[0:self.params_amount_ - 1] 80 else: 81 return self.params_[0:self.params_amount_] 82 83 @property 84 def extension_name(self) -> str | None: 85 """Returns extension's code name.""" 86 if self.in_extension: 87 # Command is in extension. 88 return str(self.func).split(" ")[1].split(".")[0] 89 else: 90 # Command is not in any extension. 91 return None 92 93 @property 94 def extension(self) -> GoldyBot.ext.extensions.Extension | None: 95 """Finds and returns the object of the command's extension.""" 96 if self.in_extension: 97 return GoldyBot.cache.FindExtensions().find_object_by_extension_name(extension_name=self.extension_name) 98 else: 99 None 100 101 @property 102 def in_extension(self) -> bool: 103 """Returns true/false if the command is in a extension.""" 104 if self.in_extension_: 105 return True 106 else: 107 return False 108 109 @property 110 def module_name(self) -> str: 111 """Returns name of module the command is located in.""" 112 return self.extension.module_name 113 114 @property 115 def module(self) -> GoldyBot.modules.Module: 116 return GoldyBot.cache.FindModules().find_object_by_module_name(module_name=self.module_name) 117 118 @property 119 def is_hidden(self): 120 """Is the command hidden.""" 121 return self.is_hidden_ 122 123 @property 124 def parent_cmd(self) -> Command|None: 125 """Returns the command object of the parent command if command has parent.""" 126 return self.parent_cmd_ 127 128 @property 129 def is_child(self): 130 """Returns if command is child or not.""" 131 if self.parent_cmd == None: 132 return False 133 else: 134 return True 135 136 def mention(self) -> str: 137 """Returns mention of slash command, if registered as a slash command.""" 138 #TODO: Perhaps have this return codeblock if this command is not a slash command. 139 try: 140 if self.is_child == False: 141 return f"</{self.code_name}:{self.command.command_ids[0]}>" 142 else: 143 return f"</{self.parent_cmd.code_name} {self.code_name}:{self.command.command_ids[0]}>" 144 except (TypeError, AttributeError): 145 GoldyBot.log("warn", f"[{MODULE_NAME}] Tried to mention slash command '{self.code_name}' but could not find it's command id so I'm returning the mention without it.") 146 147 if self.is_child == False: return f"</{self.code_name}:0>" 148 else: return f"</{self.parent_cmd.code_name} {self.code_name}:0>" 149 150 def create_slash(self) -> nextcord.BaseApplicationCommand: 151 """Creates slash command.""" 152 153 GoldyBot.logging.log(f"[{MODULE_NAME}] [{self.command_name.upper()}] Creating slash command...") 154 slash_command_params = self.slash_commands_params_generator() 155 156 return_data = {} 157 158 # Make slash command only visible to admins if it is hidden. 159 default_member_permissions = None 160 if self.is_hidden: default_member_permissions = nextcord.Permissions(permissions=8) 161 162 163 if self.in_extension == True: # Run in EXTENSION! 164 exec(f""" 165@client.slash_command(name=command_name, description=help_des, guild_ids=guilds_allowed_in, default_member_permissions=default_member_permissions) 166async def slash_command_(interaction: Interaction{slash_command_params[0]}): 167 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 168 try: 169 if self.allowed_to_run(ctx): 170 await func(class_, ctx{slash_command_params[1]}) 171 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash command '{self.code_name}' was executed.") 172 173 except GoldyBot.errors.MemberHasNoPermsForCommand: 174 if hidden == False: 175 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 176 message = await ctx.send(embed=no_perms_embed) 177 await asyncio.sleep(6) 178 await message.delete() 179 180 except GoldyBot.errors.GuildNotRegistered: 181 if hidden == False: 182 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 183 message = await ctx.send(embed=guild_not_registered_embed) 184 await asyncio.sleep(15) 185 message.delete() 186 187 except Exception as e: 188 GoldyBot.logging.log("error", e) 189 """, 190 191 {"func":self.func, "client":GoldyBot.cache.main_cache_dict["client"], "command_name":self.command_name, "help_des":self.get_help_des(), "self":self, 192 "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, "class_":self.extension, "no_perms_embed":self.no_perms_embed, 193 "guild_not_registered_embed":self.guild_not_registered_embed, "hidden":self.is_hidden, "guilds_allowed_in":self.guilds_allowed_in, 194 "default_member_permissions":default_member_permissions}, return_data) 195 196 else: # Run as NORMAL command! 197 exec(f""" 198@client.slash_command(name=command_name, description=help_des, guild_ids=guilds_allowed_in, default_member_permissions=default_member_permissions) 199async def slash_command_(interaction: Interaction{slash_command_params[0]}): 200 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 201 try: 202 if self.allowed_to_run(ctx): 203 await func(ctx{slash_command_params[1]}) 204 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash command '{self.code_name}' was executed.") 205 206 except GoldyBot.errors.MemberHasNoPermsForCommand: 207 if hidden == False: 208 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 209 message = await ctx.send(embed=no_perms_embed) 210 await asyncio.sleep(15) 211 await message.delete() 212 213 except GoldyBot.errors.GuildNotRegistered: 214 if hidden == False: 215 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 216 message = await ctx.send(embed=guild_not_registered_embed) 217 await asyncio.sleep(15) 218 await message.delete() 219 220 except Exception as e: 221 GoldyBot.logging.log("error", e) 222 """, 223 224 {"func":self.func, "client":GoldyBot.cache.main_cache_dict["client"], "command_name":self.command_name, "help_des":self.get_help_des(), "self":self, 225 "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, "no_perms_embed":self.no_perms_embed, 226 "guild_not_registered_embed":self.guild_not_registered_embed, "hidden":self.is_hidden, "guilds_allowed_in":self.guilds_allowed_in, 227 "default_member_permissions":default_member_permissions}, return_data) 228 229 GoldyBot.logging.log(f"[{MODULE_NAME}] [{self.command_name.upper()}] Slash command created!") 230 231 self.command = return_data["slash_command_"] 232 return return_data["slash_command_"] 233 234 def remove(self): 235 """Removes command from nextcord.""" 236 command_application_object = self.command 237 238 # Remove command from extension in cache. 239 if self.in_extension: 240 if self.module.is_internal_module: 241 GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].remove(self) 242 else: 243 GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].remove(self) 244 else: 245 GoldyBot.cache.main_cache_dict["internal_modules"]["goldy"]["extensions"]["core"]["commands"].remove(self) 246 247 # Remove from nextcord. 248 client = GoldyBot.cache.client() 249 client.remove_command(name=self.code_name) 250 251 for guild_id in self.guilds_allowed_in: 252 print(command_application_object.command_ids) #TODO: Problem here! 253 GoldyBot.async_loop.run_until_complete(client.delete_application_commands(command_application_object, guild_id=guild_id)) 254 255 GoldyBot.cache.main_cache_dict["client"] = client 256 257 GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Removed the command '{self.code_name}'!") 258 return True 259 260 def any_args_missing(self, command_executers_args:tuple) -> bool: 261 """Checks if the args given by the command executer matches what parameters the command needs.""" 262 if len(command_executers_args) == len(self.params[1:]): 263 return True 264 else: 265 return False 266 267 def slash_commands_params_generator(self): 268 """Generates a string of params for slash commands. This is more of an in-house thing.""" 269 params_amount = len(self.params[1:]) 270 slash_command_params = "" 271 slash_command_args = "" 272 273 if params_amount >= 1: 274 slash_command_params = ", " 275 slash_command_args = ", " 276 count = 0 277 for param in self.params[1:]: 278 count += 1 279 280 try: 281 # String 282 if isinstance(self.slash_options_[param.lower()], str): 283 default_value = f"='{self.slash_options_[param.lower()]}'" 284 285 # Slash Option 286 if isinstance(self.slash_options_[param.lower()], nextcord.SlashOption): 287 slash_option:nextcord.SlashOption = self.slash_options_[param.lower()] 288 289 if isinstance(slash_option.name, str): 290 name = f"'{slash_option.name}'" 291 else: 292 name = None 293 294 if isinstance(slash_option.description, str): 295 description = f"'{slash_option.description}'" 296 else: 297 description = None 298 299 if isinstance(slash_option.required, nextcord.utils._MissingSentinel): 300 required = None 301 else: 302 required = slash_option.required 303 304 if isinstance(slash_option.choices, nextcord.utils._MissingSentinel): 305 choices = None 306 else: 307 choices = slash_option.choices 308 309 """ 310 if isinstance(slash_option.min_value, nextcord.utils._MissingSentinel): 311 min_value = None 312 else: 313 min_value = slash_option.min_value 314 315 if isinstance(slash_option.max_value, nextcord.utils._MissingSentinel): 316 max_value = None 317 else: 318 max_value = slash_option.max_value 319 """ 320 321 if isinstance(slash_option.autocomplete, nextcord.utils._MissingSentinel): 322 autocomplete = None 323 else: 324 autocomplete = slash_option.autocomplete 325 326 if isinstance(slash_option.default, str): 327 default = f"'{slash_option.default}'" 328 else: 329 default = None 330 331 default_value = f"""=nextcord.SlashOption(name={name}, description={description}, required={required}, 332 choices={choices}, autocomplete={autocomplete}, default={default}, verify={slash_option._verify})""" 333 334 else: 335 default_value = f"={self.slash_options_[param.lower()]}" 336 337 except KeyError: 338 default_value = "" 339 340 if count >= params_amount: 341 slash_command_params += f"{param}{default_value}" 342 slash_command_args += f"{param}" 343 else: 344 slash_command_params += f"{param}{default_value}, " 345 slash_command_args += f"{param}, " 346 347 return (slash_command_params, slash_command_args) 348 349 def update_command_object(self, command_object:commands.Command): 350 """Adds/updates this command object to the class.""" 351 self.command = command_object 352 353 def sub_command(self, command_name:str=None, required_roles:list=[], help_des:str=None, slash_options:Dict[str, nextcord.SlashOption]={}, also_run_parent_CMD:bool=True): 354 """Create a lovely sub command from this slash command. 😀 (Only works with slash commands.)""" 355 356 def decorate(func): 357 def inner(func, command_name, required_roles, help_des, slash_options): 358 parent_command = self.command 359 360 return_data = {} 361 362 goldy_sub_command = Command(func, command_name=command_name, required_roles=required_roles, slash_options=slash_options, help_des=help_des, parent_cmd=self) 363 slash_command_params = goldy_sub_command.slash_commands_params_generator() 364 parent_slash_command_params = self.slash_commands_params_generator() 365 366 if self.in_extension == True: # Run in EXTENSION! 367 exec(f""" 368@parent_command.subcommand(name=command_name, description=help_des) 369async def slash_command_(interaction: Interaction{slash_command_params[0]}): 370 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 371 try: 372 if self.allowed_to_run(ctx): 373 continue_onto_subcommand = None 374 if also_run_parent_CMD == True: continue_onto_subcommand = await goldy_parent_command.func(class_, ctx{parent_slash_command_params[1]}) 375 if not continue_onto_subcommand == False: 376 await func(class_, ctx{slash_command_params[1]}) 377 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash subcommand '{goldy_sub_command.code_name}' was executed.") 378 else: 379 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash subcommand '{goldy_sub_command.code_name}' never executed because parent command returned 'False'.") 380 381 except GoldyBot.errors.MemberHasNoPermsForCommand: 382 if hidden == False: 383 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 384 message = await ctx.send(embed=no_perms_embed) 385 await asyncio.sleep(6) 386 await message.delete() 387 388 except GoldyBot.errors.GuildNotRegistered: 389 if hidden == False: 390 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 391 message = await ctx.send(embed=guild_not_registered_embed) 392 await asyncio.sleep(15) 393 message.delete() 394 395 except Exception as e: 396 GoldyBot.logging.log("error", e) 397 """, 398 # Lambda expression: Returns nc_co 399 {"func":goldy_sub_command.func, "parent_command": parent_command, "command_name":goldy_sub_command.command_name, "help_des":goldy_sub_command.get_help_des(), 400 "self":goldy_sub_command, "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, 401 "class_":goldy_sub_command.extension, "no_perms_embed":self.no_perms_embed, "guild_not_registered_embed":self.guild_not_registered_embed, 402 "hidden":goldy_sub_command.is_hidden, "also_run_parent_CMD":also_run_parent_CMD, "goldy_parent_command": self}, return_data) 403 404 else: # Run as NORMAL command! 405 exec(f""" 406@parent_command.subcommand(name=command_name, description=help_des) 407async def slash_command_(interaction: Interaction{slash_command_params[0]}): 408 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 409 try: 410 if self.allowed_to_run(ctx): 411 if also_run_parent_CMD == True: await goldy_parent_command.func(ctx{parent_slash_command_params[1]}) 412 await func(ctx{slash_command_params[1]}) 413 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash command '{goldy_sub_command.code_name}' was executed.") 414 415 except GoldyBot.errors.MemberHasNoPermsForCommand: 416 if hidden == False: 417 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 418 message = await ctx.send(embed=no_perms_embed) 419 await asyncio.sleep(15) 420 await message.delete() 421 422 except GoldyBot.errors.GuildNotRegistered: 423 if hidden == False: 424 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 425 message = await ctx.send(embed=guild_not_registered_embed) 426 await asyncio.sleep(15) 427 await message.delete() 428 429 except Exception as e: 430 GoldyBot.logging.log("error", e) 431 """, 432 433 {"func":goldy_sub_command.func, "parent_command": parent_command, "command_name":goldy_sub_command.command_name, "help_des":goldy_sub_command.get_help_des(), 434 "self":goldy_sub_command, "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, 435 "no_perms_embed":self.no_perms_embed, "guild_not_registered_embed":self.guild_not_registered_embed, "hidden":goldy_sub_command.is_hidden, 436 "also_run_parent_CMD":also_run_parent_CMD, "goldy_parent_command": self}, return_data) 437 438 goldy_sub_command.update_command_object(return_data["slash_command_"]) 439 440 GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Sub Command '{goldy_sub_command.command_name}' of '{parent_command.name}' has been loaded.") 441 return goldy_sub_command 442 443 return inner(func, command_name, required_roles, help_des, slash_options) 444 445 return decorate 446 447 def allowed_to_run(self, ctx): 448 """Checks if the command is allowed to run with current circumstances.""" 449 goldy_config = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)) 450 451 # Check if guild is registered. 452 #-------------------------------- 453 if str(ctx.guild.id) in goldy_config.read("allowed_guilds"): 454 guild_code_name = GoldyBot.cache.FindGuilds(goldy_config).find_object_by_id(ctx.guild.id).code_name 455 guild_config = GoldyBot.utility.guilds.config.GuildConfig(GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.CONFIG + f"/{guild_code_name}/config.json"))) 456 457 if guild_config.is_extension_allowed(self.extension_name): 458 459 if not self.required_roles_ == []: 460 # If the required roles contain 'bot_dev' and the bot dev is running the command allow the command to execute. 461 #---------------------------------------------------------------------------------------------------------------- 462 if "bot_dev" in self.required_roles_: 463 if str(ctx.author.id) in GoldyBot.settings.BOT_DEVS: 464 return True 465 466 # If the required roles contain 'bot_admin' and a bot admin is running the command allow the command to execute. (NEW) 467 #---------------------------------------------------------------------------------------------------------------- 468 if "bot_admin" in self.required_roles_: 469 if str(ctx.author.id) in goldy_config.read("admin_users"): 470 return True 471 472 # Check if member has any of the required roles. 473 #---------------------------------------------------- 474 for role_code_name in self.required_roles_: 475 if not role_code_name in ["bot_dev", "bot_admin"]: 476 role = guild_config.get_role(ctx, role_code_name) 477 if GoldyBot.objects.member.Member(ctx).has_role(role): 478 return True 479 480 raise GoldyBot.errors.MemberHasNoPermsForCommand(f"The member '{ctx.author.name}' does not have the right permissions to use this command.") 481 482 else: 483 return True 484 485 else: 486 raise GoldyBot.errors.GuildNotRegistered(f"The guild '{ctx.guild.name}' has not been registered.") 487 488 @property 489 def guilds_allowed_in(self) -> List[int]: 490 """Returns the ids of the guilds this command is allowed to function in.""" 491 goldy_config = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)) 492 allowed_guilds = goldy_config.read("allowed_guilds") 493 494 guilds_command_is_allowed_in:List[int] = [] 495 496 for guild_id in allowed_guilds: 497 try: 498 guild_config = GoldyBot.utility.guilds.config.GuildConfig(GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.CONFIG + f"/{allowed_guilds[guild_id]}/config.json"))) 499 500 if guild_config.is_extension_allowed(self.extension_name): 501 guilds_command_is_allowed_in.append(int(guild_id)) 502 except FileNotFoundError: 503 pass 504 505 if guilds_command_is_allowed_in == []: guilds_command_is_allowed_in = [123] 506 507 print(guilds_command_is_allowed_in) 508 509 return guilds_command_is_allowed_in 510 511 def get_help_des(self) -> str: 512 """Returns the command's help description.""" 513 if self.help_des_ == None: 514 try: 515 return (importlib.import_module(f'.{self.command_name}', package="GoldyBot.utility.msgs")).help_des 516 517 except ImportError: 518 GoldyBot.logging.log("info", f"[{MODULE_NAME}] The command '{self.command_name}' does not have a 'msg' module, so the help command will not display a help description for it.") 519 return "None" 520 521 except AttributeError: 522 GoldyBot.logging.log("info", f"[{MODULE_NAME}] The command '{self.command_name}' does not contain 'help_des' variable in it's 'msg' module, so the help command will not display a help description.") 523 return "None" 524 else: 525 return self.help_des_
31 def __init__(self, func, command_object:nextcord.BaseApplicationCommand | commands.Command=None, command_name=None, 32 required_roles:list=[], slash_options:dict={}, help_des:str=None, hidden:bool=False, 33 parent_cmd:Command=None 34 ): 35 """Generates goldy bot command object with command function object.""" 36 self.func:function = func 37 self.command = command_object 38 """Nextcord command object.""" 39 40 if command_name == None: 41 self.command_name = self.func.__name__ 42 else: 43 self.command_name = command_name 44 self.required_roles_ = required_roles 45 self.slash_options_ = slash_options 46 self.params_ = list(self.func.__code__.co_varnames) 47 self.params_amount_ = self.func.__code__.co_argcount 48 self.help_des_ = help_des 49 self.is_hidden_ = hidden 50 51 self.parent_cmd_ = parent_cmd 52 53 self.in_extension_ = False 54 55 if self.params[0] == "self": 56 self.in_extension_ = True 57 self.params_.pop(0) 58 59 # Add command to extension in cache. 60 if self.in_extension: 61 if self.module.is_internal_module: 62 GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].append(self) 63 else: 64 GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].append(self) 65 else: 66 GoldyBot.cache.main_cache_dict["internal_modules"]["goldy"]["extensions"]["core"]["commands"].append(self) 67 68 super().__init__()
Generates goldy bot command object with command function object.
Finds and returns the object of the command's extension.
Returns the command object of the parent command if command has parent.
136 def mention(self) -> str: 137 """Returns mention of slash command, if registered as a slash command.""" 138 #TODO: Perhaps have this return codeblock if this command is not a slash command. 139 try: 140 if self.is_child == False: 141 return f"</{self.code_name}:{self.command.command_ids[0]}>" 142 else: 143 return f"</{self.parent_cmd.code_name} {self.code_name}:{self.command.command_ids[0]}>" 144 except (TypeError, AttributeError): 145 GoldyBot.log("warn", f"[{MODULE_NAME}] Tried to mention slash command '{self.code_name}' but could not find it's command id so I'm returning the mention without it.") 146 147 if self.is_child == False: return f"</{self.code_name}:0>" 148 else: return f"</{self.parent_cmd.code_name} {self.code_name}:0>"
Returns mention of slash command, if registered as a slash command.
150 def create_slash(self) -> nextcord.BaseApplicationCommand: 151 """Creates slash command.""" 152 153 GoldyBot.logging.log(f"[{MODULE_NAME}] [{self.command_name.upper()}] Creating slash command...") 154 slash_command_params = self.slash_commands_params_generator() 155 156 return_data = {} 157 158 # Make slash command only visible to admins if it is hidden. 159 default_member_permissions = None 160 if self.is_hidden: default_member_permissions = nextcord.Permissions(permissions=8) 161 162 163 if self.in_extension == True: # Run in EXTENSION! 164 exec(f""" 165@client.slash_command(name=command_name, description=help_des, guild_ids=guilds_allowed_in, default_member_permissions=default_member_permissions) 166async def slash_command_(interaction: Interaction{slash_command_params[0]}): 167 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 168 try: 169 if self.allowed_to_run(ctx): 170 await func(class_, ctx{slash_command_params[1]}) 171 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash command '{self.code_name}' was executed.") 172 173 except GoldyBot.errors.MemberHasNoPermsForCommand: 174 if hidden == False: 175 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 176 message = await ctx.send(embed=no_perms_embed) 177 await asyncio.sleep(6) 178 await message.delete() 179 180 except GoldyBot.errors.GuildNotRegistered: 181 if hidden == False: 182 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 183 message = await ctx.send(embed=guild_not_registered_embed) 184 await asyncio.sleep(15) 185 message.delete() 186 187 except Exception as e: 188 GoldyBot.logging.log("error", e) 189 """, 190 191 {"func":self.func, "client":GoldyBot.cache.main_cache_dict["client"], "command_name":self.command_name, "help_des":self.get_help_des(), "self":self, 192 "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, "class_":self.extension, "no_perms_embed":self.no_perms_embed, 193 "guild_not_registered_embed":self.guild_not_registered_embed, "hidden":self.is_hidden, "guilds_allowed_in":self.guilds_allowed_in, 194 "default_member_permissions":default_member_permissions}, return_data) 195 196 else: # Run as NORMAL command! 197 exec(f""" 198@client.slash_command(name=command_name, description=help_des, guild_ids=guilds_allowed_in, default_member_permissions=default_member_permissions) 199async def slash_command_(interaction: Interaction{slash_command_params[0]}): 200 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 201 try: 202 if self.allowed_to_run(ctx): 203 await func(ctx{slash_command_params[1]}) 204 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash command '{self.code_name}' was executed.") 205 206 except GoldyBot.errors.MemberHasNoPermsForCommand: 207 if hidden == False: 208 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 209 message = await ctx.send(embed=no_perms_embed) 210 await asyncio.sleep(15) 211 await message.delete() 212 213 except GoldyBot.errors.GuildNotRegistered: 214 if hidden == False: 215 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 216 message = await ctx.send(embed=guild_not_registered_embed) 217 await asyncio.sleep(15) 218 await message.delete() 219 220 except Exception as e: 221 GoldyBot.logging.log("error", e) 222 """, 223 224 {"func":self.func, "client":GoldyBot.cache.main_cache_dict["client"], "command_name":self.command_name, "help_des":self.get_help_des(), "self":self, 225 "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, "no_perms_embed":self.no_perms_embed, 226 "guild_not_registered_embed":self.guild_not_registered_embed, "hidden":self.is_hidden, "guilds_allowed_in":self.guilds_allowed_in, 227 "default_member_permissions":default_member_permissions}, return_data) 228 229 GoldyBot.logging.log(f"[{MODULE_NAME}] [{self.command_name.upper()}] Slash command created!") 230 231 self.command = return_data["slash_command_"] 232 return return_data["slash_command_"]
Creates slash command.
234 def remove(self): 235 """Removes command from nextcord.""" 236 command_application_object = self.command 237 238 # Remove command from extension in cache. 239 if self.in_extension: 240 if self.module.is_internal_module: 241 GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].remove(self) 242 else: 243 GoldyBot.cache.main_cache_dict["modules"][f"{self.module_name}"]["extensions"][f"{self.extension_name}"]["commands"].remove(self) 244 else: 245 GoldyBot.cache.main_cache_dict["internal_modules"]["goldy"]["extensions"]["core"]["commands"].remove(self) 246 247 # Remove from nextcord. 248 client = GoldyBot.cache.client() 249 client.remove_command(name=self.code_name) 250 251 for guild_id in self.guilds_allowed_in: 252 print(command_application_object.command_ids) #TODO: Problem here! 253 GoldyBot.async_loop.run_until_complete(client.delete_application_commands(command_application_object, guild_id=guild_id)) 254 255 GoldyBot.cache.main_cache_dict["client"] = client 256 257 GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Removed the command '{self.code_name}'!") 258 return True
Removes command from nextcord.
260 def any_args_missing(self, command_executers_args:tuple) -> bool: 261 """Checks if the args given by the command executer matches what parameters the command needs.""" 262 if len(command_executers_args) == len(self.params[1:]): 263 return True 264 else: 265 return False
Checks if the args given by the command executer matches what parameters the command needs.
267 def slash_commands_params_generator(self): 268 """Generates a string of params for slash commands. This is more of an in-house thing.""" 269 params_amount = len(self.params[1:]) 270 slash_command_params = "" 271 slash_command_args = "" 272 273 if params_amount >= 1: 274 slash_command_params = ", " 275 slash_command_args = ", " 276 count = 0 277 for param in self.params[1:]: 278 count += 1 279 280 try: 281 # String 282 if isinstance(self.slash_options_[param.lower()], str): 283 default_value = f"='{self.slash_options_[param.lower()]}'" 284 285 # Slash Option 286 if isinstance(self.slash_options_[param.lower()], nextcord.SlashOption): 287 slash_option:nextcord.SlashOption = self.slash_options_[param.lower()] 288 289 if isinstance(slash_option.name, str): 290 name = f"'{slash_option.name}'" 291 else: 292 name = None 293 294 if isinstance(slash_option.description, str): 295 description = f"'{slash_option.description}'" 296 else: 297 description = None 298 299 if isinstance(slash_option.required, nextcord.utils._MissingSentinel): 300 required = None 301 else: 302 required = slash_option.required 303 304 if isinstance(slash_option.choices, nextcord.utils._MissingSentinel): 305 choices = None 306 else: 307 choices = slash_option.choices 308 309 """ 310 if isinstance(slash_option.min_value, nextcord.utils._MissingSentinel): 311 min_value = None 312 else: 313 min_value = slash_option.min_value 314 315 if isinstance(slash_option.max_value, nextcord.utils._MissingSentinel): 316 max_value = None 317 else: 318 max_value = slash_option.max_value 319 """ 320 321 if isinstance(slash_option.autocomplete, nextcord.utils._MissingSentinel): 322 autocomplete = None 323 else: 324 autocomplete = slash_option.autocomplete 325 326 if isinstance(slash_option.default, str): 327 default = f"'{slash_option.default}'" 328 else: 329 default = None 330 331 default_value = f"""=nextcord.SlashOption(name={name}, description={description}, required={required}, 332 choices={choices}, autocomplete={autocomplete}, default={default}, verify={slash_option._verify})""" 333 334 else: 335 default_value = f"={self.slash_options_[param.lower()]}" 336 337 except KeyError: 338 default_value = "" 339 340 if count >= params_amount: 341 slash_command_params += f"{param}{default_value}" 342 slash_command_args += f"{param}" 343 else: 344 slash_command_params += f"{param}{default_value}, " 345 slash_command_args += f"{param}, " 346 347 return (slash_command_params, slash_command_args)
Generates a string of params for slash commands. This is more of an in-house thing.
349 def update_command_object(self, command_object:commands.Command): 350 """Adds/updates this command object to the class.""" 351 self.command = command_object
Adds/updates this command object to the class.
353 def sub_command(self, command_name:str=None, required_roles:list=[], help_des:str=None, slash_options:Dict[str, nextcord.SlashOption]={}, also_run_parent_CMD:bool=True): 354 """Create a lovely sub command from this slash command. 😀 (Only works with slash commands.)""" 355 356 def decorate(func): 357 def inner(func, command_name, required_roles, help_des, slash_options): 358 parent_command = self.command 359 360 return_data = {} 361 362 goldy_sub_command = Command(func, command_name=command_name, required_roles=required_roles, slash_options=slash_options, help_des=help_des, parent_cmd=self) 363 slash_command_params = goldy_sub_command.slash_commands_params_generator() 364 parent_slash_command_params = self.slash_commands_params_generator() 365 366 if self.in_extension == True: # Run in EXTENSION! 367 exec(f""" 368@parent_command.subcommand(name=command_name, description=help_des) 369async def slash_command_(interaction: Interaction{slash_command_params[0]}): 370 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 371 try: 372 if self.allowed_to_run(ctx): 373 continue_onto_subcommand = None 374 if also_run_parent_CMD == True: continue_onto_subcommand = await goldy_parent_command.func(class_, ctx{parent_slash_command_params[1]}) 375 if not continue_onto_subcommand == False: 376 await func(class_, ctx{slash_command_params[1]}) 377 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash subcommand '{goldy_sub_command.code_name}' was executed.") 378 else: 379 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash subcommand '{goldy_sub_command.code_name}' never executed because parent command returned 'False'.") 380 381 except GoldyBot.errors.MemberHasNoPermsForCommand: 382 if hidden == False: 383 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 384 message = await ctx.send(embed=no_perms_embed) 385 await asyncio.sleep(6) 386 await message.delete() 387 388 except GoldyBot.errors.GuildNotRegistered: 389 if hidden == False: 390 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 391 message = await ctx.send(embed=guild_not_registered_embed) 392 await asyncio.sleep(15) 393 message.delete() 394 395 except Exception as e: 396 GoldyBot.logging.log("error", e) 397 """, 398 # Lambda expression: Returns nc_co 399 {"func":goldy_sub_command.func, "parent_command": parent_command, "command_name":goldy_sub_command.command_name, "help_des":goldy_sub_command.get_help_des(), 400 "self":goldy_sub_command, "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, 401 "class_":goldy_sub_command.extension, "no_perms_embed":self.no_perms_embed, "guild_not_registered_embed":self.guild_not_registered_embed, 402 "hidden":goldy_sub_command.is_hidden, "also_run_parent_CMD":also_run_parent_CMD, "goldy_parent_command": self}, return_data) 403 404 else: # Run as NORMAL command! 405 exec(f""" 406@parent_command.subcommand(name=command_name, description=help_des) 407async def slash_command_(interaction: Interaction{slash_command_params[0]}): 408 ctx = GoldyBot.objects.slash.InteractionToCtx(interaction) 409 try: 410 if self.allowed_to_run(ctx): 411 if also_run_parent_CMD == True: await goldy_parent_command.func(ctx{parent_slash_command_params[1]}) 412 await func(ctx{slash_command_params[1]}) 413 GoldyBot.logging.log(f"[{MODULE_NAME}] The slash command '{goldy_sub_command.code_name}' was executed.") 414 415 except GoldyBot.errors.MemberHasNoPermsForCommand: 416 if hidden == False: 417 no_perms_embed.description = GoldyBot.utility.msgs.bot.CommandNoPerms.Embed.des.format(ctx.author.mention) 418 message = await ctx.send(embed=no_perms_embed) 419 await asyncio.sleep(15) 420 await message.delete() 421 422 except GoldyBot.errors.GuildNotRegistered: 423 if hidden == False: 424 guild_not_registered_embed.description = GoldyBot.utility.msgs.bot.CommandGuildNotRegistered.Embed.des.format(ctx.author.mention) 425 message = await ctx.send(embed=guild_not_registered_embed) 426 await asyncio.sleep(15) 427 await message.delete() 428 429 except Exception as e: 430 GoldyBot.logging.log("error", e) 431 """, 432 433 {"func":goldy_sub_command.func, "parent_command": parent_command, "command_name":goldy_sub_command.command_name, "help_des":goldy_sub_command.get_help_des(), 434 "self":goldy_sub_command, "Interaction": GoldyBot.nextcord.Interaction, "GoldyBot": GoldyBot, "asyncio":asyncio, "nextcord":nextcord, 435 "no_perms_embed":self.no_perms_embed, "guild_not_registered_embed":self.guild_not_registered_embed, "hidden":goldy_sub_command.is_hidden, 436 "also_run_parent_CMD":also_run_parent_CMD, "goldy_parent_command": self}, return_data) 437 438 goldy_sub_command.update_command_object(return_data["slash_command_"]) 439 440 GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Sub Command '{goldy_sub_command.command_name}' of '{parent_command.name}' has been loaded.") 441 return goldy_sub_command 442 443 return inner(func, command_name, required_roles, help_des, slash_options) 444 445 return decorate
Create a lovely sub command from this slash command. 😀 (Only works with slash commands.)
447 def allowed_to_run(self, ctx): 448 """Checks if the command is allowed to run with current circumstances.""" 449 goldy_config = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)) 450 451 # Check if guild is registered. 452 #-------------------------------- 453 if str(ctx.guild.id) in goldy_config.read("allowed_guilds"): 454 guild_code_name = GoldyBot.cache.FindGuilds(goldy_config).find_object_by_id(ctx.guild.id).code_name 455 guild_config = GoldyBot.utility.guilds.config.GuildConfig(GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.CONFIG + f"/{guild_code_name}/config.json"))) 456 457 if guild_config.is_extension_allowed(self.extension_name): 458 459 if not self.required_roles_ == []: 460 # If the required roles contain 'bot_dev' and the bot dev is running the command allow the command to execute. 461 #---------------------------------------------------------------------------------------------------------------- 462 if "bot_dev" in self.required_roles_: 463 if str(ctx.author.id) in GoldyBot.settings.BOT_DEVS: 464 return True 465 466 # If the required roles contain 'bot_admin' and a bot admin is running the command allow the command to execute. (NEW) 467 #---------------------------------------------------------------------------------------------------------------- 468 if "bot_admin" in self.required_roles_: 469 if str(ctx.author.id) in goldy_config.read("admin_users"): 470 return True 471 472 # Check if member has any of the required roles. 473 #---------------------------------------------------- 474 for role_code_name in self.required_roles_: 475 if not role_code_name in ["bot_dev", "bot_admin"]: 476 role = guild_config.get_role(ctx, role_code_name) 477 if GoldyBot.objects.member.Member(ctx).has_role(role): 478 return True 479 480 raise GoldyBot.errors.MemberHasNoPermsForCommand(f"The member '{ctx.author.name}' does not have the right permissions to use this command.") 481 482 else: 483 return True 484 485 else: 486 raise GoldyBot.errors.GuildNotRegistered(f"The guild '{ctx.guild.name}' has not been registered.")
Checks if the command is allowed to run with current circumstances.
511 def get_help_des(self) -> str: 512 """Returns the command's help description.""" 513 if self.help_des_ == None: 514 try: 515 return (importlib.import_module(f'.{self.command_name}', package="GoldyBot.utility.msgs")).help_des 516 517 except ImportError: 518 GoldyBot.logging.log("info", f"[{MODULE_NAME}] The command '{self.command_name}' does not have a 'msg' module, so the help command will not display a help description for it.") 519 return "None" 520 521 except AttributeError: 522 GoldyBot.logging.log("info", f"[{MODULE_NAME}] The command '{self.command_name}' does not contain 'help_des' variable in it's 'msg' module, so the help command will not display a help description.") 523 return "None" 524 else: 525 return self.help_des_
Returns the command's help description.
11class Member(database.member.Member): 12 """A class representing a discord member in Goldy Bot.""" 13 def __init__(self, ctx, member_id:str|int=None, mention_str:str=None, member_object:nextcord.Member=None): 14 self.ctx = ctx 15 self.member_id_ = member_id 16 self.mention_str_ = mention_str 17 self.member_object_ = member_object 18 19 if self.member_object_ == None: 20 # Find the member. 21 self.member = self.find_member(self.member_id) 22 else: 23 self.member = self.member_object_ 24 25 super().__init__(ctx, self) 26 27 @property 28 def member_id(self) -> str: 29 """Returns id of discord member. Defaults to ctx author if ``member_id``, ``mention_str`` and ``member_user_object`` are None.""" 30 if not self.member_id_ == None: return str(self.member_id_) 31 if not self.mention_str_ == None: return self.mention_str_[self.mention_str_.index("@") + 1: self.mention_str_.index(">")] # Getting id from mention (e.g. <@332592361307897856>). 32 if not self.member_object_ == None: return str(self.member_object_.id) 33 else: 34 if isinstance(self.ctx, Interaction): 35 return str(InteractionToCtx(self.ctx).author.id) 36 else: 37 return str(self.ctx.author.id) 38 39 @property 40 def name(self): 41 """Returns the discord name of member including tag. Does not return server nickname!""" 42 return self.member.name 43 44 @property 45 def display_name(self): 46 """Returns display name of member, so server nickname.""" 47 return self.member.display_name 48 49 # Roles 50 #--------- 51 def has_role(self, role:role.Role): 52 """Checks if the member has a certain role.""" 53 if role.role in self.member.roles: 54 return True 55 else: 56 return False 57 58 async def add_role(self, role:role.Role): 59 """This method adds the specified role to this member.""" 60 if not self.has_role(role): 61 await self.member.add_roles(role) 62 return True 63 else: 64 return True 65 66 async def remove_role(self, role:role.Role): 67 """This method removes the specified role from this member.""" 68 if self.has_role(role): 69 await self.member.remove_roles(role) 70 return True 71 else: 72 return None 73 74 def find_member(self, member_id:int|str) -> nextcord.Member | None: 75 """Finds the damn member!""" 76 77 if not member_id == None: 78 member = nextcord.utils.get(self.ctx.guild.members, id=int(member_id)) 79 80 if member is None: raise GoldyBot.errors.FailedToFindMember() 81 82 return member 83 else: 84 return None 85 86 # Utils 87 async def send(self, **args): 88 args.pop("ephemeral") 89 await self.member.send(**args)
A class representing a discord member in Goldy Bot.
13 def __init__(self, ctx, member_id:str|int=None, mention_str:str=None, member_object:nextcord.Member=None): 14 self.ctx = ctx 15 self.member_id_ = member_id 16 self.mention_str_ = mention_str 17 self.member_object_ = member_object 18 19 if self.member_object_ == None: 20 # Find the member. 21 self.member = self.find_member(self.member_id) 22 else: 23 self.member = self.member_object_ 24 25 super().__init__(ctx, self)
Returns id of discord member. Defaults to ctx author if member_id
, mention_str
and member_user_object
are None.
51 def has_role(self, role:role.Role): 52 """Checks if the member has a certain role.""" 53 if role.role in self.member.roles: 54 return True 55 else: 56 return False
Checks if the member has a certain role.
58 async def add_role(self, role:role.Role): 59 """This method adds the specified role to this member.""" 60 if not self.has_role(role): 61 await self.member.add_roles(role) 62 return True 63 else: 64 return True
This method adds the specified role to this member.
66 async def remove_role(self, role:role.Role): 67 """This method removes the specified role from this member.""" 68 if self.has_role(role): 69 await self.member.remove_roles(role) 70 return True 71 else: 72 return None
This method removes the specified role from this member.
74 def find_member(self, member_id:int|str) -> nextcord.Member | None: 75 """Finds the damn member!""" 76 77 if not member_id == None: 78 member = nextcord.utils.get(self.ctx.guild.members, id=int(member_id)) 79 80 if member is None: raise GoldyBot.errors.FailedToFindMember() 81 82 return member 83 else: 84 return None
Finds the damn member!
9class Role(): 10 """ 11 A class representing a discord role in Goldy Bot. Either 'role_id', 'role_name', 'mention_str' or 'role_object' has to be passed in the 'Role()'. 12 13 Raises FailedToFindRole() when role is not found. 14 """ 15 def __init__(self, ctx, role_id:str=None, role_name:str=None, role_object:nextcord.Role=None, mention_str:str=None): 16 self.ctx = ctx 17 self.role_id_ = role_id 18 self.role_name_ = role_name 19 self.mention_str_ = mention_str 20 self.role_object_ = role_object 21 22 self.role_ = None 23 24 if self.role_object_ == None: 25 self.role_ = self.find_role(self.role_id, self.role_name_) 26 else: 27 self.role_ = self.role_object_ 28 29 @property 30 def role(self) -> nextcord.Role: 31 """Returns the actual representation of the role in nextcord.""" 32 return self.role_ 33 34 @property 35 def role_id(self) -> str|None: 36 """Returns id of discord role. Returns ``None`` if ``role_id``, ``role_name``, ``mention_str`` and ``role_object`` are left blank.""" 37 if not self.role_id_ == None: return str(self.role_id_) 38 if not self.mention_str_ == None: return self.mention_str_[3:-1] 39 if not self.role_object_ == None: return str(self.role_object_.id) 40 41 return None 42 43 @property 44 def role_name(self) -> str: 45 """Returns the name of the role.""" 46 return self.role.name 47 48 def find_role(self, role_id:int|str, role_name:str=None) -> nextcord.Role: 49 role:nextcord.Role 50 51 if role_name == None: 52 if not role_id == None: 53 role = self.ctx.guild.get_role(int(role_id)) 54 else: 55 role = None 56 57 if role == None: 58 raise FailedToFindRole(option_used="id", option_value=role_id) 59 else: 60 GoldyBot.logging.log(f"Found the role '{role.name}' by id.") 61 return role 62 63 else: 64 role = nextcord.utils.get(self.ctx.guild.roles, name=role_name) 65 66 if role == None: 67 raise FailedToFindRole(option_used="role name", option_value=role_name) 68 else: 69 GoldyBot.logging.log(f"Found the role '{role.name}' by name.") 70 return role
A class representing a discord role in Goldy Bot. Either 'role_id', 'role_name', 'mention_str' or 'role_object' has to be passed in the 'Role()'.
Raises FailedToFindRole() when role is not found.
15 def __init__(self, ctx, role_id:str=None, role_name:str=None, role_object:nextcord.Role=None, mention_str:str=None): 16 self.ctx = ctx 17 self.role_id_ = role_id 18 self.role_name_ = role_name 19 self.mention_str_ = mention_str 20 self.role_object_ = role_object 21 22 self.role_ = None 23 24 if self.role_object_ == None: 25 self.role_ = self.find_role(self.role_id, self.role_name_) 26 else: 27 self.role_ = self.role_object_
48 def find_role(self, role_id:int|str, role_name:str=None) -> nextcord.Role: 49 role:nextcord.Role 50 51 if role_name == None: 52 if not role_id == None: 53 role = self.ctx.guild.get_role(int(role_id)) 54 else: 55 role = None 56 57 if role == None: 58 raise FailedToFindRole(option_used="id", option_value=role_id) 59 else: 60 GoldyBot.logging.log(f"Found the role '{role.name}' by id.") 61 return role 62 63 else: 64 role = nextcord.utils.get(self.ctx.guild.roles, name=role_name) 65 66 if role == None: 67 raise FailedToFindRole(option_used="role name", option_value=role_name) 68 else: 69 GoldyBot.logging.log(f"Found the role '{role.name}' by name.") 70 return role
13class InteractionToCtx(): 14 """This Goldy Bot class is used to convert interactions to ctx.""" 15 def __init__(self, interaction: Interaction): 16 self.interaction = interaction 17 18 @property 19 def guild(self) -> Interaction.guild: 20 return self.interaction.guild 21 22 @property 23 def author(self): 24 return self.interaction.user 25 26 @property 27 def channel(self): 28 return self.interaction.channel 29 30 @property 31 def response(self) -> InteractionResponse: 32 return self.interaction.response 33 34 async def send(self, text:str=None, **kwargs): 35 if not text == None: 36 await self.interaction.send(text) 37 else: 38 await self.interaction.send(**kwargs) 39 40 return Message(self.interaction) 41 42 async def send_modal(self, modal:nextcord.ui.Modal): 43 """Sends modal.""" 44 await self.interaction.response.send_modal(modal) 45 46 return Message(self.interaction)
This Goldy Bot class is used to convert interactions to ctx.
10class Channel(): 11 """A class representing a discord channel in Goldy Bot.""" 12 def __init__(self, ctx, channel_id:str|int=None, mention_str:str=None, channel_object:nextcord.abc.GuildChannel=None): 13 14 self.ctx = ctx 15 self.channel_id_ = channel_id 16 self.mention_str_ = mention_str 17 self.channel_object_ = channel_object 18 19 self.channel:nextcord.abc.GuildChannel|None 20 21 if self.channel_object_ == None: 22 # Find the channel. 23 self.channel = self.find_channel(self.channel_id) 24 else: 25 self.channel = self.channel_object_ 26 27 @property 28 def channel_id(self) -> str: 29 """Returns id of discord channel. Defaults to ctx channel if ``channel_id``, ``mention_str`` and ``channel_object`` are None.""" 30 if not self.channel_id_ == None: return str(self.channel_id_) 31 if not self.mention_str_ == None: return self.mention_str_[3:-1] 32 if not self.channel_object_ == None: return str(self.channel_object_.id) 33 else: 34 if isinstance(self.ctx, Interaction): 35 return str(InteractionToCtx(self.ctx).channel.id) 36 else: 37 return str(self.ctx.channel.id) 38 39 @property 40 def name(self): 41 """Returns the discord channel name.""" 42 return self.channel.name 43 44 @property 45 def display_name(self): 46 """Alias of ``Channel().name``""" 47 return self.name 48 49 async def purge(self, amount:int|None): 50 """Deletes specified number of messages in this channel. (Only works if this channel is a text channel.)""" 51 if isinstance(self.channel, nextcord.TextChannel): 52 channel:nextcord.TextChannel = self.channel 53 54 deleted = None 55 try: 56 deleted = await channel.purge(limit=amount) 57 GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Deleted '{len(deleted)}' messages from the channel '{self.name}'.") 58 except Exception as e: 59 GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Couldn't delete from '{self.name}' because '{e}'.") 60 61 return deleted 62 else: 63 GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Can't purge messages because this channel isn't a text channel!") 64 65 66 def find_channel(self, channel_id:int|str) -> nextcord.abc.GuildChannel | None: 67 """Finds the damn channel!""" 68 69 if not channel_id == None: 70 return nextcord.utils.get(self.ctx.guild.channels, id=int(channel_id)) 71 else: 72 return None
A class representing a discord channel in Goldy Bot.
12 def __init__(self, ctx, channel_id:str|int=None, mention_str:str=None, channel_object:nextcord.abc.GuildChannel=None): 13 14 self.ctx = ctx 15 self.channel_id_ = channel_id 16 self.mention_str_ = mention_str 17 self.channel_object_ = channel_object 18 19 self.channel:nextcord.abc.GuildChannel|None 20 21 if self.channel_object_ == None: 22 # Find the channel. 23 self.channel = self.find_channel(self.channel_id) 24 else: 25 self.channel = self.channel_object_
Returns id of discord channel. Defaults to ctx channel if channel_id
, mention_str
and channel_object
are None.
49 async def purge(self, amount:int|None): 50 """Deletes specified number of messages in this channel. (Only works if this channel is a text channel.)""" 51 if isinstance(self.channel, nextcord.TextChannel): 52 channel:nextcord.TextChannel = self.channel 53 54 deleted = None 55 try: 56 deleted = await channel.purge(limit=amount) 57 GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Deleted '{len(deleted)}' messages from the channel '{self.name}'.") 58 except Exception as e: 59 GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Couldn't delete from '{self.name}' because '{e}'.") 60 61 return deleted 62 else: 63 GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Can't purge messages because this channel isn't a text channel!")
Deletes specified number of messages in this channel. (Only works if this channel is a text channel.)
66 def find_channel(self, channel_id:int|str) -> nextcord.abc.GuildChannel | None: 67 """Finds the damn channel!""" 68 69 if not channel_id == None: 70 return nextcord.utils.get(self.ctx.guild.channels, id=int(channel_id)) 71 else: 72 return None
Finds the damn channel!
2class Currency(): 3 """ 4 Base class for a currency in Goldy Bot. Use this to create you own custom currency. 5 6 --------------- 7 ### ***``Example:``*** 8 9 Hello, want to make your own custom currency? Well anyways you came to the right place. 10 Below I show you an example on how to create your very own currency in Goldy Bot using the currency base class. 11 12 ```python 13 class GBP(GoldyBot.Currency): 14 def __init__(self): 15 super().__init__("GBP", "British Pounds", "💷", 600) 16 ``` 17 - This is how a custom currency is implemented. The code name is ``GBP``, the display name is ``British Pounds``, the currency icon/emoji is a ``pound banknote`` (💷) emoji and the default balance for this currency is 600. 18 19 ```python 20 class UwUCoin(GoldyBot.Currency): 21 def __init__(self): 22 super().__init__("uwu_coin", "UwU Coin", "🟡", 0) 23 ``` 24 - Here's another example for fun. 😁 25 """ 26 27 def __init__(self, code_name:str, display_name:str, display_emoji:str="💷", default_bal:int=600): 28 self.code_name_ = code_name 29 self.display_name_ = display_name 30 self.display_emoji_ = display_emoji 31 self.default_bal_ = default_bal 32 33 @property 34 def code_name(self): 35 """Returns code name of currency.""" 36 return self.code_name_ 37 38 @property 39 def display_name(self): 40 """Returns display name of currency.""" 41 return self.display_name_ 42 43 @property 44 def display_emoji(self): 45 """Returns some sort of emoji or icon that is used to identify this currency.""" 46 return self.display_emoji_ 47 48 @property 49 def default_bal(self): 50 """Returns the default balance for this currency.""" 51 return self.default_bal_
Base class for a currency in Goldy Bot. Use this to create you own custom currency.
Example:
Hello, want to make your own custom currency? Well anyways you came to the right place. Below I show you an example on how to create your very own currency in Goldy Bot using the currency base class.
class GBP(GoldyBot.Currency):
def __init__(self):
super().__init__("GBP", "British Pounds", "💷", 600)
- This is how a custom currency is implemented. The code name is
GBP
, the display name isBritish Pounds
, the currency icon/emoji is apound banknote
(💷) emoji and the default balance for this currency is 600.
class UwUCoin(GoldyBot.Currency):
def __init__(self):
super().__init__("uwu_coin", "UwU Coin", "🟡", 0)
- Here's another example for fun. 😁