yor-discord-bot / cogs / anime.py
anime.py
Raw
"""This file contains the Anime Discord Cog extension.
"""
import discord
from discord.ext import commands
from discord.ui import Button, View
from datetime import datetime
from asyncio import sleep



from py_files.src.anime_libraries import anime9
from py_files.src.cog_utils.embed_pages import EmbedPages


class Anime(commands.Cog):
    """Anime handles 9Anime functionalities.
    
    Attributes:
        bot: A discord bot object.
        recent_update: A list of recently updated animes.
        recent_added: A list of recently added animes.
        release_date: A list of animes sorted by release date.
        trending: A list of trending animes.
        highest: A list of highest rated animes.
        highest_movie: A list of highest rated anime movies.
        most_watched: A list of most watched animes.
        most_favorited: A list of most favorited animes.
    """
    def __init__(self, bot) -> None:
        """Constructs an Anime Cog."""
        self.bot = bot
        # self updates every 15 mins
        self.recent_update = []
        self.recent_added = []
        self.release_date = []
        self.trending = []
        self.highest = []
        self.highest_movie = []
        self.most_watched = []
        self.most_favorited = []
    
    # @commands.Cog.listener()
    # async def on_ready(self, minutes: int=15) -> None:
    #     """Periodically updates cached anime info.
        
    #     Args:
    #         minutes: An int minute to wait for between each update cycle.
        
    #     Returns:
    #         None.
    #     """
    #     # convert to seconds
    #     t = 60 * minutes
    #     # delay time to prevent request spamming
    #     delay = 1
    #     while True:
    #         self.recent_update = self.embed_pages(
    #             anime_data=anime9.recently_updated(),
    #             title='Recently Updated Anime')
    #         await sleep(delay)
            
    #         self.recent_added = self.embed_pages(
    #             anime_data=anime9.recently_added(),
    #             title='Recently Added Anime')
    #         await sleep(delay)
            
    #         self.release_date = self.embed_pages(
    #             anime_data=anime9.release_date(),
    #             title='Newest Release')
    #         await sleep(delay)
            
    #         self.trending = self.embed_pages(
    #             anime_data=anime9.trending(),
    #             title='Currently Trending')
    #         await sleep(delay)
            
    #         self.highest_anime = self.embed_pages(
    #             anime_data=anime9.highest_rated(),
    #             title='Highest Rated Animes')
    #         await sleep(delay)
            
    #         self.highest_movie = self.embed_pages(
    #             anime_data=anime9.highest_rated_movie(),
    #             title='Highest Rated Movies')
    #         await sleep(delay)
            
    #         self.most_watched = self.embed_pages(
    #             anime_data=anime9.most_watched(),
    #             title='Most Watched')
    #         await sleep(delay)
            
    #         self.most_favorited = self.embed_pages(
    #             anime_data=anime9.most_favorited(),
    #             title='Most Favorited')
    #         # print status to console
    #         update_time = datetime.now().strftime('%d/%m/%Y %H:%M:%S')
    #         print(f'[UPDATE] 9Anime Cache - {update_time}')
    #         await sleep(t)

    @commands.command(name='anime')
    async def anime_master(self, ctx, *, args) -> None:
        """Handles sending the appropriate Discord Embed from the user's input.
        
        Args:
            ctx: Discord context.
            args: User input.
            
        Returns: 
            None.
        """
        # latest update 
        if not args or 'up' in args:
            await self.handle_embeds(ctx, self.recent_update.copy())
        # newest added
        elif 'add' in args:
            await self.handle_embeds(ctx, self.recent_added.copy())
        # latest release
        elif 'release' in args:
            await self.handle_embeds(ctx, self.release_date.copy())
        # trending
        elif 'trend' in args:
            await self.handle_embeds(ctx, self.trending.copy())
        # top rated movie
        elif 'movie' in args:
            await self.handle_embeds(ctx, self.highest_movie.copy())
        # top rated anime
        elif 'top' in args:
            await self.handle_embeds(ctx, self.highest_anime.copy())
        # most watched
        elif 'watch' in args:
            await self.handle_embeds(ctx, self.most_watched.copy())
        # most favorited
        elif 'fav' in args:
            await self.handle_embeds(ctx, self.most_favorited.copy())
        # latest update (default)
        else:
            await ctx.send('Huh?')
            
    async def handle_embeds(self, ctx, pages: EmbedPages) -> None:
        """Handles sending and caching EmbedPages objects.
        
        Args:
            ctx: A discord context. 
            pages: An EmbedPages containing discord embeds.
            
        Returns:
            None.
        """
        if len(pages) > 0:
            # send first page of bookmarked
            try:
                msg = await ctx.send(embed=pages.get_embed())
            except discord.Forbidden:
                try:
                    await ctx.send("Hey, seems like I can't send embeds. Please check my permissions :(")
                except discord.Forbidden:
                    await ctx.author.send(
                        f"Hey, seems like I can't send any message in {ctx.channel.name} on {ctx.guild.name}\n"
                        f"May you inform the server team about this issue? :slight_smile: ", embed=pages.get_embed)
            await self.add_nav(msg)
            # cache embed
            self.bot.nav_cache[msg.id] = pages
        else:
            await ctx.send("Hmm, can't seem to find anything.")

    def embed_pages(self, anime_data: tuple, title: str) -> EmbedPages:
        """Returns an EmbedPages from the given data.
        
        Args:
            anime_data: A tuple of anime information.
            title: A str title for the embed.
        
        Returns:
            An EmbedPages object for the given anime list.
        """
        anime_list, anime9_url, time_updated = anime_data
        pages = []
        for count, anime in enumerate(anime_list):
            # build embed
            r, g, b = (250, 210, 221)
            embed_d = {'title': title,'url': anime9_url}
            embed = discord.Embed.from_dict(embed_d)
            embed.add_field(name=anime['name'], value=f'[{anime["url"]}]({anime["url"]})')
            embed.set_image(url=anime['img'])
            foot = f'Pages: {count+1}/{len(anime_list)} | {time_updated}'
            embed.set_footer(text=foot)
            embed.color = discord.Color.from_rgb(r, g, b)
            pages.append(embed)
        return EmbedPages(pages)

    async def add_nav(self, msg: discord.Message) -> None:
        """Adds navigation reactions to the given discord message.
        """
        await msg.add_reaction(self.bot.reactions['leftarrow'])
        await msg.add_reaction(self.bot.reactions['rightarrow'])

async def setup(bot):
    await bot.add_cog(Anime(bot))