async def grp2_list(self, ctx): """[Administrator] List all available name colours.""" nc_roles = [ role for role in ctx.guild.roles if role.id in self.cogset['namecolors'] ] nc_roles.reverse() desc = "\n".join((f"> {role.name}" for role in nc_roles)) desc += f"\nTotal number of self available colours: {len(nc_roles)}." e = discord.Embed(title="List of Available Name Colours", description=desc, colour=RANDOM_DISCORD_COLOR(), type="rich", timestamp=datetime.datetime.utcnow()) e.set_footer(icon_url=GUILD_URL_AS(ctx.guild), text=ctx.guild.name) await self.bot.send_msg(dest=ctx.channel, embed=e) return
async def cmd_leaderboard(self, ctx): printout = "" for i, result in enumerate(await self.db.fetch(pgCmds.GET_MEMBER_LEADERBOARD)): printout += f"{(i+1)}:\t<@{result['user_id']}>\tLvl: {result['level']}\n" embed = discord.Embed( description=printout, colour= RANDOM_DISCORD_COLOR(), type= 'rich', timestamp = datetime.datetime.utcnow() ) embed.set_author( name= "FurSail Leaderboard", icon_url= ctx.guild.icon_url ) embed.set_footer( text= ctx.guild.name, icon_url= ctx.guild.icon_url ) await ctx.send(embed=embed) return
async def gen_self_roles_msg(self, guild): key = dict() rkey = dict() desc = 'Add a reaction to **toggle** your self assignable roles!\n\n' self_roles = [ role for role in guild.roles if role.id in self.cogset['selfroles'] ] self_roles.reverse() # ===== BUILD THE EMBED DESCRIPTION for i, role in enumerate(self_roles): desc = f'{desc}{self.emojiname[i]} - for {role.name}\n' key[self.emojistring[i]] = role.id rkey[role.id] = self.emojistring[i] # ===== BUILD THE EMBED e = discord.Embed(title="Give Yourself Some Roles", description=desc, colour=RANDOM_DISCORD_COLOR(), type="rich", timestamp=datetime.datetime.utcnow()) e.set_footer(icon_url=GUILD_URL_AS(guild), text=guild.name) return (e, key, rkey, self_roles)
async def cmd_hoststats(self, ctx): """ [Bot Owner] Returns current system utilzation of the bots host. """ valid = await self.oneline_valid(ctx.message.content) if not valid: return def MBorGB(val): ret = val / 1073741824 if ret < 1: ret = "{0:.2f} MB".format((val / 1048576)) return ret ret = "{0:.2f} GB".format(ret) return ret # ===== CPU INFORMATION cpu_freq = psutil.cpu_freq() # ===== PHYSICAL RAM mem = psutil.virtual_memory() # ===== DISK DRIVE SPACE d = psutil.disk_usage(pathlib.Path.cwd().__str__()) # ===== UPTIME updelta = datetime.datetime.utcnow() - self.bot.start_timestamp seconds = updelta.seconds hours = int(seconds / 3600) if hours > 1: seconds = hours * 3600 minutes = int(seconds / 60) if minutes > 1: seconds = minutes * 60 embed = discord.Embed(title="Host System Stats", description="", colour=RANDOM_DISCORD_COLOR(), timestamp=datetime.datetime.utcnow(), type="rich") embed.add_field( name="CPU:", value= f"> **Cores:** {psutil.cpu_count(logical=False)} ({psutil.cpu_count(logical=True)})\n" f"> **Architecture:** {platform.machine()}\n" f"> **Affinity:** {len(psutil.Process().cpu_affinity())}\n" f"> **Useage:** {psutil.cpu_percent()}%\n" f"> **Freq:** {cpu_freq[0]} Mhz", inline=True) embed.add_field(name="Memory:", value=f"> **Total:** {MBorGB(mem[0])}\n" f"> **Free:** {MBorGB(mem[1])}\n" f"> **Used:** {mem[2]}%", inline=True) embed.add_field(name="Storage:", value=f"> **Total:** {MBorGB(d[0])}\n" f"> **Free:** {MBorGB(d[2])}\n" f"> **Used:** {d[3]}%", inline=True) embed.add_field( name="Network:", value="> **Useage:**\n" f"> - Send: {MBorGB(psutil.net_io_counters().bytes_sent)}" f"> - Recv: {MBorGB(psutil.net_io_counters().bytes_recv)}", inline=True) embed.add_field(name="Python:", value=f"> **Version:** {platform.python_version()}\n" f"> **Discord.py** {discord.__version__}\n" f"> **Bits:** {platform.architecture()[0]}", inline=True) embed.add_field( name="Bot Uptime:", value= f"> **Launched:** {self.bot.start_timestamp.strftime('%b %d, %Y')}\n" f"> **Time:** days:{updelta.days}, hours:{hours}, minutes:{minutes}, seconds:{seconds}\n", inline=True) embed.add_field( name="Process", value=f"> **Memory:** {MBorGB(psutil.Process().memory_info().rss)}\n" f"> **CPU:** {psutil.Process().cpu_percent(interval=2)}%\n" f"> **Threads:**{psutil.Process().num_threads()}", inline=True) embed.set_author( name=f"{self.bot.user.name}#{self.bot.user.discriminator}", icon_url=AVATAR_URL_AS(self.bot.user)) embed.set_thumbnail( url=AVATAR_URL_AS(user=self.bot.user, format=None, size=512)) await ctx.channel.send(embed=embed) return
async def cmd_userperms(self, ctx): """ [All Staff] Gets all the perms for a role both default and channel overwrite. Obviously, member needs to be part of the guild for this to work. Useage: [prefix]UserPerms <userID/userMention> """ try: user_id = ctx.message.content.split(" ")[1] member = ctx.guild.get_member_named(user_id) ###=== remove the user mention if user_id.isdigit() or user_id.startswith("<@"): user_id = user_id.replace("<", "").replace("@", "").replace( "!", "").replace(">", "") user_id = int(user_id) member = ctx.guild.get_member(user_id) else: raise ValueError #if user == idiot except (IndexError, ValueError): await ctx.send_help('userperms', delete_after=15) #===== If user is owner; end function early if member == ctx.guild.owner: try: embed = await GenEmbed.getUserPermsOwner(member, msg=ctx.message) await ctx.channel.send(embed=embed) return except Exception as e: print(e) return #===== If user has Admin perms; end function early isAdmin = False for role in member.roles: if role.permissions.administrator: isAdmin = True if isAdmin: embed = await GenEmbed.getUserPermsAdmin(member, msg=ctx.message) await ctx.channel.send(embed=embed) return #===== Variable setup server_wide_perms = list() channel_specific_perms = list() embeds = list() #===== server wide for role in member.roles: for i in range(31): if bool((role.permissions.value >> i) & 1): server_wide_perms.append(self.raw_perms[i].replace( "_", " ").title()) #===== one entry for each item server_wide_perms = list(set(server_wide_perms)) #===== channel """ Getting the channel perms for the role sorted. The channels are sorted by position for readability of results. Normally they are sorted by position anyway but sometimes they come back in a mess of an order. """ for channel in sorted(ctx.guild.channels, key=lambda x: x.position): temp = list() cleanedTemp = list() for role in ([member] + member.roles): channelPerms = channel.overwrites_for(role) for i in range(31): if not self.raw_perms[i] == "": #Making sure voice channels are not checked for buggy text channel perms if (channel.type == discord.ChannelType.voice) and ( self.raw_perms[i] in ["read_messages", "send_messages"]): continue #Making sure text channels are not checked for voice channel perms if (channel.type == discord.ChannelType.text) and ( self.raw_perms[i] in [ "speak", "connect", "mute_members", "deafen_members", "move_members", "use_voice_activation", "stream" ]): continue result = channelPerms._values.get(self.raw_perms[i]) if isinstance(role, discord.Member): if result == True: temp.append("**[User]** {}".format( self.raw_perms[i].replace("_", " ").title())) elif result == False: temp.append("**[User]** Not {}".format( self.raw_perms[i].replace("_", " ").title())) else: if result == True: temp.append(self.raw_perms[i].replace( "_", " ").title()) elif result == False: temp.append("Not {}".format( self.raw_perms[i].replace("_", " ").title())) """ Because discord will take a yes over a no when it comes to perms, we remove the Not {perm} is the perm is there as a yes """ for item in temp: if item.startswith("Not"): if not any([i for i in temp if i == item[4:]]): cleanedTemp.append(item) else: cleanedTemp.append(item) #=== If at end of loop no perms where found, log nothing. if len(cleanedTemp) > 0: channel_specific_perms.append( dict(channelName=channel.name, perms=cleanedTemp, channelType=channel.type.__str__())) #===== results, processing them into an actual reply #You can only have 25 fields in a discord embed. So I'm breaking up my list of possible fields into a 2d array. channel_specific_perms = await self.split_list(channel_specific_perms, size=24) firstLoop = True for channelSpecificPerms in channel_specific_perms: #=== Set up the first embed if firstLoop: text = " | ".join(server_wide_perms) if text == "": text = "None" embed = discord.Embed( title="Server Wide:", description="{}\n" "**Hierarchy: {}**".format( text, (len(ctx.guild.roles) - member.top_role.position)), colour=RANDOM_DISCORD_COLOR(), timestamp=datetime.datetime.utcnow(), type="rich") embed.set_author( name="{0.name}#{0.discriminator}".format(member), icon_url=AVATAR_URL_AS(member)) embed.add_field(name="Roles[{}]".format(len(member.roles) - 1), value=(" ".join([ role.mention for role in member.roles if not role.is_everyone ])) if len(member.roles) > 1 else ("Member has no roles.")) #=== Set up additional embeds else: embed = discord.Embed(description="", colour=RANDOM_DISCORD_COLOR(), timestamp=datetime.datetime.utcnow(), type="rich") embed.set_author( name="{0.name}#{0.discriminator} | Information Continued". format(member.name), icon_url=AVATAR_URL_AS(member)) for i in channelSpecificPerms: #= The category channel type does not have a name, instead it's called "4" embed.add_field( name=i["channelName"] + (":" if not i["channelType"] == "4" else " - Category:"), value=" | ".join(i["perms"]), inline=False) #=== since these are always going to be the same embed.set_thumbnail(url=AVATAR_URL_AS(member)) embed.set_footer(icon_url=GUILD_URL_AS(ctx.guild), text=f"{ctx.guild.name} | ID: {member.id}") embeds.append(embed) firstLoop = False #===== send each generated embed as it's own message for embed in embeds: await ctx.channel.send(embed=embed) return
async def on_message_delete(self, msg): if not msg.guild or msg.author.bot or not self.cogset['enableDelMsgLog'] or not msg.type == discord.MessageType.default: return if not self.report_ch: self.report_ch = msg.guild.get_channel(self.cogset['report_ch_id']) if msg.channel.id in self.cogset['lis_channels'] or msg.author.id in self.cogset['lis_members']: msg_attach = list() reason = "" embed = discord.Embed( title= "Message Deleted.", description= "**Author:** <@{}>\n" "**Sent:** {}\n" "**Channel:** <#{}>".format( msg.author.id, msg.created_at, msg.channel.id ), colour= RANDOM_DISCORD_COLOR(), timestamp= datetime.datetime.utcnow(), type= "rich" ) embed.add_field ( name= "**Content**", value= escape(msg.content, mass_mentions=True, formatting=True), inline= False ) embed.set_author( name= f"{msg.author.name}#{msg.author.discriminator}", icon_url= AVATAR_URL_AS(msg.author), url= AVATAR_URL_AS(msg.author) ) embed.set_footer( icon_url= GUILD_URL_AS(msg.guild), text= msg.guild.name ) if self.cogset['save_attach'] and msg.attachments: for attach in msg.attachments: try: fb = await attach.read(use_cached=True) filename = attach.filename msg_attach.append(discord.File(BytesIO(fb), filename=filename, spoiler=False)) except discord.errors.Forbidden: msg_attach = None reason = 'I do not have permissions to access this attachment.' break except discord.errors.NotFound: msg_attach = None reason = 'The attachment was deleted.' break except discord.errors.HTTPException: msg_attach = None reason = 'Downloading the attachment failed.' break if msg_attach is None: embed.add_field ( name= "**Attachments Failed**", value= f"**Reason:** {reason}", inline= False ) await self.report_ch.send(embed=embed, files=msg_attach) return
async def nuggethelp(self, ctx): """ [Core] Prints a help message for the users Useage: [prefix]NuggetHelp/Help """ embed = discord.Embed( title="Self Assignable Roles:", description="**SFW Roles:**\n" f"{ctx.prefix}NotifyMe:\tA role that we use to ping people about goings on.\n" f"{ctx.prefix}Book_Wyrm:\tUsed to access <#304365533619421184> text and voice channels.\n" f"{ctx.prefix}RP:\tUsed to access the SFW RP channels.\n" f"{ctx.prefix}Artist:\tArtists who are open to commissions. Plus gain write permissions in <#382167213521633280>\n" "\n" "**NSFW Roles (NSFW Role required):**\n" f"{ctx.prefix}RP_Lewd:\tUsed to access the NSFW RP channels.\n" "\n", type="rich", timestamp=datetime.datetime.utcnow(), colour=RANDOM_DISCORD_COLOR()) embed.set_author(name="Nugget Help", icon_url=AVATAR_URL_AS(self.bot.user)) embed.add_field( name="NSFW Access", value= f"To get access to the NSFW channels just ping staff in <#{self.bot.config.channels['reception_id']}> with your age.", inline=False) embed.add_field( name="Private Feedback:", value= f"You can always DM me {self.bot.user.mention} with {self.bot.command_prefix}feedback followed by your feedback for the staff.\nFeedback can be submitted anonymously this way.", inline=False) embed.add_field( name="Fun Commands:", value= f"{ctx.prefix}RPS <rock/paper/scissors>:\tPlay rock paper scissors with me.\n" f"{ctx.prefix}8ball <question>:\tAsk your question and I shall consult the ball of knowledge.\n" f"{ctx.prefix}Roll <number>:\tRole a dice, you tell me how high I can go.\n" f"{ctx.prefix}Leaderboard:\tTop 10 most popular, I hope I'm on that list.\n", inline=False) #embed.add_field( # name= "Art and Commissions:", # value= # f"{ctx.prefix}Commissioner:\tAdds commissioner role, meant for people looking for commissions.\n" # f"{ctx.prefix}FindArtists:\tDMs you info about any artist who have registered with us.\n" # f"{ctx.prefix}OpenCommissions:\tAdds OpenCommissions role to artists, to show you have slots open.\n" # f"{ctx.prefix}ArtistRegister <info>: For artists registering their info with us.\n" # f"{ctx.prefix}PingCommissioners: Artists can ping people with the Commissioner role.\n" # "[Note: expect more info on this subject soon]", # inline= False # ) #embed.add_field( # name= "Need a break?:", # value= "If you want to hide the server from yourself for a while; " # f"you can post {ctx.prefix}HideServer <xDxHxMxS/seconds> and " # "I'll try hide the server from you for a bit. You can re-show the server anytime. \n" # "If you're stressed, don't worry: https://www.youtube.com/watch?v=L3HQMbQAWRc,", # inline= False # ) embed.set_footer(text=ctx.guild.name, icon_url=GUILD_URL_AS(ctx.guild)) await ctx.channel.send(embed=embed, delete_after=90) return
async def cmd_logstaff(self, ctx, *, staff_id: Union[int, str], maker_id=0, received_role=0, removed_role=0, reason="None"): """ [Admin] Log history of staff change. Args: staff_id : ID of the member who has been added/removed from staff maker_id : ID of the existing staff who added/removed staff_id from staff. If not provided, it is assumed the owner edited the roles of ex/staff. received_role : Role ID of the staff role which has been applied to the new guy, this is 0 if role was removed. removed_role : Role ID of the staff tole which has been removed from the ex-staff, this is 0 if the role was added. reason : Reason for this changed, limited to 1000 chatactors. """ # ===== MAKE SURE A ROLE IS EITHER ADDED OR REMOVED. if received_role == 0 and removed_role == 0: await ctx.send("`A role needs to be added or removed.`") await ctx.send_help('logstaff') return # ===== ASSUME THE COMMAND INVOKER EDITED THE EX/STAFF if maker_id == 0: maker_id = ctx.author.id # ===== MAKE SURE ALL VARIABLES WHICH SHOULD BE INTS, ARE INT. try: maker_id = GuildDB.StripMention(maker_id) staff_id = GuildDB.StripMention(staff_id) maker_id = int(maker_id) received_role = int(received_role) removed_role = int(received_role) # ===== IF A VARIABLE IS NOT AN INT, THEN CALL THE USER A MORON. except ValueError: await ctx.send("`All id's provided **must** be a number.`") await ctx.send_help('logstaff') return # ===== COMMIT DATA TO DATABASE staff_data = staff_id, maker_id, received_role, removed_role, reason[: 1000] await self.db.execute(pgCmds.APPEND_GUILD_STAFF, staff_data, ctx.guild.id) # ===== GIVE A RETURN SO THE INVOKER DOESN'T THINK THAT NOTHING HAPPENED. embed = discord.Embed(description=f"Ex/Staff: <@{staff_id}>" f"Maker: <@{maker_id}>" f"Received Role: <@{received_role}>" f"Removed Role: <@{removed_role}>" f"Reason: {reason}", colour=RANDOM_DISCORD_COLOR(), type="rich", timestamp=datetime.datetime.utcnow()) await ctx.channel.send(embed=embed) return