async def on_command_error(ctx: commands.Context, error: Exception): """ A function that will be called when bot encounters a error. This function may be removed after testing phase. Args: ctx (commands.Context): passing in the error context error(Exception): the error Returns: None Raises: commands.errors: when error that isn't caught """ # Send appropriate error message on command error # Code Reference: From Commando950#0251 (119533809338155010) > https://gitlab.com/Commando950 try: show_error = bot.get_cog("Admin").debug except AttributeError: return if isinstance(error, commands.CommandNotFound): return elif isinstance(error, commands.NotOwner): return elif isinstance(error, commands.MissingRequiredArgument): return elif isinstance(error, commands.BadArgument): return elif isinstance(error, commands.MissingPermissions): if CustomTools.ignore_check(bot, ctx.channel, from_main=True): await ctx.send(str(error)) return try: await ctx.message.add_reaction(emoji="⚠") except discord.HTTPException: pass if show_error: try: dest = bot.get_cog("Message") except ValueError: return try: raise error except Exception: await bot.appinfo.owner.send("Error has occurred on this message") await dest.encode_message(ctx.message, bot.appinfo.owner) report = f"{traceback.format_exc()}" mes = CustomTools.split_string(report, 1900) for i in range(len(mes)): await bot.appinfo.owner.send( f"discord error page **{i + 1}**:\n```python\n{mes[i]}\n```" ) raise error
async def list(self, ctx: commands.Context, name: str = None): """ Sub-command of word_trigger that list either the word trigger for the server or words within a specified word trigger. Args: ctx(commands.Context): pass in context for reply name(str): name of the word trigger if any. Returns: None """ if not name: try: data = self.memory[ctx.guild.id] except KeyError: await ctx.send("There is no word trigger set for this server") else: temp = [] mes = "" for i in data: if i.label not in data: temp.append(i.label) a = "Delete Word List" if i.delete else "Trigger Word List" if i.active: mes += f"✅ **{i.label}** - {a}\n" else: mes += f"❌ **{i.label}** - {a}\n" await ctx.send(embed=discord.Embed( title="Server Word Lists", description=mes, colour=0x81ecec )) else: data = self.findin(ctx.guild.id, name) if not data: await ctx.send(f"word list `{name}` don't exist") return if len(data.words) <= 0: await ctx.send(f"word list `{name}` is empty") return temp = "" data.words.sort() for i in data.words: temp += f"**-** {i} \n" embed = discord.Embed( title=f"Words in **{name}**", timestamp=ctx.message.created_at, colour=0xffdd59 ) ret = CustomTools.split_string(temp, 1000) for i in range(len(ret)): embed.add_field(name=f"Word list Page{i+1}", value=ret[i]) await ctx.send(embed=embed)
async def tell(self, ctx: commands.Context, target: discord.Member, reason: str, duration: str, inc: bool = False): """ Async method for Mute class that DMs the target regarding their mute. Args: ctx(commands.Context): pass in context for analysis target(discord.Member): pass in member to DM reason(str): reasoning duration(str): mute duration or increment in string form inc(bool): whether or not mute time is increased and not new mute Returns: None """ if target.bot: return if len(reason) <= 0: return if ctx.author.id == target.id: return data = CustomTools.add_warn(self.bot, ctx.message.created_at, ctx.guild.id, target.id, None, 2, reason, duration) try: await target.send( "🔇 You have been muted 🔇" if not inc else "➕ Mute Time Increased", embed=discord.Embed( timestamp=ctx.message.created_at, description=f"[{duration}] - **{reason}**", colour=0x636e72).set_footer( icon_url=target.avatar_url_as(size=64), text=f"{data} offenses").set_author( icon_url=ctx.guild.icon_url_as(size=128), name=f"{ctx.guild.name}")) except discord.HTTPException: pass
async def word_trigger(self, ctx: commands.Context): """ Command for WordTrigger class, and group of word_trigger commands. This command will send back the correct usage of sub-commands when wrong sub-command or none are given. Args: ctx(commands.Context): pass in context for reply Returns: None """ if not ctx.invoked_subcommand: pre = CustomTools.prefix(self, ctx) embed = discord.Embed( title="`Word Trigger` Commands", colour=0xff6b6b ) embed.add_field(inline=False, name=f"{pre}ignore <user mention or ID>", value="Adds the mentioned user into the word trigger ignore list and ask whether or not to " "remove the user if they are already in the list.") embed.add_field(inline=False, name=f"{pre}il", value="List members in the word trigger's ignore list.") embed.add_field(inline=False, name=f"{pre}wt c <name> (True/False to auto delete message)", value="Create a new word trigger menu with given info. Auto delete is default to false.") embed.add_field(inline=False, name=f"{pre}wt s <word trigger name>", value="Open up the setting menu with option to turn on or off the mentioned word trigger, " "delete word trigger, or toggle auto delete.") embed.add_field(inline=False, name=f"{pre}wt + <word trigger name> <word>", value="Add the word into that specified word trigger.") embed.add_field(inline=False, name=f"{pre}wt - <word trigger name> <existing word>", value="Remove the word from the specified word trigger.") embed.add_field(inline=False, name=f"{pre}wt ++ <'words to add'>...", value="Add multiple words into the specified word trigger separated by space.") embed.add_field(inline=False, name=f"{pre}wt -- <'words to remove'>...", value="Remove multiple words into the specified word trigger separated by space.") embed.add_field(inline=False, name=f"{pre}wt list (word trigger name)", value="List all the word triggers in the server no name mentioned, else will list word " "list of that word trigger.") embed.add_field(inline=False, name=f"{pre}wt = <word trigger name> <word>", value="See if the mentioned word is in the mentioned word trigger.") embed.add_field(inline=False, name=f"{pre} wt data <use mention or ID>", value="Display word trigger data of the mentioned user in the server") await ctx.send(embed=embed)
async def warn(self, ctx: commands.Context, target: discord.Member, *, reason: str): """ Part of the Moderation command that warns the targeted member with the specified reason and append it to database. Args: ctx(commands.Context): pass in context for reply target(discord.Member): member to warn reason(str): warn reasoning Returns: None """ if target.bot: await ctx.send("Warn a bot? Why?") return if len(reason) <= 0: await ctx.send("Please specify a reason.") return if ctx.author.id == target.id: await ctx.send("LOL, why?") return data = CustomTools.add_warn(self.bot, ctx.message.created_at, ctx.guild.id, target.id, ctx.author.id, 0, reason) try: await target.send("⚠ You received a warning ⚠", embed=discord.Embed( timestamp=ctx.message.created_at, description=reason, colour=0xd63031).set_footer( icon_url=target.avatar_url, text=f"{data} offenses").set_author( icon_url=ctx.guild.icon_url, name=f"{ctx.guild.name}")) await ctx.message.add_reaction(emoji='👍') except discord.HTTPException: await ctx.send( "Warning stored in system, however, can not warn the target via DM." )
async def list(self, ctx: commands.Context): """ Sub-command of log_channels that list number of log channels within the server. Args: ctx(commands.Context): pass in context for analysis and reply Returns: None """ try: data = self.memory[ctx.guild.id] except KeyError: await ctx.send("This server don't have any log channel.") return message = "=========================\nList of log channels:\n-------------------------\n" for i in data: channel = ctx.guild.get_channel(i.channel) message += f"> {channel.mention}\n" if channel else f"> {i.channel} 🗑️\n" message += "=========================" new = CustomTools.split_string(message, 2000) for i in new: await ctx.send(i)
import itertools import CustomTools as f import random a = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] a = f.TileSpawnInit(a) a = f.TileSpawnInit(a) f.GridPrint(a) while 1 == 1: axis = int(input("1 for up, 2 for down, 3 for left, 4 for right")) if axis < 3: a = f.transpose(a) b = f.CustomSort(a, axis) a = list(itertools.chain.from_iterable(b)) b = f.MergeLogic(a) a = list(itertools.chain.from_iterable(b)) b = f.CustomSort(a, axis) a = list(itertools.chain.from_iterable(b)) a = f.TileSpawn( a ) #easily the worst part of the code but haven't found a way to streamline if axis < 3: a = f.transpose(a) f.GridPrint(a) score = f.score(a) print("score =", score)
async def on_member_update(self, before: discord.Member, after: discord.Member): """ Event listener for ScanName class that detects member nickname update and scans it to take appropriate action. Args: before(discord.Member): member before update after(discord.Member): member after update Returns: None """ if before.nick != after.nick: self_change = False async for entry in after.guild.audit_logs( limit=1, action=discord.AuditLogAction.member_update): if entry.user.id == entry.target.id and after.id == entry.target.id: self_change = True if not self_change: return else: try: temp = self.bot.get_cog("Notification") data = temp.memory[after.guild.id] except KeyError: return except AssertionError: return bad_nick = self.scan_name(after.guild.id, after.nick, after.id) if bad_nick: await after.edit(nick=self.nicking[after.guild.id].change, reason="Bad Username") current = datetime.datetime.utcnow() reason = ", ".join(bad_nick) data2 = CustomTools.add_warn( self.bot, current, after.guild.id, after.id, None, 1, f"Nickname contains banned words: {reason} in " f"{self.bot.get_guild(after.guild.id).name}") try: await after.send( "⚠ You received an auto warn ⚠", embed=discord.Embed( timestamp=current, description= f"Having **{reason}** in your nickname isn't allowed here.", colour=0xf1c40f).set_footer( icon_url=after.avatar_url_as(size=64), text=f"{data2} offenses").set_author( icon_url=after.guild.icon_url, name=f"{after.guild.name}")) except discord.HTTPException: pass for i in data: if i.data['member_update'] and not bad_nick: channel = self.bot.get_channel(i.channel) if not channel: self.bot.mongodb["system_message"].delete_many( {"guild_id": i.guild}) return embed = discord.Embed( timestamp=datetime.datetime.utcnow(), colour=0x9980FA, description=after.mention) embed.set_author(name="✍ Nickname change!", icon_url=after.avatar_url) if before.nick: embed.add_field(name="Before", value=before.nick, inline=False) if after.nick: embed.add_field(name="Now", value=after.nick, inline=False) await channel.send(embed=embed) if bad_nick: if i.data['trigger']: channel = self.bot.get_channel(i.channel) if not channel: self.bot.mongodb["system_message"].delete_many( { "guild_id": i.guild, "channel_id": i.channel }) await temp.local_update(i.guild) else: embed = discord.Embed( colour=0xF79F1F, timestamp=datetime.datetime.utcnow(), description=after.mention) embed.set_author(icon_url=after.avatar_url, name="🚨 Bad Nickname!") embed.add_field(name="Triggered Words", value=", ".join(bad_nick)) await channel.send(embed=embed)
async def on_user_update(self, before: discord.User, after: discord.User): """ Event listener for ScanName class that detects username update and scans it for banned words and take appropriate active. Args: before(discord.User): user before the update after(discord.User): user after the update Returns: None """ if (before.name != after.name) or (before.discriminator != after.discriminator): try: cog = self.bot.get_cog("Notification") except AssertionError: cog = None is_in = [] for i in self.bot.guilds: if i.get_member(after.id): is_in.append(i) for i in is_in: bad_name = self.scan_name(i.id, after.name, after.id) if not cog: data = None else: try: data = cog.memory[i.id] except KeyError: data = None if not bad_name: if data: for a in data: if a.data['member_update']: channel = self.bot.get_channel(a.channel) if not channel: self.db.delete_many({ "guild_id": i.guild, "channel_id": i.channel }) await cog.local_update(i.guild) else: embed = discord.Embed( colour=0x45aaf2, timestamp=datetime.datetime.utcnow(), description=after.mention) embed.set_author(name="✍ Username change!", icon_url=after.avatar_url) embed.add_field(name="Before", value=before.display_name, inline=False) embed.add_field(name="Now", value=after.display_name, inline=False) await channel.send(embed=embed) else: member = i.get_member(after.id) await member.edit(nick=self.nicking[i.id].change, reason="Bad Username") current = datetime.datetime.utcnow() reason = ", ".join(bad_name) CustomTools.add_warn( self.bot, current, i.id, member.id, None, 1, f"Username contains banned words: {reason}") if data: for a in data: if a.data['trigger']: channel = self.bot.get_channel(a.channel) if not channel: self.bot.mongodb[ "system_message"].delete_many({ "guild_id": i.guild, "channel_id": i.channel }) await cog.local_update(i.guild) else: embed = discord.Embed( colour=0xF79F1F, timestamp=datetime.datetime.utcnow(), description=after.mention) embed.set_author(icon_url=after.avatar_url, name="🚨 Bad Username!") embed.add_field(name="Triggered Words", value=reason) await channel.send(embed=embed)
def __init__(self): import platform self._toolList = {} for category in ToolCategory: self._toolList[category.value] = [] toolsFile = './tools.json' if platform.system() == 'Windows': toolsFile = './tools_win.json' data = None with open(toolsFile, encoding="utf8") as f: data = json.load(f) for obj in data: try: if str(obj['category']).isdigit(): num = int(obj['category']) self.addTool( Tool(obj['name'], obj['category'], obj['desc'], obj['example'], obj['cmd'], obj['customInput'], obj['parser']), num) else: logging.exception('Could not load tool:\n' + obj) except Exception as e: logging.exception(type(e)) # Add custom tools import CustomTools import NmapScripts self.addTool(NmapScripts.NmapLoudTcp(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapLoudUdp(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapStandardTcp(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapStandardUdp(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapSneaky(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapPing(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapVersion(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapQuick(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapStealth(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapAcars(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapAfp(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapAjp(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapAllseeingeye(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapAmqp(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapIdentd(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapBackorifice(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapBACNet(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapBitcoin(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapBittorrent(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapBjnp(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapDiscoverScripts(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapEigrp(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapCassandra(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapCccam(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapCics(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapCitrixWeb(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapCitrixIca(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapClam(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapCoap(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapCouchDb(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapCredSummary(), ToolCategory.Reporting) self.addTool(NmapScripts.NmapCups(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapCvs(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapDb2(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapDelugeRpc(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapDhcp(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapDistccd(), ToolCategory.Exploit) self.addTool(NmapScripts.NmapDnsEnum(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapDnsVul(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapDocker(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapDominoUsers(), ToolCategory.Exploit) self.addTool(NmapScripts.NmapDominoConsole(), ToolCategory.Exploit) self.addTool(NmapScripts.NmapIphoto(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapDrda(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapMultihomed(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapEnip(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapFinger(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapFirewalk(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapFirewall(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapFume(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapFox(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapFreelancer(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapFtp(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapHddTemp(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapHnap(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapHttpAnalytics(), ToolCategory.Forensics) self.addTool(NmapScripts.NmapHttpEnum(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapHttpExploit(), ToolCategory.Exploit) self.addTool(NmapScripts.NmapHttpVul(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapImapEnum(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapImapBrute(), ToolCategory.Password) self.addTool(NmapScripts.NmapVlcStreamer(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapVmware(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapMsSqlBrute(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapMySqlEnum(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapMySqlBrute(), ToolCategory.Password) self.addTool(NmapScripts.NmapSmbEnum(), ToolCategory.Enumeration) self.addTool(NmapScripts.NmapSmbVuln(), ToolCategory.VulnerabilityScanner) self.addTool(NmapScripts.NmapSmbBrute(), ToolCategory.Password) self.addTool(NmapScripts.NmapSnmpBrute(), ToolCategory.Password) self.addTool(CustomTools.SmtpUserVerify(), ToolCategory.Enumeration) if platform.system() == 'Windows': self.addTool(CustomTools.DownloadFileWindows(), ToolCategory.Maintaining) else: self.addTool(CustomTools.CustomWordlist(), ToolCategory.Password) self.addTool(CustomTools.HydraCustom(), ToolCategory.Password) self.addTool(CustomTools.BruteSopMultiServer(), ToolCategory.Password) self.addTool(CustomTools.CiscoGlobalExploiter(), ToolCategory.VulnerabilityScanner) self.addTool(CustomTools.OpenVAS(), ToolCategory.VulnerabilityScanner) self.addTool(CustomTools.SearchsploitNmap(), ToolCategory.Exploit) self.addTool(CustomTools.SearchsploitTargetHost(), ToolCategory.Exploit) self.addTool(CustomTools.SearchsploitCustomSearch(), ToolCategory.Exploit) self.addTool(CustomTools.DownloadFileLinux(), ToolCategory.Maintaining) self.addTool(CustomTools.SQLMapCustom(), ToolCategory.Web) return
import itertools import CustomTools as f import random GameBoard_Primary = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] GameBoard_Primary = f.TileSpawnInit(GameBoard_Primary) GameBoard_Primary = f.TileSpawnInit(GameBoard_Primary) f.GridPrint(GameBoard_Primary) while 1 == 1: axis = int(input("1 for up, 2 for down, 3 for left, 4 for right")) if axis < 3: GameBoard_Primary = f.transpose(GameBoard_Primary) GameBoard_Secondary = f.CustomSort(GameBoard_Primary, axis) GameBoard_Primary = list( itertools.chain.from_iterable(GameBoard_Secondary)) GameBoard_Secondary = f.MergeLogic(GameBoard_Primary) GameBoard_Primary = list( itertools.chain.from_iterable(GameBoard_Secondary)) GameBoard_Secondary = f.CustomSort(GameBoard_Primary, axis) GameBoard_Primary = list( itertools.chain.from_iterable(GameBoard_Secondary)) GameBoard_Primary = f.TileSpawn( GameBoard_Primary ) #easily the worst part of the code but haven't found a way to streamline if axis < 3: GameBoard_Primary = f.transpose(GameBoard_Primary) f.GridPrint(GameBoard_Primary) f.score(GameBoard_Primary)
async def on_message_edit(self, before: discord.Message, message: discord.Message): """ Event listener for word trigger that scans for the edited message for word trigger process. Args: before(discord.Message): the old message message(discord.Message): the new edited message Returns: None """ if message.author.bot: return if message.channel.type != discord.ChannelType.text: return if message.content == "": return if self.find_ignore(message.guild.id, message.author.id): return try: location = self.bot.get_cog('Notification').memory[message.guild.id] except KeyError: return if not location: return try: data = self.memory[message.guild.id] except KeyError: return delete, word_type, problem = self.scanner(message, data) if len(word_type) <= 0: return if delete: await message.delete() embed = discord.Embed( colour=0xEA2027, timestamp=message.created_at, title=f"Message from **{message.author}** in **{message.channel}**" ) embed.add_field(inline=False, name="Message Before", value=before.content) embed.add_field(inline=False, name="Message After Edit:", value=message.content) jump = await message.channel.send(f"Watch your language {message.author.mention}, even editing.") embed.set_author(icon_url=message.guild.icon_url_as(size=128), name="Automatic message deletion") jump = jump.jump_url reason = ", ".join(problem) data2 = CustomTools.add_warn(self.bot, message.created_at, message.guild.id, message.author.id, self.bot.user.id, 1, f"Used banned words in edited message: {reason}") try: await message.author.send("⚠ You received an auto warn ⚠", embed=discord.Embed( timestamp=message.created_at, description=f"Use of **{reason}** are banned, even in edited message. Go wash your hands.", colour=0xf1c40f ).set_footer(icon_url=message.author.avatar_url_as(size=64), text=f"{data2} offenses") .set_author(icon_url=message.guild.icon_url_as(size=128), name=f"{message.guild.name}")) except discord.HTTPException: pass else: embed = discord.Embed( colour=0xf1c40f, timestamp=message.created_at, title=f"Message edited by **{message.author}** in **#{message.channel}**" ) embed.add_field(inline=False, name="Message Before:", value=before.content) embed.add_field(inline=False, name="Message Edited to:", value=message.content) embed.set_author(icon_url=message.guild.icon_url_as(size=128), name="Word Trigger") jump = message.jump_url embed.add_field(name="Message Location", value=f"[Jump]({jump})") embed.add_field(name="Time", value=message.created_at.strftime("%#d %B %Y, %I:%M %p UTC")) embed.add_field(inline=False, name="Categories", value=f"{word_type}") embed.add_field(inline=False, name="Problematic words", value=f"{problem}") embed.set_footer(icon_url=message.author.avatar_url_as(size=64), text=f"User ID: {message.author.id}") embed.add_field(name="Mention", value=message.author.mention) for i in location: if i.data['trigger']: await message.guild.get_channel(i.channel).send(embed=embed)
async def show(self, ctx: commands.Context, target: typing.Union[discord.Member, discord.User, int]): """ Command of Moderation class and sub-command of warn_menu. This will list the amount of warnings the user have received in the guild. Args: ctx(commands.Context): pass in context for analysis and reply target(typing.Union[discord.Member, discord.User, int]): the user to fetch warnings for Returns: None """ if isinstance(target, int): target = target else: target = target.id data = self.warn_db.find_one({ "guild_id": ctx.guild.id, "user_id": target }) user = ctx.guild.get_member(target) if not data: await ctx.send(f"**{user}** have a clean record") else: embed = discord.Embed(colour=user.colour, timestamp=ctx.message.created_at).set_author( icon_url=user.avatar_url, name=f"{user} Warn List") line1 = "" line2 = "" line3 = "" for i in range(len(data["warn_id"])): if data["kind"][i] == 0: line1 += f"**{data['warn_id'][i]}**. [`{data['time'][i]}`] |<@!{data['warner'][i]}>| - " \ f"{data['reason'][i]}\n" if data["kind"][i] == 1: line2 += f"**{data['warn_id'][i]}**. [`{data['time'][i]}`] - {data['reason'][i]}\n" if data["kind"][i] == 2: line3 += f"**{data['warn_id'][i]}**. [`{data['time'][i]}`] ({data['addition'][i]} mute) - " \ f"{data['reason'][i]}\n" if len(line1) > 0: result = CustomTools.split_string(line1, 1000) for i in range(len(result)): embed.add_field(inline=False, name=f"Manual Warns {i+1}", value=result[i]) if len(line2) > 0: result = CustomTools.split_string(line2, 1000) for i in range(len(result)): embed.add_field(inline=False, name=f"Auto Warns {i+1}", value=result[i]) if len(line3) > 0: result = CustomTools.split_string(line3, 1000) for i in range(len(result)): embed.add_field(inline=False, name=f"Mutes {i+1}", value=result[i]) await ctx.send(embed=embed)