async def send_bird(ctx, bird, on_error=None, message=None, addOn="", bw=False): if bird == "": logger.error("error - bird is blank") await ctx.send("**There was an error fetching birds.**\n*Please try again.*") if on_error is not None: on_error(ctx) return # add special condition for screech owls # since screech owl is a genus and SciOly # doesn't specify a species if bird == "Screech Owl": logger.info("choosing specific Screech Owl") bird = random.choice(screech_owls) delete = await ctx.send("**Fetching.** This may take a while.") # trigger "typing" discord message await ctx.trigger_typing() try: response = await get_image(ctx, bird, addOn) except GenericError as e: await delete.delete() await ctx.send(f"**An error has occurred while fetching images.**\n*Please try again.*\n**Reason:** {str(e)}") logger.exception(e) if on_error is not None: on_error(ctx) return filename = str(response[0]) extension = str(response[1]) statInfo = os.stat(filename) if statInfo.st_size > 8000000: # another filesize check await delete.delete() await ctx.send("**Oops! File too large :(**\n*Please try again.*") else: if bw: loop = asyncio.get_running_loop() fn = partial(_black_and_white, filename) file_stream = await loop.run_in_executor(None, fn) else: file_stream = filename if message is not None: await ctx.send(message) # change filename to avoid spoilers file_obj = discord.File(file_stream, filename=f"bird.{extension}") await ctx.send(file=file_obj) await delete.delete()
async def leader_error(self, ctx, error): logger.info("leaderboard error") if isinstance(error, commands.BadArgument): await ctx.send('Not an integer!') elif isinstance(error, commands.CommandOnCooldown): # send cooldown await ctx.send("**Cooldown.** Try again after " + str(round(error.retry_after)) + " s.", delete_after=5.0) elif isinstance(error, commands.BotMissingPermissions): logger.error("missing permissions error") await ctx.send( f"""**The bot does not have enough permissions to fully function.** **Permissions Missing:** `{', '.join(map(str, error.missing_perms))}` *Please try again once the correct permissions are set.*""") else: await ctx.send("""**An uncaught leaderboard error has occurred.** *Please log this message in #support in the support server below, or try again.* **Error:** """ + str(error)) await ctx.send("https://discord.gg/husFeGG") raise error
async def send_birdsong(ctx, bird, on_error=None, message=None): if bird == "": logger.error("error - bird is blank") await ctx.send("**There was an error fetching birds.**\n*Please try again.*") if on_error is not None: on_error(ctx) return delete = await ctx.send("**Fetching.** This may take a while.") # trigger "typing" discord message await ctx.trigger_typing() try: response = await get_song(ctx, bird) except GenericError as e: await delete.delete() await ctx.send(f"**An error has occurred while fetching songs.**\n*Please try again.*\n**Reason:** {str(e)}") logger.exception(e) if on_error is not None: on_error(ctx) return filename = str(response[0]) extension = str(response[1]) # remove spoilers in tag metadata audioFile = eyed3.load(filename) if audioFile is not None and audioFile.tag is not None: audioFile.tag.remove(filename) statInfo = os.stat(filename) if statInfo.st_size > 8000000: # another filesize check await delete.delete() await ctx.send("**Oops! File too large :(**\n*Please try again.*") else: with open(filename, 'rb') as img: if message is not None: await ctx.send(message) # change filename to avoid spoilers await ctx.send(file=discord.File(img, filename="bird." + extension)) await delete.delete()
async def _download_helper(path, url, session): try: async with session.get(url) as response: # from https://stackoverflow.com/questions/29674905/convert-content-type-header-into-file-extension content_type = response.headers['content-type'].partition(';')[0].strip() if content_type.partition("/")[0] == "image": try: ext = "." + \ (set(ext[1:] for ext in guess_all_extensions( content_type)).intersection(valid_image_extensions)).pop() except KeyError: raise GenericError(f"No valid extensions found. Extensions: {guess_all_extensions(content_type)}") elif content_type.partition("/")[0] == "audio": try: ext = "." + ( set(ext[1:] for ext in guess_all_extensions(content_type)).intersection(valid_audio_extensions) ).pop() except KeyError: raise GenericError(f"No valid extensions found. Extensions: {guess_all_extensions(content_type)}") else: ext = guess_extension(content_type) # type: ignore if ext is None: raise GenericError(f"No extensions found.") filename = f"{path}{ext}" # from https://stackoverflow.com/questions/38358521/alternative-of-urllib-urlretrieve-in-python-3-5 with open(filename, 'wb') as out_file: block_size = 1024 * 8 while True: block = await response.content.read(block_size) # pylint: disable=no-member if not block: break out_file.write(block) return filename except aiohttp.ClientError: logger.error(f"Client Error with url {url} and path {path}") raise
async def send_fossil(ctx, fossil, on_error=None, message=None): if fossil == "": logger.error("error - fossil is blank") await ctx.send( "**There was an error fetching fossils.**\n*Please try again.*") if on_error is not None: on_error(ctx) return delete = await ctx.send("**Fetching.** This may take a while.") # trigger "typing" discord message await ctx.trigger_typing() try: response = await get_image(ctx, fossil) except GenericError as e: logger.exception(e) await delete.delete() await ctx.send( f"**An error has occurred while fetching images.**\n*Please try again.*\n**Reason:** {str(e)}" ) if on_error is not None: on_error(ctx) return filename = str(response[0]) extension = str(response[1]) statInfo = os.stat(filename) if statInfo.st_size > 8000000: # another filesize check await delete.delete() await ctx.send("**Oops! File too large :(**\n*Please try again.*") else: if message is not None: await ctx.send(message) # change filename to avoid spoilers file_obj = discord.File(filename, filename=f"fossil.{extension}") await ctx.send(file=file_obj) await delete.delete()
async def remove_error(self, ctx, error): logger.info("remove error") if isinstance(error, commands.MissingRequiredArgument): await ctx.send( f"**Please enter a state.**\n*Valid States:* `{', '.join(map(str, list(states.keys())))}`" ) elif isinstance(error, commands.CommandOnCooldown): # send cooldown await ctx.send("**Cooldown.** Try again after " + str(round(error.retry_after)) + " s.", delete_after=5.0) elif isinstance(error, commands.NoPrivateMessage): await ctx.send("**This command is unavaliable in DMs!**") elif isinstance(error, commands.BotMissingPermissions): logger.error("missing permissions error") await ctx.send( f"""**The bot does not have enough permissions to fully function.** **Permissions Missing:** `{', '.join(map(str, error.missing_perms))}` *Please try again once the correct permissions are set.*""") else: await ctx.send("""**An uncaught remove error has occurred.** *Please log this message in #support in the support server below, or try again.* **Error:** """ + str(error)) await ctx.send("https://discord.gg/fXxYyDJ") raise error
async def on_command_error(ctx, error): logger.exception(error) # don't handle errors with local handlers if hasattr(ctx.command, 'on_error'): return if isinstance(error, commands.CommandOnCooldown): # send cooldown await ctx.send("**Cooldown.** Try again after " + str(round(error.retry_after)) + " s.", delete_after=5.0) elif isinstance(error, commands.CommandNotFound): await ctx.send("Sorry, the command was not found.") elif isinstance(error, commands.MissingRequiredArgument): await ctx.send("This command requires an argument!") elif isinstance(error, commands.BadArgument): logger.error("bad argument") await ctx.send("The argument passed was invalid. Please try again.") elif isinstance(error, commands.ArgumentParsingError): logger.error("quote error") await ctx.send("An invalid character was detected. Please try again.") elif isinstance(error, commands.TooManyArguments): logger.error("too many args") await ctx.send("Too many arguments were provided. Please try again.") elif isinstance(error, commands.BotMissingPermissions): logger.error("missing permissions error") await ctx.send( f"""**The bot does not have enough permissions to fully function.** **Permissions Missing:** `{', '.join(map(str, error.missing_perms))}` *Please try again once the correct permissions are set.*""" ) elif isinstance(error, commands.NoPrivateMessage): await ctx.send("**This command is unavaliable in DMs!**") elif isinstance(error, commands.CommandInvokeError): if isinstance(error.original, redis.exceptions.ResponseError): if database.exists(f"channel:{str(ctx.channel.id)}"): await ctx.send( """**An unexpected ResponseError has occurred.** *Please log this message in #support in the support server below, or try again.* **Error:** """ + str(error) ) await ctx.send("https://discord.gg/husFeGG") else: await channel_setup(ctx) await ctx.send("Please run that command again.") elif isinstance(error.original, wikipedia.exceptions.DisambiguationError): await ctx.send("Wikipedia page not found. (Disambiguation Error)") elif isinstance(error.original, wikipedia.exceptions.PageError): await ctx.send("Wikipedia page not found. (Page Error)") elif isinstance(error.original, wikipedia.exceptions.WikipediaException): await ctx.send("Wikipedia page unavaliable. Try again later.") elif isinstance(error.original, aiohttp.ClientOSError): if error.original.errno != errno.ECONNRESET: await ctx.send( """**An unexpected ClientOSError has occurred.** *Please log this message in #support in the support server below, or try again.* **Error:** """ + str(error) ) await ctx.send("https://discord.gg/husFeGG") else: await ctx.send("**An error has occured with discord. :(**\n*Please try again.*") else: logger.exception(error) await ctx.send( """**An uncaught command error has occurred.** *Please log this message in #support in the support server below, or try again.* **Error:** """ + str(error) ) await ctx.send("https://discord.gg/husFeGG") raise error else: logger.error("uncaught non-command") await ctx.send( """**An uncaught non-command error has occurred.** *Please log this message in #support in the support server below, or try again.* **Error:** """ + str(error) ) await ctx.send("https://discord.gg/husFeGG") raise error