async def on_command_error(ctx, error): logger.info("ON_ERROR_COMMAND") if ctx.cog is not None: # Errors coming from cogs logger.info("Received cog exception: {0}".format(error)) raise error.original if isinstance(error, MissingPermissions): # Handle missing permissions await ctx.channel.send(i18n._("Permission denied.")) elif isinstance(error, NoPrivateMessage): await ctx.channel.send( i18n._("This command cannot be used in private messages.")) elif isinstance(error, MissingRole): await ctx.channel.send( i18n._("You don't have the required role to run this")) elif isinstance(error, CommandNotFound): await ctx.channel.send(i18n._("Command not found")) elif isinstance(error, ExpectedClosingQuoteError): await ctx.channel.send(i18n._("Missing a quote?")) else: # TODO: Send this only if the exception was not handled already... How to check this?? # await ctx.channel.send(i18n._("Something went wrong...")) if hasattr(error, "original"): raise error.original else: raise error
async def reminders(self, ctx): """ Group of commands to manage reminders. Displays existing reminders if called without a subcommand. """ if ctx.subcommand_passed is None: # No subcommand passed ctf = self._get_channel_ctf(ctx) if ctf.pending_reminders: await ctx.channel.send( "\n".join( "**{0})** {1}".format(idx + 1, r) for idx, r in enumerate(ctf.pending_reminders) ) ) else: await ctx.send( "Εν έσσιει κανένα reminder ρε τσιάκκο... Εν να βάλεις όξα?" ) elif ctx.invoked_subcommand is None: self.help_command.context = ctx await failed(ctx.message) await ctx.send( i18n._("**Invalid command passed**. See below for more help") ) await self.help_command.command_callback(ctx, command=str(ctx.command))
def launch(self) -> None: logger.info("Launching bot...") if self.config.DISCORD_BOT_TOKEN is None: raise ValueError( i18n._("DISCORD_BOT_TOKEN variable has not been set!")) self.run(self.config.DISCORD_BOT_TOKEN)
async def install_error(ctx, err): if isinstance(err.original, CogAlreadyInstalledException): await ctx.channel.send(i18n._("Extension already installed")) elif isinstance(err.original, SSHKey.DoesNotExist): await ctx.channel.send(i18n._("This key does not exist.")) elif isinstance(err.original, CogSpecificationMissingException): await ctx.channel.send( i18n. _("Extension specification (extension.json) does not exist!" )) elif isinstance(err.original, discord.ext.commands.errors.ExtensionFailed): await ctx.channel.send(i18n._("Error when loading:")) logger.info(dir(err.original)) await ctx.channel.send("```" + err.original.args[0] + "```") await failed(ctx.message)
async def wait_for_ssh_public_key(add_key_msg): """Coroutine that waits for a public key to be uploaded""" url = None try: message = await bot.wait_for( "message", timeout=60.0, check=partial(is_key, add_key_msg, pub_prefix), ) except asyncio.TimeoutError: await ctx.author.send( i18n._("Timed out... Try running `addkey` again")) else: await ctx.author.send( i18n._("Saved public key successfully!")) url = message.attachments[0].url return url
def launch(): sys.path.insert(1, os.path.join(os.getcwd(), "ovisbot", "extensions")) for extension in extensions: bot.load_extension(extension) if token is None: raise ValueError( i118n._("DISCORD_BOT_TOKEN variable has not been set!")) bot.run(token)
async def on_command_error(ctx, error): if ctx.cog is not None: # Errors coming from cogs logger.info("Received cog exception: {0}".format(error)) raise error.original return if isinstance(error, MissingPermissions): # Handle missing permissions await ctx.channel.send(i118n._("Permission denied.")) elif isinstance(error, CommandNotFound): await ctx.channel.send(i118n._("Command not found")) elif isinstance(error, ExpectedClosingQuoteError): await ctx.channel.send(i118n._("Command not found")) else: await ctx.channel.send(i118n._("Something went wrong...")) raise error.original
async def sayin(ctx, channel_id, *, msg): """Sends the given message to the channel with the specified channel id""" channel = discord.utils.get(ctx.guild.text_channels, id=int(channel_id)) if channel is None: await ctx.channel.send(i18n._("Could not find channel...")) else: await channel.send(msg) await success(ctx.message)
async def set(ctx, option, value): """Sets given config variable""" if hasattr(self.config, option): value = type(value)(value) setattr(self.config, option, value) self.config.save() await success(ctx.message) else: await ctx.send( i18n._("Property {0} does not exist".format(option))) await failed(ctx.message)
async def on_member_join(member): await member.send( i118n. _("Hello {0}! Welcome to the server! Send {1}help to see a list of available commands" .format(member.name, COMMAND_PREFIX))) announcements = discord.utils.get(member.guild.text_channels, name="announcements") if announcements is not None: await announcements.send((i118n._( "Welcome {0}! Take your time to briefly introduce yourself".format( member.name))))
async def keys(ctx): """ Group of commangs to manage extensions / Displays a list of all installed extensions if no subcommand passed """ if ctx.subcommand_passed is None: await ctx.send("```" + SSHKey.table_serialize() + "```") elif ctx.invoked_subcommand is None: self.help_command.context = ctx await failed(ctx.message) await ctx.send( i18n._( "**Invalid command passed**. See below for more help")) await self.help_command.command_callback(ctx, command=str( ctx.command))
async def rank_ctftime(ctx): """ Displays team ranking on Ctftime. """ url = "https://ctftime.org/api/v1/teams/81678/" headers = { "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0", } r = requests.get(url, headers=headers) data = r.json() status_response = i118n._( "CTFTime Ranking: " + str(data["rating"][0][str(datetime.now().year)]["rating_place"])) await ctx.channel.send(status_response)
async def config(ctx): """ Group of commangs to manage bot configuration / Displays a config opions and values if run without a subcommand """ if ctx.subcommand_passed is None: await ctx.send("```" + bot.config.options_table() + "```") elif ctx.invoked_subcommand is None: self.help_command.context = ctx await failed(ctx.message) await ctx.send( i18n._( "**Invalid command passed**. See below for more help")) await self.help_command.command_callback(ctx, command=str( ctx.command))
def challenge_summary(self): if not self.challenges: return i18n._( "No challenges found. Try adding one with `!ctf addchallenge <name> <category>`" ) solved_response, unsolved_response = "", "" for challenge in self.challenges: challenge_details = f'**{escape_md(challenge.name[len(self.name)+1:])}** [{", ".join(challenge.tags)}]' if challenge.solved_at: solved_response += f':white_check_mark: {challenge_details} Solved by: [{", ".join(challenge.solved_by)}]\n' else: unsolved_response += f':thinking: {challenge_details} Attempted by: [{escape_md(", ".join(challenge.attempted_by))}]\n' return (f"\\>>> Solved\n{solved_response}" + f"\\>>> Unsolved\n{unsolved_response}")
async def rank_htb(ctx): """ Displays Hack The Box team ranking """ headers = { "Host": "www.hackthebox.eu", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", } url = "https://www.hackthebox.eu/teams/profile/353" r = requests.get(url, headers=headers) result = re.search('<i class="fas fa-user-chart"></i> (.*)</span><br>', r.text) status_response = i118n._("HTB Ranking: " + result.group(1)) await ctx.channel.send(status_response)
async def rank_htb(ctx): """ Displays Hack The Box team ranking """ if self.config.HTB_TEAM_ID is None: raise NotConfiguredException( "Variable HTB_TEAM_ID is not configured") headers = { "Host": "www.hackthebox.eu", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", } url = "https://www.hackthebox.eu/teams/profile/{0}".format( self.config.HTB_TEAM_ID) r = requests.get(url, headers=headers) result = re.search( '<i class="fas fa-user-chart"></i> (.*)</span><br>', r.text) status_response = i18n._("Position: " + result.group(1)) embed = discord.Embed( title="Hack The Box Team Ranking", colour=discord.Colour(0x7ED321), url="https://www.hackthebox.eu", description=status_response, timestamp=datetime.now(), ) embed.set_thumbnail( url="https://forum.hackthebox.eu/uploads/RJZMUY81IQLQ.png") embed.set_footer( text="CYberMouflons", icon_url="https://i.ibb.co/yW2mYjq/cybermouflons.png", ) await ctx.channel.send(embed=embed)
async def status(ctx): """ Shows any ongoing, scheduled, finished CTFs in the server. """ status_response = "" ctfs = sorted([c for c in ctx.guild.categories], key=lambda x: x.created_at) for ctf in ctfs: try: ctf_doc = CTF.objects.get({"name": ctf.name}) except CTF.DoesNotExist: continue # await ctx.channel.send(f"{ctf.name} was not in the DB") ctfrole = discord.utils.get(ctx.guild.roles, name="Team-" + ctf.name) status_response += ctf_doc.status(len(ctfrole.members)) if len(status_response) == 0: status_response = i18n._("CTF list is empty!") await ctx.channel.send(status_response) return for chunk in chunkify(status_response, 1900): emb = discord.Embed(description=chunk, colour=4387968) await ctx.channel.send(embed=emb)
async def rank_ctftime(ctx): """ Displays team ranking on Ctftime. """ if self.config.CTFTIME_TEAM_ID is None: raise NotConfiguredException( "Variable CTFTIME_TEAM_ID is not configured") url = "https://ctftime.org/api/v1/teams/{0}/".format( self.config.CTFTIME_TEAM_ID) headers = { "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0", } r = requests.get(url, headers=headers) data = r.json() status_response = i18n._("Position: " + str(data["rating"][0][str( datetime.now().year)]["rating_place"])) embed = discord.Embed( title="CTFTime Ranking", colour=discord.Colour(0xFF0035), url="https://ctftime.org/", description=status_response, timestamp=datetime.now(), ) embed.set_thumbnail( url= "https://pbs.twimg.com/profile_images/2189766987/ctftime-logo-avatar_400x400.png" ) embed.set_footer( text="CYberMouflons", icon_url="https://i.ibb.co/yW2mYjq/cybermouflons.png", ) await ctx.channel.send(embed=embed)
async def on_message(message): if bot.user in message.mentions: await message.channel.send(i118n._("What?!")) await bot.process_commands(message)
async def add(ctx, keyname): """Adds an SSH key""" try: SSHKey.objects.get({"name": keyname}) except SSHKey.DoesNotExist: pass else: await ctx.send( i18n._("This key name already exists. Choose another one.") ) return if not isinstance(ctx.channel, discord.DMChannel): await ctx.send( i18n. _("This is a public channel. Continue the process through DM." )) # TODO: Create key manager to handle these sort of tasks async def prompt_keys(): """Creates coroutines to pick up private and public keys and saves key""" def is_key(add_key_msg, prefix, message): return (isinstance(message.channel, discord.DMChannel) and add_key_msg.author == message.author and message.content.startswith(prefix) and message.attachments) priv_prefix = "private" pub_prefix = "public" await ctx.author.send( i18n. _("Please upload your private and public keys an attachment in a message that starts with `{0}` and `{1}` respectively." .format(priv_prefix, pub_prefix))) async def wait_for_ssh_private_key(add_key_msg): """Coroutine that waits for a private key to be uploaded""" url = None try: message = await bot.wait_for( "message", timeout=60.0, check=partial(is_key, add_key_msg, priv_prefix), ) except asyncio.TimeoutError: await ctx.author.send( i18n._("Timed out... Try running `addkey` again")) else: await ctx.author.send( i18n._("Saved private key successfully!")) url = message.attachments[0].url return url async def wait_for_ssh_public_key(add_key_msg): """Coroutine that waits for a public key to be uploaded""" url = None try: message = await bot.wait_for( "message", timeout=60.0, check=partial(is_key, add_key_msg, pub_prefix), ) except asyncio.TimeoutError: await ctx.author.send( i18n._("Timed out... Try running `addkey` again")) else: await ctx.author.send( i18n._("Saved public key successfully!")) url = message.attachments[0].url return url privkey_prompt_task = bot.loop.create_task( wait_for_ssh_private_key(ctx.message)) public_prompt_task = bot.loop.create_task( wait_for_ssh_public_key(ctx.message)) # logger.info(type(task)) private = await privkey_prompt_task public = await public_prompt_task key = SSHKey( name=keyname, owner_name=ctx.author.display_name, owner_id=str(ctx.author.id), private_key=private, public_key=public, ) key.save() message = await ctx.author.send(i18n._("Key added!")) await success(message) bot.loop.create_task(prompt_keys())
async def prompt_keys(): """Creates coroutines to pick up private and public keys and saves key""" def is_key(add_key_msg, prefix, message): return (isinstance(message.channel, discord.DMChannel) and add_key_msg.author == message.author and message.content.startswith(prefix) and message.attachments) priv_prefix = "private" pub_prefix = "public" await ctx.author.send( i18n. _("Please upload your private and public keys an attachment in a message that starts with `{0}` and `{1}` respectively." .format(priv_prefix, pub_prefix))) async def wait_for_ssh_private_key(add_key_msg): """Coroutine that waits for a private key to be uploaded""" url = None try: message = await bot.wait_for( "message", timeout=60.0, check=partial(is_key, add_key_msg, priv_prefix), ) except asyncio.TimeoutError: await ctx.author.send( i18n._("Timed out... Try running `addkey` again")) else: await ctx.author.send( i18n._("Saved private key successfully!")) url = message.attachments[0].url return url async def wait_for_ssh_public_key(add_key_msg): """Coroutine that waits for a public key to be uploaded""" url = None try: message = await bot.wait_for( "message", timeout=60.0, check=partial(is_key, add_key_msg, pub_prefix), ) except asyncio.TimeoutError: await ctx.author.send( i18n._("Timed out... Try running `addkey` again")) else: await ctx.author.send( i18n._("Saved public key successfully!")) url = message.attachments[0].url return url privkey_prompt_task = bot.loop.create_task( wait_for_ssh_private_key(ctx.message)) public_prompt_task = bot.loop.create_task( wait_for_ssh_public_key(ctx.message)) # logger.info(type(task)) private = await privkey_prompt_task public = await public_prompt_task key = SSHKey( name=keyname, owner_name=ctx.author.display_name, owner_id=str(ctx.author.id), private_key=private, public_key=public, ) key.save() message = await ctx.author.send(i18n._("Key added!")) await success(message)
async def ranking_error(ctx, error): if isinstance(error, NotConfiguredException): await ctx.channel.send( i18n._("Configuration missing: {0}".format(error.args[0])))
async def frappe(ctx): """ Orders a cold frappe! """ await ctx.channel.send(i118n._("Frappe on it's way...!"))