Esempio n. 1
0
 async def on_message(self, msg: Message):
     if str(self.bot.user.id) in msg.content:
         ts = tz.localize(datetime.now()).strftime("%b. %d, %Y %I:%M %p")
         author = msg.author
         display_name = f' ({author.display_name})' if author.display_name != author.name else ''
         em = Embed(title=f"{msg.guild}: #{msg.channel} at {ts}",
                    description=msg.content,
                    color=author.colour)
         em.set_author(
             name=f"{author.name}#{author.discriminator}{display_name}",
             icon_url=author.avatar_url_as(format="png"))
         await self.notifchannel.send(msg.jump_url, embed=em)
Esempio n. 2
0
    def em_base(self, user: Union[Member, User], log_title: str,
                color: int) -> Embed:
        """Do basic formatting on the embed"""

        em = Embed(description=f"*{log_title}*", color=color)

        user_repr = f"{user.name}#{user.discriminator}   (ID: {user.id})"
        em.set_author(name=user_repr, icon_url=user.avatar_url)

        em.set_footer(text=self._get_timestamp())

        return em
Esempio n. 3
0
    async def user(self, ctx: Context, *, user: str = None):
        """User

        Selects a GitHub user account and shows a brief of the profile.
        `[p]gh user <username>` will select a user account
        `[p]gh user self` will select your user account
        `[p]gh user` will display the currently selected user"""

        try:
            if user == "self":
                self.user = user = self.gh_client.get_user()
            elif user:
                self.user = user = self.gh_client.get_user(user)
            else:
                if self.user:
                    user = self.user
                else:
                    return await self.bot.send_help_for(
                        ctx.command,
                        "No account is currently selected."
                    )

            if self.repo.owner.name != self.user.name:
                self.repo = None

            repos = len(list(user.get_repos()))
            gists = len(list(user.get_gists()))
            stars = len(list(user.get_gists()))

            em = Embed(
                title=f"{user.login}'s Public GitHub Profile",
                description=f"*\"{user.bio}\"*\n\n"
                            f"{Emoji.repo} [Repositories]({user.html_url}?tab=repositories): {repos}\n"
                            f"{Emoji.gist} [Gists](https://gist.github.com/{user.login}): {gists}\n"
                            f"{Emoji.star} [Starred Repositories]({user.html_url}?tab=stars): {stars}",
                color=Colour.green()
            )
            em.set_author(name=user.name, url=user.html_url, icon_url=user.avatar_url)

        except:
            em = Embed(
                title="GitHub: Error",
                description="Unable to load user or user not found",
                color=Colour.red()
            )

        await ctx.send(embed=em)
Esempio n. 4
0
class SearchResultsBrowser:
    def __init__(self, bot: Bot, ctx: Context, results: List[Doujin], **kwargs):
        """Class to create and run a browser from NHentai-API

        `results` - obtained from nhentai_api.search(query)
        `msg` - optional message that the bot owns to edit, otherwise created 
        """
        self.bot = bot
        self.ctx = ctx
        self.doujins = results
        self.index = 0
        self.lolicon_allowed = kwargs.pop("lolicon_allowed", False)
        self.minimal_details = kwargs.pop("minimal_details", True)
        self.name = kwargs.pop("name", "Search Results")

        self.active_message: Message = kwargs.pop("msg", None)
        self.am_embed: Embed = Embed()
        self.is_zoomed = False

        self.language = kwargs.pop("user_language", "eng")
    
    async def update_browser(self, ctx):
        message_part = []
        for ind, dj in enumerate(self.doujins):
            try: 
                if ind == self.index and int(dj.id) in self.bot.user_data['UserData'][str(ctx.author.id)]['Lists']['Built-in']["Favorites|*n*|fav"]: symbol = '🟩'
                elif ind == self.index: symbol='πŸŸ₯'
                elif int(dj.id) in self.bot.user_data['UserData'][str(ctx.author.id)]['Lists']['Built-in']["Favorites|*n*|fav"]: symbol = '🟦'
                else: symbol='⬛'
            except KeyError: 
                symbol='⬛'
            
            tags = [tag.name for tag in dj.tags if tag.type == "tag"]
            if any([tag in restricted_tags for tag in tags]) and ctx.guild and not self.lolicon_allowed:
                message_part.append(
                    f"{'**' if ind == self.index else ''}"
                    f"`{symbol} {str(ind+1).ljust(2)}` | {localization[self.language]['search_doujins']['contains_restricted_tags']}"
                    f"{'**' if ind == self.index else ''}")
            else:
                message_part.append(
                    f"{'**' if ind == self.index else ''}"
                    f"`{symbol} {str(ind+1).ljust(2)}` | "
                    f"__`{str(dj.id).ljust(7)}`__ | "
                    f"{language_to_flag(dj.languages)} | "
                    f"{shorten(dj.title.pretty, width=40, placeholder='...')}"
                    f"{'**' if ind == self.index else ''}")

        doujin = self.doujins[self.index]
        previous_emb = deepcopy(self.am_embed)
        #self.active_message.embeds[0] = self.am_embed

        self.am_embed = Embed(
            title=self.name,
            description=f"\n"+('\n'.join(message_part))+"\n\nβ–Œβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–“β–’β–’β–‘β–‘")

        nhentai = NHentai()
        tags = [tag.name for tag in doujin.tags if tag.type == "tag"]
        if any([tag in restricted_tags for tag in tags]) and ctx.guild and not self.lolicon_allowed:
            self.am_embed.add_field(
                name=localization[self.language]['results_browser']['forbidden']['title'],
                inline=False,
                value=localization[self.language]['results_browser']['forbidden']['description']
            ).set_footer(
                text=f"⭐ N/A"
            )
            
            doujin.cover.src = str(self.bot.user.avatar.url) 
        
        else:
            if self.minimal_details:
                self.am_embed.add_field(
                    name=localization[self.language]['results_browser']['minimal_details'],
                    inline=False,
                    value=
                        f"ID: `{doujin.id}`\n"
                        f"{localization[self.language]['doujin_info']['fields']['title']}: {language_to_flag(doujin.languages)} `{shorten(doujin.title.pretty, width=256, placeholder='...')}`\n"
                        f"{localization[self.language]['doujin_info']['fields']['artists']}: `{', '.join([tag.name for tag in doujin.artists]) if doujin.artists else localization[self.language]['doujin_info']['fields']['not_provided']}`\n"
                        f"{localization[self.language]['doujin_info']['fields']['characters']}: `{', '.join([tag.name for tag in doujin.characters]) if doujin.characters else localization[self.language]['doujin_info']['fields']['original']}`\n"
                        f"{localization[self.language]['doujin_info']['fields']['parodies']}: `{', '.join([tag.name for tag in doujin.parodies]) if doujin.parodies else localization[self.language]['doujin_info']['fields']['original']}`\n"
                        f"{localization[self.language]['doujin_info']['fields']['tags']}:\n||`{shorten(str(', '.join([tag.name for tag in doujin.tags if tag.type == 'tag']) if [tag.name for tag in doujin.tags if tag.type == 'tag'] else localization[self.language]['doujin_info']['fields']['not_provided']), width=950, placeholder='...')}`||"
                ).set_footer(
                    text=f"{localization[self.language]['doujin_info']['sfw']}")

                self.am_embed.set_author(
                    name=f"NHentai",
                    icon_url="https://cdn.discordapp.com/emojis/845298862184726538.png?v=1")

                self.am_embed.set_thumbnail(url=Embed.Empty)
                self.am_embed.set_image(url=Embed.Empty)

            else:
                self.am_embed.add_field(
                    name=localization[self.language]['doujin_info']['fields']['title'],
                    inline=False,
                    value=f"`{shorten(doujin.title.pretty, width=256, placeholder='...')}`"
                ).add_field(
                    inline=False,
                    name=localization[self.language]['doujin_info']['fields']['id/pages'],
                    value=f"`{doujin.id}` - `{doujin.total_pages}`"
                ).add_field(
                    inline=False,
                    name=localization[self.language]['doujin_info']['fields']['date_uploaded'],
                    value=f"<t:{int(doujin.upload_at.timestamp())}>"
                ).add_field(
                    inline=False,
                    name=localization[self.language]['doujin_info']['fields']['languages'],
                    value=f"{language_to_flag(doujin.languages)} `{', '.join([localization[self.language]['doujin_info']['fields']['language_names'][tag.name] for tag in doujin.languages]) if doujin.languages else localization[self.language]['doujin_info']['fields']['not_provided']}`"
                ).add_field(
                    inline=False,
                    name=localization[self.language]['doujin_info']['fields']['artists'],
                    value=f"`{', '.join([tag.name for tag in doujin.artists]) if doujin.artists else localization[self.language]['doujin_info']['fields']['not_provided']}`"
                ).add_field(
                    inline=False,
                    name=localization[self.language]['doujin_info']['fields']['characters'],
                    value=f"`{', '.join([tag.name for tag in doujin.characters]) if doujin.characters else localization[self.language]['doujin_info']['fields']['original']}`"
                ).add_field(
                    inline=False,
                    name=localization[self.language]['doujin_info']['fields']['parodies'],
                    value=f"`{', '.join([tag.name for tag in doujin.parodies]) if doujin.parodies else localization[self.language]['doujin_info']['fields']['original']}`"
                ).set_footer(
                    text=f"⭐ {doujin.total_favorites}"
                )

                # Doujin count for tags
                tags_list = []
                for tag in [tag for tag in doujin.tags if tag.type == "tag"]:
                    count = tag.count
                    parse_count = list(str(count))
                    if len(parse_count) < 4:
                        tags_list.append(f"{localization[self.language]['fields']['tag_names'][tag.name] if tag.name in localization[self.language]['doujin_info']['fields']['tag_names'] else tag.name}[{count}]")
                    elif len(parse_count) >= 4 and len(parse_count) <= 6:
                        count = count/1000
                        tags_list.append(f"{localization[self.language]['fields']['tag_names'][tag.name] if tag.name in localization[self.language]['doujin_info']['fields']['tag_names'] else tag.name}[{round(count, 1)}k]")
                    elif len(parse_count) > 7:
                        count = count/1000000
                        tags_list.append(f"{localization[self.language]['fields']['tag_names'][tag.name] if tag.name in localization[self.language]['doujin_info']['fields']['tag_names'] else tag.name}[{round(count, 2)}m]")

                self.am_embed.add_field(
                    inline=False,
                    name=localization[self.language]["doujin_info"]["fields"]["tags"],
                    value=f"```{shorten(str(', '.join(tags_list) if tags_list else localization[self.language]['doujin_info']['fields']['not_provided']), width=1018, placeholder='...')}```"
                )

                self.am_embed.set_author(
                    name=f"NHentai",
                    url=f"https://nhentai.net/g/{doujin.id}/",
                    icon_url="https://cdn.discordapp.com/emojis/845298862184726538.png?v=1")

                if self.is_zoomed:
                    self.am_embed.set_image(url=doujin.cover.src)
                    self.am_embed.set_thumbnail(url=Embed.Empty)
                elif not self.is_zoomed:
                    self.am_embed.set_thumbnail(url=doujin.cover.src)
                    self.am_embed.set_image(url=Embed.Empty)


        if not self.active_message:
            self.active_message = await ctx.send("...")

        class SRBControls(ui.View):
            def __init__(self, bot, ctx, parent):
                super().__init__(timeout=60)
                self.value = 0
                self.bot = bot
                self.ctx = ctx
                self.parent = parent
            
            @ui.button(emoji=self.bot.get_emoji(853800909108936754), style=ButtonStyle.secondary, custom_id="up")
            async def up_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    if self.parent.index > 0:
                        self.parent.index -= 1
                    elif self.parent.index == 0:
                        self.parent.index = len(self.parent.doujins)-1

                    self.stop()

            @ui.button(emoji=self.bot.get_emoji(853800909276315678), style=ButtonStyle.secondary, custom_id="down")
            async def down_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    if self.parent.index < len(self.parent.doujins)-1:
                        self.parent.index += 1
                    elif self.parent.index == len(self.parent.doujins)-1:
                        self.parent.index = 0

                    self.stop()

            @ui.button(emoji=self.bot.get_emoji(853668227212902410), style=ButtonStyle.secondary, custom_id="select")
            async def select_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    conf = await self.ctx.send(embed=Embed(
                        description=localization[self.parent.language]['results_browser']['buttons']['select']))

                    while True:
                        try:
                            m = await self.bot.wait_for("message", timeout=15, bypass_cooldown=True,
                                check=lambda m: m.author.id == self.ctx.author.id and m.channel.id == self.ctx.channel.id)
                        
                        except TimeoutError:
                            await conf.delete()
                            
                            self.stop()
                            return

                        else:
                            with suppress(Forbidden):
                                await m.delete()
                            
                            if m.content == "n-cancel":
                                await conf.delete()
                                
                                self.stop()
                                return
                            
                            if is_int(m.content) and (int(m.content)-1) in range(0, len(self.parent.doujins)):
                                await conf.delete()
                                self.parent.index = int(m.content)-1

                                self.stop()
                                return

                            else:
                                continue

                    self.stop()  # unreachable, but just to be consistant with design

            @ui.button(emoji=self.bot.get_emoji(853668227175546952), style=ButtonStyle.secondary, custom_id="stop")
            async def stop_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    message_part = []
                    for ind, dj in enumerate(self.parent.doujins):
                        tags = [tag.name for tag in dj.tags if tag.type == "tag"]
                        if any([tag in restricted_tags for tag in tags]) and self.ctx.guild and not self.parent.lolicon_allowed:
                            message_part.append(localization[self.parent.language]['search_doujins']['contains_restricted_tags'])
                        else:
                            message_part.append(
                                f"__`{str(dj.id).ljust(7)}`__ | "
                                f"{language_to_flag(dj.languages)} | "
                                f"{shorten(dj.title.pretty, width=50, placeholder='...')}")
                    
                    self.parent.am_embed = Embed(
                        title=self.parent.name,
                        description=f"\n"+('\n'.join(message_part)))

                    self.parent.am_embed.set_author(
                        name="NHentai",
                        url=f"https://nhentai.net/",
                        icon_url="https://cdn.discordapp.com/emojis/845298862184726538.png?v=1")
                    
                    self.parent.am_embed.set_thumbnail(url=Embed.Empty)
                    self.parent.am_embed.set_image(url=Embed.Empty)
                    await self.parent.active_message.edit(embed=self.parent.am_embed, view=None)

                    self.value = 1
                    self.stop()

            if not self.ctx.guild or (self.ctx.guild and not all([
                self.ctx.guild.me.guild_permissions.manage_channels, 
                self.ctx.guild.me.guild_permissions.manage_roles, 
                self.ctx.guild.me.guild_permissions.manage_messages])):

                @ui.button(emoji=self.bot.get_emoji(853684136379416616), style=ButtonStyle.secondary, custom_id="read", disabled=True)
                async def read_button(self, button, interaction):
                    return

            else:
                @ui.button(emoji=self.bot.get_emoji(853684136379416616), style=ButtonStyle.secondary, custom_id="read", disabled=self.minimal_details)
                async def read_button(self, button, interaction):
                    if interaction.user.id == self.ctx.author.id:
                        await interaction.response.defer()

                        tags = [tag.name for tag in self.parent.doujins[self.parent.index].tags if tag.type == "tag"]
                        if any([tag in restricted_tags for tag in tags]) and self.ctx.guild and not self.parent.lolicon_allowed:
                            self.stop()
                            return
                        
                        message_part = []
                        for ind, dj in enumerate(self.parent.doujins):
                            tags = [tag.name for tag in dj.tags if tag.type == "tag"]
                            if any([tag in restricted_tags for tag in tags]) and self.ctx.guild and not self.parent.lolicon_allowed:
                                message_part.append(localization[self.parent.language]['search_doujins']['contains_restricted_tags'])
                            else:
                                message_part.append(
                                    f"{'**' if ind == self.parent.index else ''}"
                                    f"__`{str(dj.id).ljust(7)}`__ | "
                                    f"{language_to_flag(dj.languages)} | "
                                    f"{shorten(dj.title.pretty, width=50, placeholder='...')}"
                                    f"{'**' if ind == self.parent.index else ''}")

                        self.parent.am_embed = Embed(
                            title=self.parent.name,
                            description=f"\n"+('\n'.join(message_part)))
                        self.parent.am_embed.set_author(
                            name="NHentai",
                            url=f"https://nhentai.net/",
                            icon_url="https://cdn.discordapp.com/emojis/845298862184726538.png?v=1")
                        
                        self.parent.am_embed.set_thumbnail(url=Embed.Empty)
                        self.parent.am_embed.set_image(url=Embed.Empty)

                        await self.parent.active_message.edit(embed=self.parent.am_embed, view=None)

                        self.value = 1
                        self.stop()

                        doujin = self.parent.doujins[self.parent.index]
                        if str(doujin.id) in self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']["Bookmarks|*n*|bm"]:
                            page = self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']["Bookmarks|*n*|bm"][str(doujin.id)]
                        else:
                            page = 0

                        session = ImagePageReader(self.bot, self.ctx, doujin.images, doujin.title.pretty, str(doujin.id), starting_page=page)
                        response = await session.setup()
                        if response:
                            await session.start()
                        else:
                            await self.parent.active_message.edit(embed=self.parent.am_embed)

                        

            @ui.button(emoji=self.bot.get_emoji(853684136433942560), style=ButtonStyle.secondary, custom_id="zoom", disabled=self.minimal_details)
            async def zoom_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    self.parent.is_zoomed = not self.parent.is_zoomed
                    
                    self.stop()

            @ui.button(emoji=self.bot.get_emoji(853668227205038090), style=ButtonStyle.secondary, custom_id="readlater")
            async def readlater_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    if len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"]) >= 25: 
                        await self.ctx.send(
                            embed=Embed(
                                color=0xff0000, 
                                description=localization[self.parent.language]['results_browser']['buttons']['read_later_full']
                            ),
                            delete_after=5)
                        
                        self.stop()
                        return

                    if str(self.parent.doujins[self.parent.index].id) not in self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"]:
                        self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"].append(str(self.parent.doujins[self.parent.index].id))
                        await self.ctx.send(
                            embed=Embed(
                                description=localization[self.parent.language]['results_browser']['buttons']['add_to_read_later'].format(code=self.parent.doujins[self.parent.index].id)
                            ),
                            delete_after=5)
                    else:
                        self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Read Later|*n*|rl"].remove(str(self.parent.doujins[self.parent.index].id))
                        await self.ctx.send(
                            embed=Embed(
                                description=localization[self.parent.language]['results_browser']['buttons']['remove_from_read_later'].format(code=self.parent.doujins[self.parent.index].id)
                            ),
                            delete_after=5)
            
                    self.stop()

            async def on_timeout(self):
                message_part = []
                for ind, dj in enumerate(self.parent.doujins):
                    tags = [tag.name for tag in dj.tags if tag.type == "tag"]
                    if any([tag in restricted_tags for tag in tags]) and self.ctx.guild and not self.parent.lolicon_allowed:
                        message_part.append(localization[self.parent.language]['search_doujins']['contains_restricted_tags'])
                    else:
                        message_part.append(
                            f"__`{str(dj.id).ljust(7)}`__ | "
                            f"{language_to_flag(dj.languages)} | "
                            f"{shorten(dj.title.pretty, width=50, placeholder='...')}")
                
                self.parent.am_embed = Embed(
                    title=self.parent.name,
                    description=f"\n"+('\n'.join(message_part)))
                self.parent.am_embed.set_author(
                    name="NHentai",
                    url=f"https://nhentai.net/",
                    icon_url="https://cdn.discordapp.com/emojis/845298862184726538.png?v=1")
                

                self.parent.am_embed.set_thumbnail(url=Embed.Empty)
                self.parent.am_embed.set_image(url=Embed.Empty)

                await self.parent.active_message.edit(embed=self.parent.am_embed, view=None)
                
                self.value = 1
                self.stop()

        view = SRBControls(self.bot, self.ctx, self)
        view.add_item(ui.Button(label=localization[self.language]['results_browser']['buttons']['support_server'], style=ButtonStyle.link, url="https://discord.gg/DJ4wdsRYy2"))
        await self.active_message.edit(embed=self.am_embed, view=view)
        await view.wait()
        return view.value

    async def start(self, ctx):
        """Initial start of the result browser."""

        view_exit_code = 0
        while view_exit_code == 0:
            view_exit_code = await self.update_browser(self.ctx)
Esempio n. 5
0
class ImagePageReader:
    def __init__(self, bot: Bot, ctx: Context, images:list, name:str, code:str, **kwargs):
        """Create and run a reader based on pages from a Doujin. 
        To work for any purpose, this class needs a few changes.
        
        `bot` - The Bot class created on initialization
        `ctx` - Context used
        `images` The list of image urls to use
        `name` - Title of the reader
        `code` - Book/Item ID

        `**kwargs` - Further keyword arguments if need be
        -- `current_page` - The starting page as an integer. Defaults to `0`

        """
        self.bot = bot
        self.ctx: Context = ctx
        self.images: list = images
        self.name: str = name
        self.code: str = code

        self.current_page: int = kwargs.pop("starting_page", 0)
        self.active_message: Message = None

        self.am_embed: Embed = None
        self.am_channel: TextChannel = None
        self.is_paused: bool = False
        self.on_bookmarked_page: bool = False

        self.language = kwargs.pop("user_language", "eng")

    async def update(self, ctx):
        if self.code in self.bot.user_data['UserData'][str(ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm'] and \
            self.current_page == self.bot.user_data['UserData'][str(ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm'][self.code]:
            self.on_bookmarked_page = True
        else:
            self.on_bookmarked_page = False

        self.am_embed.description = f"<:nprev:853668227124953159>{'<:nfini:853670159310913576>' if self.current_page == (len(self.images)-1) else '<:nnext:853668227207790602>'} {localization[self.language]['page_reader']['description']['previous']} | {localization[self.language]['page_reader']['description']['finish'] if self.current_page == (len(self.images)-1) else localization[self.language]['page_reader']['description']['next']}\n" \
                                    f"<:nsele:853668227212902410><:nstop:853668227175546952> {localization[self.language]['page_reader']['description']['select']} | {localization[self.language]['page_reader']['description']['stop']}\n" \
                                    f"<:npaus:853668227234529300><:nbook:853668227205038090> {localization[self.language]['page_reader']['description']['pause']} | {localization[self.language]['page_reader']['description']['bookmark'] if not self.on_bookmarked_page else localization[self.language]['page_reader']['description']['unbookmark']}\n" 

        self.am_embed.set_image(url=self.images[self.current_page].src)
        self.am_embed.set_footer(text=localization[self.language]['page_reader']['footer'].format(current=self.current_page+1, total=len(self.images), bookmark='πŸ”–' if self.on_bookmarked_page else ''))

        if self.bot.user_data["UserData"][str(ctx.author.id)]["Settings"]["ThumbnailPreference"] == 0:
            self.am_embed.set_thumbnail(url=self.images[self.current_page+1].src if (self.current_page+1) in range(0, len(self.images)) else Embed.Empty)                
        if self.bot.user_data["UserData"][str(ctx.author.id)]["Settings"]["ThumbnailPreference"] == 1:
            self.am_embed.set_thumbnail(url=self.images[self.current_page-1].src if (self.current_page-1) in range(0, len(self.images)) else Embed.Empty) 
        if self.bot.user_data["UserData"][str(ctx.author.id)]["Settings"]["ThumbnailPreference"] == 2:
            self.am_embed.set_thumbnail(url=Embed.Empty)

        thumbnail_buttons = {
            0: self.bot.get_emoji(903121521571168276),
            1: self.bot.get_emoji(903122915619373106),
            2: self.bot.get_emoji(903121521621491732)
        }

        class IPRControls(ui.View):
            def __init__(self, bot, ctx, parent):
                super().__init__(timeout=300)
                self.value = 0
                self.bot = bot
                self.ctx = ctx
                self.parent = parent
            
            @ui.button(emoji=self.bot.get_emoji(853668227124953159), style=ButtonStyle.secondary, custom_id="previous", disabled=self.current_page==0)
            async def previous_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    if self.parent.current_page == 0:  # Not allowed to go behind zero
                        return self.stop()
                    else:
                        self.parent.current_page = self.parent.current_page - 1

                    self.stop()

            @ui.button(emoji=self.bot.get_emoji(853670159310913576) if self.current_page+1==len(self.images) else self.bot.get_emoji(853668227207790602), style=ButtonStyle.secondary, custom_id="next")
            async def next_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    self.parent.current_page = self.parent.current_page + 1
                    if self.parent.current_page > (len(self.parent.images)-1):  # Finish the doujin if at last page
                        self.parent.am_embed.set_image(url=Embed.Empty)
                        self.parent.am_embed.set_thumbnail(url=Embed.Empty)
                        self.parent.am_embed.description=localization[self.parent.language]['page_reader']['finished']

                        await self.parent.active_message.edit(embed=self.parent.am_embed, view=None)
                        if self.parent.code in self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Read Later|*n*|rl']:
                            self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Read Later|*n*|rl'].remove(self.parent.code)
                        
                        await sleep(2)
                        await self.parent.active_message.edit(content=f"{self.parent.bot.get_emoji(810936543401213953)} {localization[self.parent.language]['page_reader']['closing']}", embed=None)

                        await sleep(1)
                        await self.parent.am_channel.delete()

                        self.value = 1
                        self.stop()
                    
                    else:
                        self.stop()

            @ui.button(emoji=self.bot.get_emoji(853668227212902410), style=ButtonStyle.secondary, custom_id="select")
            async def select_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()
                    
                    bm_page = None
                    if self.parent.code in self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm']:
                        bm_page = self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm'][self.parent.code]
                    
                    conf = await self.parent.am_channel.send(embed=Embed(
                        description=localization[self.parent.language]['page_reader']['select_inquiry']['description']
                    ).set_footer(
                        text=localization[self.parent.language]['page_reader']['select_inquiry']['footer'].format(bookmarked_page=str(bm_page+1) if bm_page else 'N/A')))
                    
                    while True:
                        try:
                            m = await self.bot.wait_for("message", timeout=15, bypass_cooldown=True,
                                check=lambda m: m.author.id == self.ctx.author.id and m.channel.id == self.parent.am_channel.id)
                        
                        except TimeoutError:
                            await conf.delete()
                            break

                        else:
                            with suppress(Forbidden):
                                await m.delete()
                            
                            if m.content == "n-cancel":
                                await conf.delete()
                                break
                            
                            if is_int(m.content) and (int(m.content)-1) in range(0, len(self.parent.images)):
                                await conf.delete()
                                self.parent.current_page = int(m.content)-1
                                
                                return self.stop()
                            
                            else:
                                with suppress(Forbidden):
                                    await m.delete()

                                continue
                
            @ui.button(emoji=self.bot.get_emoji(853668227175546952), style=ButtonStyle.secondary, custom_id="stop")
            async def stop_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    self.parent.am_embed.set_image(url=Embed.Empty)
                    self.parent.am_embed.set_thumbnail(url=Embed.Empty)
                    self.parent.am_embed.description=localization[self.parent.language]['page_reader']['stopped']
                    
                    await self.parent.active_message.edit(embed=self.parent.am_embed, view=None)

                    await sleep(2)
                    await self.parent.active_message.edit(content=f"{self.bot.get_emoji(810936543401213953)} {localization[self.parent.language]['page_reader']['closing']}", embed=None)
                    
                    await sleep(1)
                    await self.parent.am_channel.delete()
                    
                    self.value = 1
                    self.stop()

            @ui.button(emoji=self.bot.get_emoji(853668227234529300), style=ButtonStyle.secondary, custom_id="pause")
            async def pause_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    self.parent.am_embed.set_image(url=Embed.Empty)
                    self.parent.am_embed.set_thumbnail(url=Embed.Empty)
                    self.parent.am_embed.description=localization[self.parent.language]['page_reader']['paused']
                    
                    await self.parent.active_message.edit(embed=self.parent.am_embed, view=None)

                    await sleep(2)
                    await self.parent.active_message.edit(content=f"{self.bot.get_emoji(810936543401213953)} {localization[self.parent.language]['page_reader']['closing']}", embed=None)
                    
                    await sleep(1)
                    await self.parent.am_channel.delete()
                    
                    await sleep(1)
                    self.bot.user_data["UserData"][str(self.ctx.author.id)]["Recall"] = f"{self.parent.code}*n*{self.parent.current_page}"
                    await self.ctx.author.send(embed=Embed(
                        title=localization[self.parent.language]['page_reader']['recall_saved']['title'],
                        description=localization[self.parent.language]['page_reader']['recall_saved']['description'].format(code=self.parent.code, current=self.parent.current_page+1, total=len(self.parent.images))))

                    self.value = 1
                    self.stop()

            @ui.button(emoji=self.bot.get_emoji(853668227205038090), style=ButtonStyle.secondary, custom_id="bookmark")
            async def bookmark_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    if not self.parent.on_bookmarked_page:
                        if self.parent.current_page == 0:
                            await self.parent.am_channel.send(
                                embed=Embed(
                                    color=0xFF0000,
                                    description=localization[self.parent.language]['page_reader']['cannot_bookmark_first_page']
                                ),
                                delete_after=5)
                            
                            return self.stop()

                        if len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Bookmarks|*n*|bm"]) >= 25: 
                            await self.parent.am_channel.send(
                                color=0xff0000, 
                                embed=Embed(
                                    description=localization[self.parent.language]['page_reader']['bookmarks_full']
                                ),
                                delete_after=5)

                            return self.stop()

                        self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm'][self.parent.code] = self.parent.current_page
                        self.parent.on_bookmarked_page = True
                    
                    else:
                        if self.parent.code in self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm']:
                            self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Bookmarks|*n*|bm'].pop(self.parent.code)
                            self.parent.on_bookmarked_page = False

                    self.stop()

            @ui.button(emoji="⭐", style=ButtonStyle.secondary, custom_id="favorite")
            async def favorite_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    if self.parent.code not in self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Favorites|*n*|fav']:
                        if len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["Favorites|*n*|fav"]) >= 25: 
                            await self.parent.am_channel.send(
                                embed=Embed(
                                    color=0xff0000, 
                                    description=localization[self.parent.language]['page_reader']['favorites_full']
                                ),
                                delete_after=5)

                            return self.stop()

                        self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Favorites|*n*|fav'].append(self.parent.code)

                        await self.parent.am_channel.send(
                            embed=Embed(
                                description=localization[self.parent.language]['page_reader']['added_to_favorites'].format(code=self.parent.code)
                            ),
                            delete_after=5)
                    else:
                        self.bot.user_data['UserData'][str(self.ctx.author.id)]['Lists']['Built-in']['Favorites|*n*|fav'].remove(self.parent.code)

                        await self.parent.am_channel.send(
                            embed=Embed(
                                description=localization[self.parent.language]['page_reader']['removed_from_favorites'].format(code=self.parent.code)
                            ),
                            delete_after=5)

                    self.stop()

            @ui.button(emoji=thumbnail_buttons[self.bot.user_data["UserData"][str(self.ctx.author.id)]["Settings"]["ThumbnailPreference"]], style=ButtonStyle.secondary, custom_id="thumbnail")
            async def thumbnail_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    if self.bot.user_data["UserData"][str(self.ctx.author.id)]["Settings"]["ThumbnailPreference"] == 2:
                        self.bot.user_data["UserData"][str(self.ctx.author.id)]["Settings"]["ThumbnailPreference"] = 0
                    else:
                        self.bot.user_data["UserData"][str(self.ctx.author.id)]["Settings"]["ThumbnailPreference"] += 1

                    self.stop()

            async def on_timeout(self):
                with suppress(NotFound):
                    self.parent.am_embed.set_image(url=Embed.Empty)
                    self.parent.am_embed.set_thumbnail(url=Embed.Empty)
                    self.parent.am_embed.description=localization[self.parent.language]['page_reader']['timeout'].format(current=self.parent.current_page+1, total=len(self.parent.images))

                    await self.parent.active_message.edit(embed=self.parent.am_embed, view=None)
                    temp = await self.parent.am_channel.send(content=localization[self.parent.language]['page_reader']['timeout_notification'].format(mention=self.ctx.author.mention), delete_after=1)
        
                    await sleep(10)

                    with suppress(NotFound):
                        await self.parent.active_message.edit(content=f"{self.bot.get_emoji(810936543401213953)} {localization[self.parent.language]['page_reader']['closing']}", embed=None)

                    await sleep(1)
                    await self.parent.am_channel.delete()

                self.value = 1
                self.stop()

        self.view = IPRControls(self.bot, self.ctx, self)
        self.view.add_item(ui.Button(label=localization[self.language]['page_reader']['redirect_button'], style=ButtonStyle.link, url="https://discord.gg/DJ4wdsRYy2"))
        with suppress(NotFound):
            await self.active_message.edit(embed=self.am_embed, view=self.view)
        await self.view.wait()
        return self.view.value

    async def setup(self):
        edit = await self.ctx.send(embed=Embed(
            description=f"{self.bot.get_emoji(810936543401213953)}"))

        # Fetch existing category for readers, otherwise create new
        cat = get(self.ctx.guild.categories, name="πŸ“–NReader")
        if not cat:
            cat = await self.ctx.guild.create_category_channel(name="πŸ“–NReader")
        elif not cat.permissions_for(self.ctx.guild.me).manage_roles:
            with suppress(Forbidden):
                await cat.delete()
            
            cat = await self.ctx.guild.create_category_channel(name="πŸ“–NReader")

        # Create reader channel under category
        channel = await cat.create_text_channel(name=f"πŸ“–nreader-{self.ctx.message.id}", nsfw=True)

        # Set channel permissions
        await channel.set_permissions(self.ctx.guild.me, read_messages=True)
        await channel.set_permissions(self.ctx.guild.default_role, read_messages=False)
        await channel.set_permissions(self.ctx.author, read_messages=True)

        self.am_embed = Embed(
            description=localization[self.language]['page_reader']['init']['description'])
        self.am_embed.set_author(
            name=f"{self.code} [*n*] {self.name}",
            icon_url="https://cdn.discordapp.com/emojis/845298862184726538.png?v=1")
        self.am_embed.set_footer(
            text=localization[self.language]['page_reader']['init']['footer'].format(total=len(self.images)))
        
        class Start(ui.View):
            def __init__(self, bot, ctx, parent):
                super().__init__(timeout=30)
                self.value = None
                self.bot = bot
                self.ctx = ctx
                self.parent = parent
            
            @ui.button(label=localization[self.language]["page_reader"]["init"]["button"], style=ButtonStyle.primary, emoji=self.bot.get_emoji(853674277416206387), custom_id="button1")
            async def start_button(self, button, interaction):
                if interaction.user.id == self.ctx.author.id:
                    await interaction.response.defer()

                    self.active_message = view.message

                    self.value = True
                    self.stop()

            async def on_timeout(self):
                with suppress(NotFound):
                    await view.message.edit(content=f"{self.bot.get_emoji(810936543401213953)} {localization[self.parent.language]['page_reader']['closing']}", embed=None)
            
                await sleep(1)
                
                with suppress(NotFound):
                    await view.message.channel.delete()
                
                self.value = 1
                self.stop()

        # Reader message
        view = Start(self.bot, self.ctx, self)
        self.am_channel = channel
        self.active_message = view.message = await self.am_channel.send(embed=self.am_embed, view=view)

        # Portal
        await edit.edit(
            content=self.am_channel.mention, 
            embed=Embed(
                description=localization[self.language]['page_reader']['portal'].format(code=self.code, name=self.name)
                ).set_author(
                    name=self.bot.user.name,
                    icon_url=self.bot.user.avatar.url),
            delete_after=10)

        await view.wait()
        if view.value:
            print(f"[HRB] {self.ctx.author} ({self.ctx.author.id}) started reading `{self.code}`.")
            await self.update(self.ctx)

        return view.value

    async def start(self):
        if self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["enabled"]:
            while self.code in self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"]:
                self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"].remove(self.code)

            self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"].insert(0, self.code)

            if "0" in self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"]:
                self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"].remove("0")
            
            if len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"]) >= 2 and \
                self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"][1] == self.code:
                self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"].pop(0)
            
            while len(self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"]) > 25:
                self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"].pop()

            if "0" not in self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"]:
                self.bot.user_data["UserData"][str(self.ctx.author.id)]["Lists"]["Built-in"]["History|*n*|his"]["list"].append("0")
        
        view_exit_code = 0
        while view_exit_code == 0:
            view_exit_code = await self.update(self.ctx)
Esempio n. 6
0
    async def doujin_info(self, ctx, code="random", interface="new"):
        lolicon_allowed = False
        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 not ctx.channel.is_nsfw():
            await ctx.send(embed=Embed(
                description=
                ":x: This command cannot be used in a non-NSFW channel."))

            return

        try:
            if code.lower() not in ["random", "r"]:
                code = int(code)
                code = str(code)
        except ValueError:
            await ctx.send(embed=Embed(
                description=
                ":x: You didn't type a proper ID. Hint: It has to be a number!"
            ))

            return

        nhentai_api = NHentai()
        edit = await ctx.send(embed=Embed(
            description="<a:nreader_loading:810936543401213953>"))

        if code.lower() not in ["random", "r"]:
            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 edit.edit(embed=Embed(
                    description=
                    ":mag_right::x: I did not find a doujin with that ID."))

                return

            else:
                self.bot.doujin_cache[code] = doujin

            if ("lolicon" in doujin.tags or "shotacon"
                    in doujin.tags) and ctx.guild and not lolicon_allowed:
                await edit.edit(embed=Embed(
                    description=
                    ":warning::no_entry_sign: This doujin contains lolicon/shotacon content and cannot be displayed publically."
                ))

                if not self.bot.user_data["UserData"][str(
                        ctx.author.id
                )]["Settings"]["NotificationsDue"]["LoliconViewingTip"]:
                    with suppress(Forbidden):
                        await ctx.author.send(
                            localization["eng"]["notifications_due"]
                            ["lolicon_viewing_tip"])

                    self.bot.user_data["UserData"][str(
                        ctx.author.id)]["Settings"]["NotificationsDue"][
                            "LoliconViewingTip"] = True

                return

        else:
            while True:
                doujin = await nhentai_api.get_random()
                self.bot.doujin_cache[doujin.id] = doujin
                if ("lolicon" in doujin.tags or "shotacon"
                        in doujin.tags) and ctx.guild and not lolicon_allowed:
                    await sleep(0.5)
                    continue

                else:
                    break

        # Doujin count for tags
        tags_list = []
        for tag in [tag for tag in doujin.tags if tag.type == "tag"]:
            count = tag.count
            parse_count = list(str(count))
            if len(parse_count) < 4:
                tags_list.append(f"{tag.name}[{count}]")
            elif len(parse_count) >= 4 and len(parse_count) <= 6:
                count = count / 1000
                tags_list.append(f"{tag.name}[{round(count, 1)}k]")
            elif len(parse_count) > 7:
                count = count / 1000000
                tags_list.append(f"{tag.name}[{round(count, 2)}m]")

        if interface == "old":
            emb = Embed(
                description=f"Doujin ID: __`{doujin.id}`__\n"
                f"Languages: {language_to_flag(doujin.languages)} `{', '.join([tag.name for tag in doujin.languages]) if doujin.languages else 'Not provided'}`\n"
                f"Pages: `{len(doujin.images)}`\n"
                f"Artist(s): `{', '.join([tag.name for tag in doujin.artists]) if doujin.artists else 'Not provided'}`\n"
                f"Character(s): `{', '.join([tag.name for tag in doujin.characters]) if doujin.characters else 'Original'}`\n"
                f"Parody of: `{', '.join([tag.name for tag in doujin.parodies]) if doujin.parodies else 'Original'}`\n"
                f"Tags: ```{', '.join(tags_list) if doujin.tags else 'None provided'}```"
            )
        else:
            emb = Embed()
            emb.add_field(
                inline=False,
                name="Title",
                value=
                f"`{shorten(doujin.title.pretty, width=256, placeholder='...') if doujin.title.pretty else 'Not provided'}`"
            ).add_field(
                inline=False,
                name="ID γƒΌ Pages",
                value=f"`{doujin.id} γƒΌ {len(doujin.images)}`"
            ).add_field(
                inline=False,
                name="Language(s)",
                value=
                f"{language_to_flag(doujin.languages)} `{', '.join([tag.name for tag in doujin.languages]) if doujin.languages else 'Not provided'}`"
            ).add_field(
                inline=False,
                name="Artist(s)",
                value=
                f"`{', '.join([tag.name for tag in doujin.artists]) if doujin.artists else 'Not provided'}`"
            ).add_field(
                inline=False,
                name="Character(s)",
                value=
                f"`{', '.join([tag.name for tag in doujin.characters]) if doujin.characters else 'Original'}`"
            ).add_field(
                inline=False,
                name="Parody Of",
                value=
                f"`{', '.join([tag.name for tag in doujin.parodies]) if doujin.parodies else 'Original'}`"
            ).add_field(
                inline=False,
                name="Tags",
                value=
                f"```{', '.join(tags_list) if doujin.tags else 'None provided'}```"
            )

        emb.set_author(
            name=
            f"{shorten(doujin.title.pretty, width=120, placeholder='...') if doujin.title.pretty else 'Not provided'}",
            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].src)

        print(f"[HRB] {ctx.author} ({ctx.author.id}) looked up `{doujin.id}`.")

        await edit.edit(content="", embed=emb)

        await edit.add_reaction("πŸ“–")
        await edit.add_reaction("πŸ”")

        while True:
            try:
                reaction, user = await self.bot.wait_for("reaction_add", timeout=60,
                    check=lambda r,u: r.message.id==edit.id and \
                        u.id==ctx.author.id and \
                        str(r.emoji) in ["πŸ“–", "πŸ”"])

            except TimeoutError:
                emb.set_footer(text="Provided by NHentai-API")
                emb.set_thumbnail(url=doujin.images[0].src)
                emb.set_image(url=Embed.Empty)
                await edit.edit(embed=emb)

                with suppress(Forbidden):
                    await edit.clear_reactions()

                return

            except BotInteractionCooldown:
                continue

            else:
                if str(reaction.emoji) == "πŸ“–":
                    with suppress(Forbidden):
                        await edit.clear_reactions()

                    emb.set_footer(text="Provided by NHentai-API")
                    emb.set_thumbnail(url=doujin.images[0].src)
                    emb.set_image(url=Embed.Empty)
                    await edit.edit(embed=emb)

                    session = ImagePageReader(
                        self.bot, ctx, doujin.images,
                        f"{doujin.id} [*n*] {doujin.title.pretty if doujin.title.pretty else 'Not provided'}"
                    )
                    response = await session.setup()
                    if response:
                        print(
                            f"[HRB] {ctx.author} ({ctx.author.id}) started reading `{doujin.id}`."
                        )
                        await session.start()

                    else:
                        emb.set_footer(text=Embed.Empty)
                        await edit.edit(embed=emb)

                    return

                elif str(reaction.emoji) == "πŸ”":
                    if not emb.image:
                        emb.set_image(url=emb.thumbnail.url)
                        emb.set_thumbnail(url=Embed.Empty)
                        # word = "Hide"

                    elif not emb.thumbnail:
                        emb.set_thumbnail(url=emb.image.url)
                        emb.set_image(url=Embed.Empty)
                        # word = "Minimize"

                    await edit.remove_reaction("πŸ”", ctx.author)
                    await edit.edit(content="", embed=emb)

                    continue
Esempio n. 7
0
    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}")