async def download_doujin(self, ctx, code): return await ctx.send( "Due to recent shutdowns, this command has been disabled prematurely. It will be removed in the future." ) lolicon_allowed = False try: if not ctx.guild or ctx.guild.id in self.bot.user_data["UserData"][ str(ctx.guild.owner_id )]["Settings"]["UnrestrictedServers"]: lolicon_allowed = True except KeyError: pass if ctx.guild and not ctx.channel.is_nsfw(): await ctx.send( ":x: This command cannot be used in a non-NSFW channel.") return try: code = int(code) except ValueError: await ctx.send( ":x: You didn't type a proper ID. Hint: It has to be a number!" ) return nhentai_api = NHentai() conf = await ctx.send("<a:nreader_loading:810936543401213953>") if code not in self.bot.doujin_cache: doujin = await nhentai_api.get_doujin(code) else: doujin = self.bot.doujin_cache[code] if not doujin: await conf.edit(content="🔎❌ I did not find a doujin with that ID.") return self.bot.doujin_cache[code] = doujin if ("lolicon" in doujin.tags or "shotacon" in doujin.tags) and ctx.guild: try: if ctx.guild.id in self.bot.user_data["UserData"][str( ctx.guild.owner_id )]["Settings"]["UnrestrictedServers"]: lolicon_allowed = True except KeyError: pass if ("lolicon" in doujin.tags or "shotacon" in doujin.tags) and ctx.guild and not lolicon_allowed: await conf.edit( content= ":warning::no_entry_sign: This doujin contains lolicon/shotacon content and cannot be shown publically." ) return emb = Embed( description= "You are attempting to download a doujin. Press the arrow to continue." ) emb.set_author( name=f"{language_to_flag(doujin.languages)} {doujin.title}", url=f"https://nhentai.net/g/{doujin.id}/", icon_url= "https://cdn.discordapp.com/emojis/845298862184726538.png?v=1") emb.set_thumbnail(url=doujin.images[0]) await conf.edit(content='', embed=emb) await conf.add_reaction("⬇") try: await self.bot.wait_for("reaction_add", timeout=30, bypass_cooldown=True, check=lambda r,u: r.message.id==conf.id and \ u.id==ctx.message.author.id and \ str(r.emoji)=="⬇") except TimeoutError: await conf.remove_reaction("⬇", self.bot.user) emb.description = "You timed out." await conf.edit(embed=emb) return else: emb.description = "Downloading...\nYou will be notified when completed." emb.set_author( name=f"[{language_to_flag(doujin.languages)}] {doujin.title}", url=f"https://nhentai.net/g/{doujin.id}/", icon_url= "https://cdn.discordapp.com/emojis/810936543401213953.gif?v=1") emb.set_footer(text=f"[{' '*len(doujin.images)}]") await conf.edit(embed=emb) print( f"[HRB] {ctx.author} ({ctx.author.id}) started downloading {doujin.id} ({len(doujin.images)} pages)." ) files = list() for ind, page_url in enumerate(doujin.images, 1): udownload(page_url, f"Workspace/{ctx.message.id}_{doujin.id}_page{ind}.png") files.append( f"Workspace/{ctx.message.id}_{doujin.id}_page{ind}.png") if ind % 5 == 0: emb.set_footer( text=f"[{'|'*ind}{' '*(len(doujin.images)-ind)}]") await conf.edit(embed=emb) await sleep(0.5) emb.set_footer( text=f"Processing zip file... [{'|'*len(doujin.images)}]") await conf.edit(embed=emb) with ZipFile(f"Workspace/{ctx.message.id}.zip", "w") as send_zip: for ind, file_p in enumerate(files, 1): send_zip.write(file_p, f"page_{ind}.png", compress_type=ZIP_DEFLATED) os.remove(file_p) os.rename(f"Workspace/{ctx.message.id}.zip", f"Storage/{ctx.message.id}") new_filelink = f"https://nreader.supermechm500.repl.co/download?" \ f"id={ctx.message.id}" await conf.delete() await ctx.send( content=f"{ctx.author.mention}, your download has completed. ⬇", embed=Embed( color=0x32d17f, description= f"Here is a zipped file of your downloaded doujin. [Download]({new_filelink})\n" f'Remember to rename the file from "download" to "**something.zip**".\n' f"Expires in **5 minutes** or until bot is forced to reboot."). set_author( name=f"{language_to_flag(doujin.languages)} {doujin.title}", url=f"https://nhentai.net/g/{doujin.id}/", icon_url= "https://cdn.discordapp.com/emojis/845298862184726538.png?v=1" ).set_footer(text=f"[{'|'*len(doujin.images)}]")) await sleep(5 * 60) with suppress(FileNotFoundError): os.remove(f"Storage/{ctx.message.id}")
async def on_command_error(self, ctx: Context, error: Exception): if not isinstance(error, CommandNotFound): with suppress(Forbidden, NotFound): await ctx.message.add_reaction("❌") if not isinstance(error, CommandOnCooldown) and ctx.command: ctx.command.reset_cooldown(ctx) if self.bot.config['debug_mode']: try: raise error.original except AttributeError: raise error if not self.bot.config['debug_mode']: msg = ctx.message em = Embed(title="Error", color=0xff0000) if isinstance(error, BotMissingPermissions): em.description = f"This bot is missing one or more permissions listed in `{self.bot.command_prefix}help` " \ f"under `Required Permissions` or you are trying to use the command in a DM channel.\n" \ f"\n" \ f"**Pleae note that `doujin_info` and `search_doujins` can only be used in servers. Try creating a private one.**" elif isinstance(error, MissingPermissions): em.description = "You are missing a required permission, or you are trying to use the command in a DM channel." elif isinstance(error, NotOwner): em.description = "That command is not listed in the help menu and is to be used by the owner only." elif isinstance(error, MissingRequiredArgument): em.description = f"\"{error.param.name}\" is a required argument for command " \ f"\"{ctx.command.name}\" that is missing." elif isinstance(error, BadArgument): em.description = f"You didn't type something correctly. Details below:\n" \ f"{error}" elif isinstance(error, CommandNotFound): supposed_command = msg.content.split()[0] try: if supposed_command.startswith("n!") and \ not supposed_command.startswith("n!T"): # stable code = int(supposed_command.strip("n!")) msg.content = f"n!code {code}" await self.bot.process_commands(msg) return elif supposed_command.startswith("n!T"): # experimental code = int(supposed_command.strip("n!T")) msg.content = f"n!Tcode {code}" await self.bot.process_commands(msg) return except ValueError: return elif isinstance(error, CommandOnCooldown): em.description = f"That command is on a {round(error.cooldown.per)} second cooldown.\n" \ f"Retry in {round(error.retry_after)} seconds." elif isinstance(error, MaxConcurrencyReached): to_str = { BucketType.user: "******", BucketType.guild: "server", BucketType.channel: "channel", BucketType.channel: "member", BucketType.channel: "category", BucketType.channel: "role", } em.description = f"That command can only have up to {error.number} instances per {to_str[error.per]}.\n" \ f"Look for and click the {self.bot.get_emoji(853668227175546952)} (STOP) icon to stop the command, or let it time out, before executing it again." elif isinstance(error, CheckFailure): return else: try: em.description = f"**{type(error.original).__name__}**: {error.original}\n" \ f"\n" \ f"If you keep getting this error, please join the support server." except AttributeError: em.description = f"**{type(error).__name__}**: {error}\n" \ f"\n" \ f"If you keep getting this error, please join the support server." # Raising the exception causes the progam # to think about the exception in the wrong way, so we must # target the exception indirectly. if not self.bot.config["debug_mode"]: try: if hasattr(error, "original"): raise error.original else: raise error except Exception: error = exc_info() await self.bot.errorlog.send( error, ctx=ctx, event=f"Command: {ctx.command.name}") else: if hasattr(error, "original"): raise error.original else: raise error try: await ctx.send(embed=em) except Forbidden: with suppress(Forbidden): await ctx.author.send( content="This error was sent likely because I " "was blocked from sending messages there.", embed=em)