async def themes(self, ctx: Context, *, anime: str): """ Searches for the openings and endings of the given anime and displays them. """ async with ctx.channel.typing(): data = await self.bot.animethemes.search(anime, 5, ['anime']) if data.get('search').get('anime'): embeds = [] for page, entry in enumerate(data.get('search').get('anime')): try: embed = await self.get_themes_embed(entry, page + 1, len(data.get('search').get('anime'))) if is_adult(entry.get('themes')[0]['entries'][0]): if not ctx.channel.is_nsfw(): embed = discord.Embed(title='Error', color=ERROR_EMBED_COLOR, description=f'Adult content. No NSFW channel.') embed.set_footer( text=f'Provided by https://animethemes.moe/ • Page {page + 1}/' f'{len(data.get("search").get("anime"))}') except Exception as e: log.exception(e) embed = discord.Embed( title='Error', color=ERROR_EMBED_COLOR, description=f'An error occurred while loading the embed for the anime.') embed.set_footer( text=f'Provided by https://animethemes.moe/ • Page ' f'{page + 1}/{len(data.get("search").get("anime"))}') embeds.append(embed) menu = menus.MenuPages(source=EmbedListMenu(embeds), clear_reactions_after=True, timeout=30) await menu.start(ctx) else: embed = discord.Embed(title=f'No themes for the anime `{anime}` found.', color=ERROR_EMBED_COLOR) await ctx.channel.send(embed=embed)
async def last(self, ctx: Context): """ Displays the most recently aired anime episodes. """ async with ctx.channel.typing(): try: data = await self.bot.anilist.schedule(page=1, perPage=15, notYetAired=False, sort='TIME_DESC') except Exception as e: log.exception(e) embed = discord.Embed( title= f'An error occurred while searching for the most recently aired episodes. Try again.', color=ERROR_EMBED_COLOR) return await ctx.channel.send(embed=embed) if data is not None and len(data) > 0: embeds = [] for page, anime in enumerate(data): try: embed = await self.get_last_embed( anime, page + 1, len(data)) if is_adult(anime.get('media')): if not ctx.channel.is_nsfw(): embed = discord.Embed( title='Error', color=ERROR_EMBED_COLOR, description= f'Adult content. No NSFW channel.') embed.set_footer( text= f'Provided by https://anilist.co/ • Page {page + 1}/{len(data)}' ) except Exception as e: log.exception(e) embed = discord.Embed( title='Error', color=ERROR_EMBED_COLOR, description= f'An error occurred while loading the embed for the recently aired episode.' ) embed.set_footer( text= f'Provided by https://anilist.co/ • Page {page + 1}/{len(data)}' ) embeds.append(embed) menu = menus.MenuPages(source=EmbedListMenu(embeds), clear_reactions_after=True, timeout=30) await menu.start(ctx) else: embed = discord.Embed( title= f'The most recently aired episodes could not be found.', color=ERROR_EMBED_COLOR) await ctx.channel.send(embed=embed)
async def theme(self, ctx: Context, theme: str, *, anime: str): """ Displays a specific opening or ending of the given anime. """ async with ctx.channel.typing(): data = await self.bot.animethemes.search(anime, 1, ['anime']) if data.get('search').get('anime'): anime_ = data.get('search').get('anime')[0] for entry in anime_.get('themes'): if theme.upper() == entry.get('slug') or \ (theme.upper() == 'OP' and entry.get('slug') == 'OP1') or \ (theme.upper() == 'ED' and entry.get('slug') == 'ED1') or \ (theme.upper() == 'OP1' and entry.get('slug') == 'OP') or \ (theme.upper() == 'ED1' and entry.get('slug') == 'ED'): try: embed = await self.get_theme_embed(anime_, entry) if is_adult(entry.get('entries')[0]): if not ctx.channel.is_nsfw(): embed = discord.Embed(title='Error', color=ERROR_EMBED_COLOR, description=f'Adult content. No NSFW channel.') embed.set_footer(text=f'Provided by https://animethemes.moe/') return await ctx.channel.send(embed=embed) except Exception as e: log.exception(e) embed = discord.Embed( title='Error', color=ERROR_EMBED_COLOR, description=f'An error occurred while loading the embed for the theme.') embed.set_footer( text=f'Provided by https://animethemes.moe/') await ctx.channel.send(embed=embed) return await ctx.channel.send( f'http://animethemes.moe/video/{entry.get("entries")[0]["videos"][0]["basename"]}') embed = discord.Embed( title=f'Cannot find `{theme.upper()}` for the anime `{anime}`.', color=ERROR_EMBED_COLOR) await ctx.channel.send(embed=embed) else: embed = discord.Embed(title=f'No theme for the anime `{anime}` found.', color=ERROR_EMBED_COLOR) await ctx.channel.send(embed=embed)
async def trace(self, ctx: Context, trace: Optional[str] = None): """ Tries to find the anime the image is from through the image url or the image as attachment. """ async with ctx.channel.typing(): url = None if trace is None: if ctx.message.attachments: url = ctx.message.attachments[0].url else: embed = discord.Embed( title='No image to look for the anime.', color=ERROR_EMBED_COLOR) await ctx.channel.send(embed=embed) ctx.command.reset_cooldown(ctx) else: url = trace if url: if not url.lower().endswith( ('.jpg', '.png', '.bmp', '.jpeg', '.gif')): embed = discord.Embed( title= 'No correct url specified (`.jpg`, `.png`, `.bmp`, `.jpeg`, `.gif`).', color=ERROR_EMBED_COLOR) await ctx.channel.send(embed=embed) ctx.command.reset_cooldown(ctx) else: try: data = await self.bot.tracemoe.search(url) except Exception as e: log.exception(e) embed = discord.Embed( title= f'An error occurred while searching for the anime or the link is invalid.', color=ERROR_EMBED_COLOR) return await ctx.channel.send(embed=embed) if data: embeds = [] for page, anime in enumerate(data): try: embed = await self.get_trace_embed( anime, page + 1, len(data)) if is_adult(anime): if not ctx.channel.is_nsfw(): embed = discord.Embed( title='Error', color=ERROR_EMBED_COLOR, description= f'Adult content. No NSFW channel.') embed.set_footer( text= f'Provided by https://trace.moe/ • Page {page + 1}/{len(data)}' ) except Exception as e: log.exception(e) embed = discord.Embed( title='Error', color=DEFAULT_EMBED_COLOR, description= 'An error occurred while loading the embed.' ) embed.set_footer( text= f'Provided by https://trace.moe/ • Page {page + 1}/{len(data.get("docs"))}' ) embeds.append(embed) menu = menus.MenuPages(source=EmbedListMenu(embeds), clear_reactions_after=True, timeout=30) await menu.start(ctx) else: embed = discord.Embed(title='No anime found.', color=ERROR_EMBED_COLOR) await ctx.channel.send(embed=embed)
async def anilist_search(self, ctx: Context, search: str, type_: AniListSearchType) -> Union[List[Embed], None]: """ Returns a list of Discord embeds with the retrieved anilist data about the searched entry. Args: ctx (Context): The context in which the command was invoked under. search (str): The entry to be searched for. type_ (AniListSearchType): The type to be searched for (`ANIME`, `MANGA`, `CHARACTER`, `STAFF`, `STUDIO`). Returns: list (Embed): A list of discord embeds. None: If no entries were found. """ embeds = [] data = None try: if type_ == AniListSearchType.ANIME: data = await self.bot.anilist.media(search=search, page=1, perPage=15, type=type_.value) elif type_ == AniListSearchType.MANGA: data = await self.bot.anilist.media(search=search, page=1, perPage=15, type=type_.value) elif type_ == AniListSearchType.CHARACTER: data = await self.bot.anilist.character(search=search, page=1, perPage=15) elif type_ == AniListSearchType.STAFF: data = await self.bot.anilist.staff(search=search, page=1, perPage=15) elif type_ == AniListSearchType.STUDIO: data = await self.bot.anilist.studio(search=search, page=1, perPage=15) except Exception as e: log.exception(e) embed = discord.Embed( title=f'An error occurred while searching for the {type_.value.lower()} `{search}`. Try again.', color=ERROR_EMBED_COLOR) embeds.append(embed) return embeds if data is not None: for page, entry in enumerate(data): embed = None try: if type_ == AniListSearchType.ANIME: embed = await self.get_media_embed(entry, page + 1, len(data)) elif type_ == AniListSearchType.MANGA: embed = await self.get_media_embed(entry, page + 1, len(data)) elif type_ == AniListSearchType.CHARACTER: embed = await self.get_character_embed(entry, page + 1, len(data)) elif type_ == AniListSearchType.STAFF: embed = await self.get_staff_embed(entry, page + 1, len(data)) elif type_ == AniListSearchType.STUDIO: embed = await self.get_studio_embed(entry, page + 1, len(data)) if is_adult(entry): if not ctx.channel.is_nsfw(): embed = discord.Embed(title='Error', color=ERROR_EMBED_COLOR, description=f'Adult content. No NSFW channel.') embed.set_footer(text=f'Provided by https://anilist.co/ • Page {page + 1}/{len(data)}') except Exception as e: log.exception(e) embed = discord.Embed( title='Error', color=ERROR_EMBED_COLOR, description=f'An error occurred while loading the embed for the {type_.value.lower()}.') embed.set_footer(text=f'Provided by https://anilist.co/ • Page {page + 1}/{len(data)}') embeds.append(embed) return embeds return None
async def anilist_random(self, ctx: Context, search: str, type_: AniListMediaType, format_in: List[str]) \ -> Union[Embed, None]: """ Returns a Discord embed with the retrieved anilist data about a random media of a specified genre. Args: ctx (Context): The context in which the command was invoked under. search (str): The media genre to be searched for. type_ (AniListMediaType): The media search type (`ANIME`, `MANGA`). format_in (list): The media format. Returns: Embed: A discord embed. None: If no entry was found. """ try: data = await self.bot.anilist.genre(genre=search, page=1, perPage=1, type=type_.value, format_in=format_in) if data.get('data')['Page']['media'] is not None and len(data.get('data')['Page']['media']) > 0: page = random.randrange(1, data.get('data')['Page']['pageInfo']['lastPage']) data = await self.bot.anilist.genre(genre=search, page=page, perPage=1, type=type_.value, format_in=format_in) else: data = await self.bot.anilist.tag(tag=search, page=1, perPage=1, type=type_.value, format_in=format_in) if data.get('data')['Page']['media'] is not None and len(data.get('data')['Page']['media']) > 0: page = random.randrange(1, data.get('data')['Page']['pageInfo']['lastPage']) data = await self.bot.anilist.tag(tag=search, page=page, perPage=1, type=type_.value, format_in=format_in) else: return None except Exception as e: log.exception(e) embed = discord.Embed( title=f'An error occurred while searching for a {type_.value.lower()} with the genre `{search}`.', color=ERROR_EMBED_COLOR) return embed if data.get('data')['Page']['media'] is not None and len(data.get('data')['Page']['media']) > 0: try: embed = await self.get_media_embed(data.get('data')['Page']['media'][0]) if is_adult(data.get('data')['Page']['media'][0]): if not ctx.channel.is_nsfw(): embed = discord.Embed(title='Error', color=ERROR_EMBED_COLOR, description=f'Adult content. No NSFW channel.') except Exception as e: log.exception(e) embed = discord.Embed( title=f'An error occurred while searching for a {type_.value.lower()} with the genre `{search}`.', color=ERROR_EMBED_COLOR) return embed return None