async def leaderboard(self, ctx) -> None: await asyncio.sleep(1) # let the database catch up # index discord.Member object: all_member_data[i][0] # index member data: all_member_data[i][1] all_member_data = GuildDatabase(ctx.guild).get_all_members() author_data = [ ctx.author, GuildDatabase(ctx.guild).get_member_data(ctx.author) ] all_member_data.sort(key=lambda x: x[1]["EXP"], reverse=True) embed = construct_embed(title=f"`{ctx.guild}` Leaderboard", color=embed_color["DEFAULT"]) embed.description = f"You are rank `#{(all_member_data.index(author_data)) + 1}` on this server." embed.set_thumbnail(url="https://files.catbox.moe/alavwx.gif") server_leaderboard = "" for i in range(0, 10): member_data = all_member_data[i] server_leaderboard += f"**{i + 1}.** `{member_data[0].name}` " server_leaderboard += f'with {round(member_data[1]["EXP"])} Exp.' server_leaderboard += "\n" embed.add_field(name="Top 10 Members", value=server_leaderboard) await ctx.send(embed=embed)
async def cogs_utility(self, ctx) -> None: if ctx.invoked_subcommand == None: embed = construct_embed(title="Available Commands") embed.color = embed_color["DEFAULT"] embed.description = "\n".join(f"`{str(x)}`" for x in ctx.command.commands) await ctx.send(embed=embed)
def create_now_playing_embed(self, for_player_loop=False): source = self.voice_client.source embed = construct_embed( title="Now Playing", description=f"[{source.title}]({source.webpage_url})", color=0x2F3136) # todo: if not lazy stop using tiemdate.timedelta, cringe lol # .177000 song_duration = int(source.duration) embed.add_field(name="Requester", value=f"`{source.requester}`") if for_player_loop: embed.add_field(name="Duration", value=f"`{timedelta(seconds=song_duration)}`") else: time_passed = int( (datetime.now() - self.play_timestamp).total_seconds()) embed.add_field( name="Duration", value= f"`{timedelta(seconds=time_passed)} / {timedelta(seconds=song_duration)}`" ) embed.set_thumbnail(url=source.thumbnail) return embed
async def cogs_list(self, ctx) -> None: cogs = [] for cog in os.listdir("cogs"): cogs.append(cog) loaded_cogs = [] for _, cog in self.bot.cogs.items(): loaded_cogs.append(cog.qualified_name) embed = construct_embed(title="Cogs List", color=embed_color["DEFAULT"]) for cog in cogs: cog = f"cogs.{cog[:-3]}" globals()["ext"] = importlib.import_module(cog) for i in range(0, len(loaded_cogs)): for obj in dir(ext): if loaded_cogs[i] == obj: loaded_cogs[ i] = f"`{loaded_cogs[i]} ({cog.split('.')[1] + '.py'})`" for i in range(0, len(cogs)): cogs[i] = f"`{cogs[i]}`" embed.add_field(name="All Cogs", value="\n".join(cog for cog in cogs)) embed.add_field(name="Loaded Cogs", value="\n".join(cog for cog in loaded_cogs)) await ctx.send(embed=embed)
async def on_message_delete(self, message): if message.author.bot: return if len(message.embeds) != 0: return # embeds are tricky, rather just ignore them embed = construct_embed( title="Message deleted.", description = f"Username: {message.author}\nUser ID: {message.author.id}", color = 0xEE28FC, timestamp=datetime.utcnow() ) embed.set_thumbnail(url=message.author.avatar_url) embed.add_field(name="Content", value=message.content, inline=False) async for entry in message.guild.audit_logs(limit=1): if entry.action == AuditLogAction.message_delete: if entry.user.bot: return # we don't want to log bots deleting messages if entry.target == message.author: embed.title = f"A message by {message.author} has been deleted." embed.add_field(name="Responsible", value=entry.user, inline=False) channel = self.bot.get_channel_by_name(message.guild, "audit") await channel.send(embed=embed)
async def on_member_remove(self, member): if member.bot: return embed = construct_embed( title="A member has left the server.", description = f"Username: {member}\nUser ID: {member.id}", color = 0x2F3136, timestamp=datetime.utcnow() ) embed.set_thumbnail(url=member.avatar_url) async for entry in member.guild.audit_logs(limit=1): if entry.action == AuditLogAction.ban: if entry.target == member: embed.color = 0xFF3030 embed.add_field(name="Reason", value=f"Banned by {entry.user.mention}", inline=False) elif entry.action == AuditLogAction.kick: if entry.target == member: embed.color = 0xFCDB03 embed.add_field(name="Reason", value=f"Kicked by {entry.user.mention}", inline=False) channel = self.bot.get_channel_by_name(member.guild, "audit") await channel.send(embed=embed)
async def user(self, ctx, user = None): user = await self.bot.get_user(ctx, user) if user == None: return await ctx.send("Unable to find this User.") embed = construct_embed( title=f"User `{user}`", color=embed_color["DEFAULT"] ) embed.set_thumbnail(url=user.avatar_url) embed.add_field( name="Information", value=f"""**ID**: {user.id} **Bot**: {'Yes' if user.bot else 'No'} **Account Created at**: {user.created_at.strftime("%B %d %Y, %H:%M")} """, inline=False ) if user not in self.bot.users: embed.description = "I do not share a server with this user." else: shared_guilds = [] for guild in self.bot.guilds: for member in guild.members: if user == member: shared_guilds.append(guild) embed.add_field(name="Shared Servers", value=", ".join(f'`{str(guild)}`' for guild in shared_guilds)) await ctx.send(embed=embed)
async def avatar(self, ctx, member = None): member = await self.bot.get_user(ctx, member) if member == None: return await ctx.send("Unable to find this Member.") embed = construct_embed( title=f"Avatar of `{member}`", description=f"[Download Link]({member.avatar_url_as(format='jpg')})", color=embed_color["DEFAULT"] ) embed.set_image(url=member.avatar_url) await ctx.send(embed=embed)
async def database_search(self, ctx, guild=None) -> None: database_list = [] for database in os.listdir("database"): database_list.append(database[:-3]) embed = construct_embed(title="Search results", color=embed_color["DEFAULT"]) found = False # database names are guild IDs if guild in database_list: found = True guild = self.bot.get_guild(int(guild)) embed.set_thumbnail(url=guild.icon_url) embed.add_field(name=guild.name, value=f"**Member Count**: {len(guild.members)}", inline=True) else: matching_guilds = [] for x in database_list: x = self.bot.get_guild(int(x)) if guild in x.name: matching_guilds.append(x) if len(matching_guilds) > 0: found = True for x in matching_guilds: if len(matching_guilds) == 1: embed.set_thumbnail(url=x.icon_url) embed.add_field( name=x.name, value= f"**Member Count**: {len(x.members)}\n**ID**: {x.id}", inline=True) if not found: embed.description = "Nothing found." await ctx.send(embed=embed)
async def on_member_join(self, member): if member.bot: return embed = construct_embed( title="A member has joined the server.", description = f"Username: {member}\nUser ID: {member.id}\nAccount Date: {member.created_at.strftime('%Y/%m/%d')}\n", color=0x2F3136, timestamp=datetime.utcnow() ) embed.set_thumbnail(url=member.avatar_url) if GuildDatabase(member.guild).check_member(member) == True: embed.description += "Member has already joined this server previously." channel = self.bot.get_channel_by_name(member.guild, "audit") await channel.send(embed=embed)
async def on_channel_prune(self, chan, messages, member): embed = construct_embed( title=f"`{len(messages) - 1}` messages pruned in `#{chan}`.", description = f"Username: {member}\nUser ID: {member.id}", color= 0xFF5EBC, timestamp=datetime.utcnow() ) embed.set_thumbnail(url=member.avatar_url) log_file_name = f"{chan.name}_{chan.id}_{datetime.utcnow().strftime('%Y_%m_%d_%H_%M_%S')}" with open(os.path.join("prune_logs", log_file_name), "w") as f: for message in messages: f.write(f"{message.created_at.strftime('%Y/%m/%d %H:%M:%S')} | {message.author} ({message.author.id}): {message.content}\n") channel = self.bot.get_channel_by_name(chan.guild, "audit") await channel.send(embed=embed) await channel.send(file=discord.File(f"prune_logs/{log_file_name}"))
async def on_message(self, message) -> None: if message.author.bot: return author = message.author db = GuildDatabase(message.guild) db_global = GlobalDatabase(self.bot.guilds) if len(message.content) > random.randint(4, 10): should_give_exp = True elif len(message.content) == 0: if len(message.attachments) > 0: should_give_exp = True else: should_give_exp = False if should_give_exp: new_server_xp = db.get_member_data(author)["EXP"] + random.uniform( 2, 4) db.update_member_data(author, "exp", new_server_xp) author_lvl = db_global.get_member_data(author)["LEVEL"] new_global_exp = db_global.get_member_data(author)["EXP"] + ( random.uniform(2, 4) / (author_lvl / 2)) db_global.update_member_data(author, "exp", new_global_exp) if new_global_exp > 50: db_global.update_member_data(author, "exp", new_global_exp - 50) db_global.update_member_data(author, "level", author_lvl + 1) await message.channel.send(embed=construct_embed( title="Level Up.", description= f"{author.mention} you've leveled up to level {author_lvl + 1}", color=embed_color["DEFAULT"])) del db del db_global
async def on_message_edit(self, before, after): if after.author.bot: return if len(before.content) == 0: return if len(after.embeds) != 0: return embed = construct_embed( title="Message edited.", description = f"Username: {after.author}\nUser ID: {after.author.id}", color = 0xACF00E, timestamp=datetime.utcnow() ) embed.set_thumbnail(url=after.author.avatar_url) embed.add_field(name="Before", value=before.content) embed.add_field(name="After", value=after.content) channel = self.bot.get_channel_by_name(after.guild, "audit") await channel.send(embed=embed)
async def profile_customize(self, ctx, *args) -> None: if len(args) > 1: author = ctx.author if args[1] == "emoji": try: if args[2].lower() == "none": GlobalDatabase(self.bot.guilds).update_member_data( author, "emoji", "'none'") else: GlobalDatabase(self.bot.guilds).update_member_data( author, "emoji", f"'{str(args[2])}'") return await ctx.send("Profile Emoji updated.") except IndexError: return await ctx.send( "Provide an Emoji. Example: :desktop:") elif args[1] == "color": try: if "0x" in args[2]: GlobalDatabase(self.bot.guilds).update_member_data( author, "color", f"'{str(args[2])}'") else: GlobalDatabase(self.bot.guilds).update_member_data( author, "color", f"'{str(args[2]).upper()}'") return await ctx.send("Profile embed Color updated.") except IndexError: colors = [ "red", "dark_red", "cherry", "orange", "tangerine", "yellow", "acid", "lime", "green", "dark_green", "cyan", "light_blue", "blue", "ink", "dark_blue", "purple", "dark_purple", "magenta", "pink", "light_pink" ] return await ctx.send( f">>> Available Colors: {' '.join(f'`{color}`' for color in colors)}" ) elif args[1] == "description": try: GlobalDatabase(self.bot.guilds).update_member_data( author, "description", f"'{str(args[2])}'") return await ctx.send("Profile Description updated.") except IndexError: return await ctx.send("Provide a Description.") else: return await ctx.send("Unknown action..") else: embed = construct_embed(title="Profile Customization", color=embed_color["DEFAULT"]) embed.set_thumbnail(url="https://files.catbox.moe/dmtt29.gif") embed.add_field( name="emoji", value= "Adds an emoji next to your name.\nSet to \"none\" to have no emoji.\nCustom emojis are not supported.", inline=False) embed.add_field( name="color", value= "Changes the Color of the embed.\nSet to \"default\" to remove embed color.\nCustom HTML Colors are supported (example: 0xff0055).", inline=False) embed.add_field( name="description", value= "Adds a custom description to your profile.\nSet to \"none\" to have no description on your profile.\nNOTE: wrap your description in qoutes (\"Cool description\").", inline=False) await ctx.send(embed=embed)
async def help(self, ctx, show_mod: str = None) -> None: if show_mod == "mod": show_mod = True elif show_mod == None: show_mod = False else: return await ctx.send( random.choice([ "Help what..?", "I can't understand that, sorry.", "I am unable to help you with that.", "Invalid request.", "Unknown request." ]) ) embed = construct_embed(color=embed_color["DEFAULT"]) if show_mod: embed.title = "Moderator Commands" embed.description = """These commands require certain permissions. *Should be obvious what sort of permission is required to execute a certain command*""" else: embed.title = "Commands" embed.description = f"""Use `{ctx.prefix}help mod` to see moderator commands.""" embed.set_thumbnail(url="https://files.catbox.moe/7bzqc2.gif") def check_mod_cog(cog): if "server" in cog.qualified_name.lower(): return True if "mod" in cog.qualified_name.lower(): return True return False for _, cog in self.bot.cogs.items(): if show_mod: if check_mod_cog(cog) == False: continue else: if check_mod_cog(cog) == True: continue if len(cog.get_commands()) == 0: continue commands = [] for command in cog.walk_commands(): if command.hidden: continue if command.parent != None: continue commands.append(str(command)) if (len(commands)) != 0: embed.add_field( name=cog.qualified_name, value="```\n{}```".format("\n".join(commands)) ) await ctx.send(embed=embed)
async def profile(self, ctx, *args) -> None: if ctx.invoked_subcommand == None: member = None if len(args) == 0: member = ctx.author elif args[0] == "customize": return await self.profile_customize(ctx, *args) else: if len(args) == 1: try: member = await ctx.guild.fetch_member(args[0]) except discord.HTTPException: name = " ".join(arg for arg in args) for m in ctx.guild.members: if m.nick == name or m.name == name: member = m if member == None: return await ctx.send("Couldn't find the specified member.") elif member.bot: return await ctx.send("Robots don't have profiles..") await asyncio.sleep(1) # let the database catch up member_data = GlobalDatabase( self.bot.guilds).get_member_data(member) if member_data["EMOJI"] == "" or member_data["EMOJI"] == "none": title = f"{member.name}" else: title = f"{member_data['EMOJI']} {member.name}" if member_data["DESCRIPTION"] == "" or member_data[ "DESCRIPTION"] == "none": description = "No description set." else: description = member_data["DESCRIPTION"] try: color = embed_color[member_data["COLOR"]] except KeyError: color = int(f"{member_data['COLOR']}", base=16) embed = construct_embed(title=title, description=description, color=color) embed.set_thumbnail(url=member.avatar_url) embed.set_footer( text= f"Use [{ctx.prefix}profile customize] to check out customization options." ) embed.add_field( name="Level", value= f'{member_data["LEVEL"]} ({(member_data["EXP"] + ((member_data["LEVEL"] - 1) * 50)):.2f} Exp.)', ) embed.add_field( name="Reputation", value=member_data["REPUTATION"], ) embed.add_field( name="Account Created at", value=member.created_at.strftime("%d %B %Y, %H:%M"), inline=False) embed.add_field(name="Joined the Server at", value=member.joined_at.strftime("%d %B %Y, %H:%M")) embed.add_field(name="Server Roles", value=", ".join(f'<@&{role.id}>' for role in member.roles), inline=False) await ctx.send(embed=embed)
async def esay(self, ctx, title, msg) -> None: await ctx.send( embed=construct_embed(title=title, description=msg, color=0x2F3136) )