Exemple #1
0
 def __init__(self, bot):
     self.bot = bot
     self.logger = logging.getLogger("TempleBot.weeb")
     self.british_timezone = pytz.timezone('Europe/London')
     self.logger.info("Opening MAL API event loop.")
     self.jikan_aio = AioJikan()
     self.cog_config = self.bot.get_cog_config("anime_manga_search_config")
     self.message_reaction_waiting_h_table = {}
     self.current_mal_req_count_ps = 0
     self.current_mal_req_count_pm = 0
Exemple #2
0
 async def weeb_search_command(self, ctx):
     ctx.message.content = ctx.message.content.strip(self.bot.command_prefix).strip("weeb_search ")
     try:
         await self.anime_title_request_func(ctx.message, ctx.message)
     except jikanpy.exceptions.APIException:
         self.logger.exception("jikanpy.exceptions.APIException raised, attempting API "
                               "restart.")
         await self.jikan_aio.close()
         self.jikan_aio = AioJikan()
         await self.anime_title_request_func(ctx.message, ctx.message)
     asyncio.create_task(self.mal_rate_limit_down_counter())
Exemple #3
0
async def search(ctx, search: str):
    async with AioJikan() as aio_jikan:
        userResult = await aio_jikan.search(search_type='anime', query=search)
        userResult = userResult['results'][0]
    userEmbed = discord.Embed(title=userResult['title'], url=userResult['url'], description=userResult['synopsis'])
    userEmbed.set_thumbnail(url=userResult['image_url'])
    await ctx.send("Here you go!", embed=userEmbed)
Exemple #4
0
async def mal_character(event):
    """Search anime characters from Kantek itself
       Powered by jikan.moe

    Examples:
        {cmd} command
    """
    async with AioJikan() as jikan:
        sr = await jikan.search('character', event.text.split(" ", 1))
        c = await jikan.character(sr['results'][0]['mal_id'])
    if not c:
        await event.reply('err \\\nNo results found')
        return
    text = f'<b>{html.escape(c["name"])}'
    if c['name_kanji']:
        text += f' ({html.escape(c["name_kanji"])})'
    text += '</b>\n'
    about = html.escape(c['about'].replace('\\n', ''))
    text += f'<i>{about}</i>\n'
    pic = f'{c["image_url"]}'
    url = f'<a href="{html.escape(c["url"])}">read more</a>'
    text = text.strip()
    if len(text) > 1024:
        text = text[0:500] + ".... "
    text = text + url
    try:
        await event.reply(text,
                          file=pic,
                          link_preview=False,
                          parse_mode='html')
    except BaseException:
        await event.reply(text, link_preview=False, parse_mode='html')
Exemple #5
0
async def mal_manga(e):
    await e.edit('Searching...')
    await e.delete()
    async with AioJikan() as jikan:
        sr = await jikan.search('manga', e.pattern_match.group(1))
        m = await jikan.manga(sr['results'][0]['mal_id'])
    if not m:
        await e.reply('err \\\nNo results found')
        return
    text = f'<b>{html.escape(m["title"])}'
    if m['title_japanese']:
        text += f' ({html.escape(m["title_japanese"])})'
    text += '</b>\n'
    text += f'<b>Score:</b> {m["score"]}\n'
    text += f'<b>Type:</b> {html.escape(m["type"])}\n'
    text += f'<b>Genres:</b> {", ".join([html.escape(i["name"]) for i in m["genres"]])}\n'
    text += f'<b>Status:</b> {html.escape(m["status"])}\n'
    if m['volumes']:
        text += f'<b>Volumes:</b> {m["volumes"]}\n'
    if m['chapters']:
        text += f'<b>Chapters:</b> {m["chapters"]}\n'
    text += f'<i>{html.escape(m["synopsis"])}</i>\n'
    pic = f'{m["image_url"]}'
    url = f'<a href="{html.escape(m["url"])}">read more</a>'
    text = text.strip()
    if len(text) > 1024:
        text = text[0:500] + ".... "
    text = text + url
    await e.reply(text, file=pic, link_preview=False, parse_mode='html')
Exemple #6
0
    async def manga(self, ctx, *, query):
        jikan = AioJikan()

        try:
            result = await jikan.search("manga", query)
        except APIException:
            await ctx.send("Problem connecting to the API. Please try again.")
            await jikan.close()
            return

        #taking first result for now
        if len(result["results"]) > 0:
            result = result["results"][0]
        else:
            await ctx.send(f"No results for <{query}>.")
            await jikan.close()
            return

        try:
            manga = await jikan.manga(result.get("mal_id"))
        except APIException:
            await ctx.send("Problem connecting to the API. Please try again.")
            await jikan.close()
            return

        title = manga.get("title")
        title_japanese = manga.get("title_japanese")
        url = manga.get("url")
        image = manga.get("image_url")
        synopsis = manga.get("synopsis")
        published = manga["published"].get("string")
        score = manga.get("score")
        broadcast = "N/A"
        if (chapters := manga.get("chapters")) is None:
            chapters = "N/A"
async def main(loop):
    aio_jikan = AioJikan(loop=loop)

    mushishi = await aio_jikan.anime(457)
    # Close the connection to Jikan API
    # print(mushishi)
    # usernames = ['juanjg', 'thundersly', 'terabyte900']
    # jj = await aio_jikan.user(username='******', request='animelist')
    # jj = await aio_jikan.user(username='******')
    # top_anime = await aio_jikan.top(type='anime')
    # try:

    mushishi = await aio_jikan.anime(15000)
    # except:
    #     mushishi = await aio_jikan.anime(1)

    animes_data = []
    # for i in range (5):
    #     animes_data[i]= await aio_jikan.anime(i)

    # jj.keys()
    # print(mushishi)
    print(mushishi.keys())
    # print(mushishi['source'])
    # print(mushishi['related']['Adaptation'])

    # print(mushishi['studios'])

    await aio_jikan.close()
Exemple #8
0
async def main():
    async with AioJikan() as aio_jikan:
        mushishi = await aio_jikan.anime(457)
        pprint(mushishi)

        fma = await aio_jikan.manga(25)
        pprint(fma)

        ginko = await aio_jikan.character(425)
        pprint(ginko)

        naruto = await aio_jikan.search(search_type="anime", query="naruto")
        pprint(naruto)

        winter_2018 = await aio_jikan.season(year=2018, season="winter")
        pprint(winter_2018)

        monday = await aio_jikan.schedule(day="monday")
        pprint(monday)

        top_anime = await aio_jikan.top(type="anime")
        pprint(top_anime)

        meta = await aio_jikan.meta(request="requests",
                                    type="anime",
                                    period="today")
        pprint(meta)
Exemple #9
0
    async def anime(self, ctx, *, query: str):
        _jikan = AioJikan()
        while len(query) < 3:
            query += ' '

        async with ctx.typing():
            try:
                search = await _jikan.search(search_type='anime', query=query)
                anime = await _jikan.anime(id=search['results'][0]['mal_id'])

                title = anime[
                    'title_english'] + f" ({anime['title_japanese']})" if anime[
                        'title_japanese'] and anime[
                            'title_english'] else anime['title']
                desc = anime['synopsis'] if anime['synopsis'] and len(
                    anime['synopsis']
                ) < 1024 else anime['synopsis'][0:1021] + '...'
                rank = '#' + str(anime['rank'])
                popularity = '#' + str(anime['popularity'])
                genres = ', '.join(
                    [genre['name'] for genre in anime['genres']])

                anime_embed = Embed(color=0x00f00,
                                    title=title,
                                    url=anime['url'])
                anime_embed.set_thumbnail(url=anime['image_url'])
                anime_embed.add_field(name='Synopsis',
                                      value=desc,
                                      inline=False)
                anime_embed.add_field(name='Episode', value=anime['episodes'])
                anime_embed.add_field(name='Score', value=anime['score'])
                anime_embed.add_field(name='Ranking', value=rank)
                anime_embed.add_field(name='Popularity', value=popularity)
                anime_embed.add_field(name='Rating', value=anime['rating'])
                anime_embed.add_field(name='Aired',
                                      value=anime['aired']['string'])
                anime_embed.add_field(name='Genre', value=genres, inline=False)

                if anime['opening_themes']:
                    op_list = split_eps([op for op in anime['opening_themes']])
                    op_inline = '\n'.join(op_list)
                    anime_embed.add_field(name='Opening',
                                          value=op_inline[0:1024],
                                          inline=False)

                if anime['ending_themes']:
                    ed_list = split_eps([ed for ed in anime['ending_themes']])
                    ed_inline = '\n'.join(ed_list)
                    anime_embed.add_field(name='Ending',
                                          value=ed_inline[0:1024],
                                          inline=False)

                result = await ctx.send(embed=anime_embed)
            except APIException:
                result = await ctx.send(embed=wibu_404('Anime'))
            finally:
                await result.add_reaction('❗')
                await _jikan.close()
Exemple #10
0
async def anime_list(session, username):
    global jikan
    if jikan is None:
        jikan = AioJikan(session=session)
    d = await jikan.user(username, "animelist", "completed")
    return [
        Anime(x["title"], int(x["start_date"].split("-")[0]))
        for x in d["anime"]
    ]
Exemple #11
0
    def __init__(self,
                 config: ConfigBox,
                 *,
                 context: commands.Context = SubContext,
                 **kwargs):
        """
        :param config: Config parser object
        :param context: Context factory to use
        """
        super().__init__(
            command_prefix=kwargs.pop("command_prefix",
                                      self.get_command_prefix),
            case_insensitive=kwargs.pop("case_insensitive", True),
            max_messages=kwargs.pop("max_messages", 10_000),
            help_command=kwargs.pop("help_command", Minimal()),
            allowed_mentions=kwargs.pop(
                "allowed_mentions",
                discord.AllowedMentions(everyone=False,
                                        roles=False,
                                        users=False),
            ),
            activity=discord.Activity(
                type=discord.ActivityType.listening,
                name=f"{config.general.prefix}help",
            ),
            **kwargs,
        )
        self.config = config
        self.context = context
        self.jikan = AioJikan()
        self.ready_once = False
        self.uptime = datetime.now()
        # Todo: make an anime entry object to replace the dicts in the lists
        self.anime_db: Dict[str, list] = {}
        # {user_id: reason}
        self.blacklist: Dict[int, Optional[str]] = {}
        # {bot_id: {prefixes}}
        self.other_bot_prefixes: Dict[int,
                                      Set[str]] = defaultdict(lambda: set())
        # {guild_id: {prefixes}}
        self.prefixes: Dict[int, Set[str]] = defaultdict(
            lambda: {config.general.prefix})
        # {send_from: {send_to}}
        self.channel_links: Dict[discord.TextChannel,
                                 Set[discord.TextChannel]] = defaultdict(
                                     lambda: set())
        # {guild_id: {channel_id: deque[Snipe]}}
        self.snipes: Dict[int, Dict[int, Deque[Snipe]]] = defaultdict(
            lambda: defaultdict(lambda: deque(maxlen=5_000)))

        if config.extra_tokens.emote_collector:
            self.ec = EcClient(token=config.extra_tokens.emote_collector)

        else:
            self.ec = None

        self.add_check(self.blacklist_check)
Exemple #12
0
async def test_containing_db(loop):
    async def write_data_to_db(record, recid, tags, db=None):

        await db.insert_to_table('records', record)
        for tag in tags:
            try:
                await db.insert_to_table('tags', {'tagname': tag},
                                         ignore_conflict=[
                                             'tagname',
                                         ])
            except UniqueViolationError:
                pass
            try:
                await db.insert_to_table('records_tags', {
                    'tagname': tag,
                    'recordid': recid
                })
            except UniqueViolationError:
                pass

    aio_jikan = AioJikan(loop=loop)

    cfg = Config()
    pg_pool = await asyncpg.create_pool(cfg.DB_ADDRESS)
    db = DbHandler(pg_pool=pg_pool, cfg=cfg)

    year_2000 = 2000
    seasons = ['winter', 'spring', 'summer', 'fall']

    for year in range(2015, 2019):
        for season in seasons:

            print(f'[+] reading {season} in {year}')

            season_year = await aio_jikan.season(year=year, season=season)

            for item in season_year['anime']:
                title = item['title']
                title_tag = ('_'.join(re.findall(r'\W?(\w+)\W?',
                                                 title))).lower()
                recid = recid_gen()
                record = {
                    'recordid': recid,
                    'username': '******',
                    'record_headline': title,
                    'record_text': f'{title} ({season} {year})'
                }
                tags = [title_tag, str(year), season]
                await write_data_to_db(record, recid, tags, db=db)

    await aio_jikan.close()
    await pg_pool.close()
Exemple #13
0
async def anime(client, message, *args):
    if len(args) == 0:
        await message.channel.send(f"Usage: {PREFIX}anime <anime name>")
        return
    search_str = " ".join(args)
    if len(search_str) < 3:
        await message.channel.send("Anime name must be atleast 3 letters.")
        return
    jikan = AioJikan()
    _search_result = await jikan.search(search_type="anime", query=search_str)
    search_result = _search_result["results"][0]["mal_id"]
    embed = await make_anime_embed(client.loop, search_result, message.author.color)
    await message.channel.send(embed=embed)
Exemple #14
0
    async def character(self, ctx, *, query: str):
        _jikan = AioJikan()
        while len(query) < 3:
            query += ' '

        try:
            async with ctx.typing():
                search = await _jikan.search(search_type='character',
                                             query=query)
                char = await _jikan.character(search['results'][0]['mal_id'])

                title = char[
                    'name'] + f" ({', '.join(char['nicknames'])})" if char[
                        'nicknames'] else char['name']
                about = clean(char['about'])
                about = about if len(about) < 1024 else about[0:1021] + '...'
                anime = '\n'.join([
                    role['name'] + f" ({role['role']})"
                    for role in char['animeography']
                ]) if char['animeography'] else '-'
                manga = '\n'.join([
                    role['name'] + f" ({role['role']})"
                    for role in char['mangaography']
                ]) if char['mangaography'] else '-'
                seiyuu = '\n'.join([
                    person['name'] + f" ({person['language']})"
                    for person in char['voice_actors']
                ]) if char['voice_actors'] else '-'

                char_embed = Embed(color=0x00ff00,
                                   title=title,
                                   url=char['url'])
                char_embed.set_image(url=char['image_url'])
                char_embed.add_field(name='About', value=about, inline=False)
                char_embed.add_field(name='Anime',
                                     value=anime[0:1024],
                                     inline=False)
                char_embed.add_field(name='Manga',
                                     value=manga[0:1024],
                                     inline=False)
                char_embed.add_field(name='Seiyuu', value=seiyuu, inline=False)

                result = await ctx.send(embed=char_embed)
        except APIException:
            result = await ctx.send(embed=wibu_404('Karakter'))
        finally:
            await result.add_reaction('❗')
            await _jikan.close()
Exemple #15
0
async def mal_upcoming(c: Korone, m: Message):
    async with AioJikan() as jikan:
        pass

    upcoming = await jikan.top("anime", page=1, subtype="upcoming")
    await jikan.close()

    upcoming_list = [entry["title"] for entry in upcoming["top"]]
    upcoming_message = "<b>Próximos animes:</b>\n"

    for entry_num in range(len(upcoming_list)):
        if entry_num == 10:
            break
        upcoming_message += f"<b>{entry_num + 1}.</b> {upcoming_list[entry_num]}\n"

    await m.reply_text(upcoming_message)
Exemple #16
0
 async def anime(self, ctx, *, query):
     async with AioJikan() as a:
         naruto = await a.search(search_type='anime', query=query)
     res = naruto['results'][0]
     o = []
     embed = discord.Embed(color=self.bot.colour)
     embed.set_thumbnail(url=res['image_url'])
     embed.title = f"{res['title']}"
     embed.url = f"{res['url']}"
     embed.description = f"{naruto['results'][0]['synopsis']}"
     embed.add_field(name="Info",
                     value=f"Type | **{res['type']}**\n📺 | **{res['episodes']}**\n:star:️ | **{res['score']}**\n<:member:731190477927219231> | **{res['members']:,}**")
     for x in range(2, len(naruto['results'])):
         o.append(f"**{naruto['results'][x]['title']}**")
     embed.add_field(name="Other Entries", value=f"\n".join(o[:5]))
     await ctx.send(embed=embed)
Exemple #17
0
async def upcoming(message):
    async with AioJikan() as jikan:
        pass

    upcoming = await jikan.top("anime", page=1, subtype="upcoming")
    await jikan.close()

    upcoming_list = [entry["title"] for entry in upcoming["top"]]
    upcoming_message = ""

    for entry_num in range(len(upcoming_list)):
        if entry_num == 10:
            break
        upcoming_message += f"{entry_num + 1}. {upcoming_list[entry_num]}\n"

    await message.reply(upcoming_message)
Exemple #18
0
    async def anime_search(self, ctx: commands.Context, *,
                           keyword: str) -> None:
        """Searches for anime information."""

        loading_msg = await ctx.send(embed=Embed("Searching..."))

        jikan = AioJikan()
        results = (await jikan.search(search_type="anime",
                                      query=keyword))['results']

        if not results:
            await ctx.send(embed=Embed("Anime not found."), delete_after=5)
            return

        anime = await jikan.anime(results[0]['mal_id'])
        await jikan.close()

        if anime['title_english'] and not anime['title_japanese']:
            title = anime['title_english']
        elif not anime['title_english'] and anime['title_japanese']:
            title = anime['title_japanese']
        else:
            title = f"{anime['title_english']} ({anime['title_japanese']})"

        embed = Embed()
        embed.set_author(name=title, url=anime['url'])
        embed.set_thumbnail(url=anime['image_url'])
        embed.set_footer(
            text="Powered by MyAnimeList",
            icon_url=ICONS['myanimelist'],
        )
        embed.add_field(
            name="Synopsis",
            value=anime['synopsis'][:1000] +
            "..." if len(anime['synopsis']) > 1000 else anime['synopsis'],
            inline=False)
        embed.add_field("Episodes", anime['episodes'])
        embed.add_field("Rank", anime['rank'])
        embed.add_field("Status", anime['status'])
        embed.add_field("Aired", anime['aired']['string'])
        embed.add_field(
            "Genres", ", ".join([genre['name'] for genre in anime['genres']]))

        await self.bot.delete_message(loading_msg)
        await ctx.send(embed=embed)
Exemple #19
0
 async def mal(self, ctx, *, anime):
     jikan = AioJikan(loop=asyncio.get_event_loop())
     result = await jikan.search(search_type='anime', query=anime)
     await jikan.close()
     img_url = result['results'][0]['image_url']
     title = result['results'][0]['title']
     desc = result['results'][0]['synopsis']
     episode_count = result['results'][0]['episodes']
     score = result['results'][0]['score']
     url = result['results'][0]['url']
     embed = discord.Embed(colour=discord.Colour.from_rgb(46, 81, 162),
                           url=url,
                           title=title,
                           description=desc)
     embed.add_field(name='Episodes:', value=episode_count, inline=False)
     embed.add_field(name='Score:', value=score, inline=False)
     embed.set_thumbnail(url=img_url)
     await ctx.send(embed=embed)
Exemple #20
0
    async def manga(self, ctx, *, query: str):
        _jikan = AioJikan()
        while len(query) < 3:
            query += ' '

        try:
            async with ctx.typing():
                search = await _jikan.search(search_type='manga', query=query)
                manga = await _jikan.manga(search['results'][0]['mal_id'])

                title = manga[
                    'title'] + f" ({manga['title_japanese']})" if manga[
                        'title_japanese'] else manga['title']
                synopsis = manga['synopsis'] if manga['synopsis'] and len(
                    manga['synopsis']
                ) < 1024 else manga['synopsis'][0:1021] + '...'
                rank = '#' + str(manga['rank'])
                popularity = '#' + str(manga['popularity'])
                genres = ', '.join(
                    [genre['name'] for genre in manga['genres']])

                manga_embed = Embed(title=title, url=manga['url'])
                manga_embed.set_thumbnail(url=manga['image_url'])
                manga_embed.add_field(name='Synopsis',
                                      value=synopsis,
                                      inline=False)
                manga_embed.add_field(name='Status', value=manga['status'])
                manga_embed.add_field(name='Total Volumes' if manga['status']
                                      == 'Finished' else 'Latest Volume',
                                      value=manga['volumes'])
                manga_embed.add_field(name='Total Chapters' if manga['status']
                                      == 'Finished' else 'Latest Chapter',
                                      value=manga['chapters'])
                manga_embed.add_field(name='Score', value=manga['score'])
                manga_embed.add_field(name='Ranking', value=rank)
                manga_embed.add_field(name='Popularity', value=popularity)
                manga_embed.add_field(name='Genre', value=genres, inline=False)

                result = await ctx.send(embed=manga_embed)
        except APIException:
            result = await ctx.send(embed=wibu_404('Manga'))
        finally:
            await result.add_reaction('❗')
            await _jikan.close()
Exemple #21
0
async def manga(client, message, *args):
    if len(args) == 0:
        await message.channel.send(f"Usage: {PREFIX}manga <manga name>")
        return
    search_str = " ".join(args)
    if len(search_str) < 3:
        await message.channel.send("Manga name must be atleast 3 letters.")
        return
    jikan = AioJikan()
    _search_result = await jikan.search(search_type="manga", query=search_str)
    search_result = _search_result["results"][0]["mal_id"]
    manga = await jikan.manga(search_result)
    synopsis = manga["synopsis"]
    if len(synopsis) > 1500:
        synopsis = synopsis[:1500] + "..."
    embed = discord.Embed(
        title=manga["title"],
        description=synopsis,
        url=manga["url"],
        color=message.author.colour,
    )
    if "image_url" in manga.keys() and manga["image_url"]:
        embed.set_image(url=manga["image_url"])
    embed.add_field(name="Type", value=manga["type"])
    embed.add_field(
        name="Chapters", value=f"{manga['chapters']} ({manga['volumes']} volumes)"
    )
    embed.add_field(name="Status", value=manga["status"])
    embed.add_field(name="Published", value=manga["published"]["string"])
    embed.add_field(name="Rank", value=manga["rank"])
    embed.add_field(
        name="Score", value=f"{manga['score']} by {manga['scored_by']} members"
    )
    genres = ", ".join([g["name"] for g in manga["genres"]])
    embed.add_field(name="Genres", value=genres, inline=True)
    if "Adaptation" in manga["related"].keys():
        adaptations = ", ".join(
            [f"{i['name']} ({i['type']})" for i in manga["related"]["Adaptation"]]
        )
        embed.add_field(name="Adaptations", value=adaptations, inline=True)
    embed.set_footer(text="Taken from MyMangaList.net")
    await message.channel.send(embed=embed)
Exemple #22
0
    async def anime_upcoming(self, ctx: commands.Context) -> None:
        """Lists upcoming anime."""

        jikan = AioJikan()
        result = (await jikan.season_later())['anime']
        await jikan.close()

        embeds = []
        for i in range(0, len(result), 10):
            temp = []
            for index, value in enumerate(result[i:i + 10], i):
                temp.append(
                    f"`{index + 1}.` [{value['title']}]({value['url']})")
            embeds.append(Embed("\n".join(temp)))

        pagination = PaginationEmbed(ctx, embeds=embeds)
        pagination.embed.title = ":clock3: Upcoming Anime"
        pagination.embed.set_footer(
            text="Powered by MyAnimeList",
            icon_url=ICONS['myanimelist'],
        )
        await pagination.build()
Exemple #23
0
async def mal_character(e):
    await e.edit('Searching...')
    await e.delete()
    async with AioJikan() as jikan:
        sr = await jikan.search('character', e.pattern_match.group(1))
        c = await jikan.character(sr['results'][0]['mal_id'])
    if not c:
        await e.reply('err \\\nNo results found')
        return
    text = f'<b>{html.escape(c["name"])}'
    if c['name_kanji']:
        text += f' ({html.escape(c["name_kanji"])})'
    text += '</b>\n'
    about = html.escape(c['about'].replace('\\n', ''))
    text += f'<i>{about}</i>\n'
    pic = f'{c["image_url"]}'
    url = f'<a href="{html.escape(c["url"])}">read more</a>'
    text = text.strip()
    if len(text) > 1024:
        text = text[0:500] + ".... "
    text = text + url
    await e.reply(text, file=pic, link_preview=False, parse_mode='html')
Exemple #24
0
async def mal_manga(event):
    """Search manga from Kantek itself
       Powered by jikan.moe

    Examples:
        {cmd} command
    """
    async with AioJikan() as jikan:
        sr = await jikan.search('manga', event.text.split(" ", 1))
        m = await jikan.manga(sr['results'][0]['mal_id'])
    if not m:
        await event.reply('err \\\nNo results found')
        return
    text = f'<b>{html.escape(m["title"])}'
    if m['title_japanese']:
        text += f' ({html.escape(m["title_japanese"])})'
    text += '</b>\n'
    text += f'<b>Score:</b> {m["score"]}\n'
    text += f'<b>Type:</b> {html.escape(m["type"])}\n'
    text += f'<b>Genres:</b> {", ".join([html.escape(i["name"]) for i in m["genres"]])}\n'
    text += f'<b>Status:</b> {html.escape(m["status"])}\n'
    if m['volumes']:
        text += f'<b>Volumes:</b> {m["volumes"]}\n'
    if m['chapters']:
        text += f'<b>Chapters:</b> {m["chapters"]}\n'
    text += f'<i>{html.escape(m["synopsis"])}</i>\n'
    pic = f'{m["image_url"]}'
    url = f'<a href="{html.escape(m["url"])}">read more</a>'
    text = text.strip()
    if len(text) > 1024:
        text = text[0:500] + ".... "
    text = text + url
    try:
        await event.reply(text,
                          file=pic,
                          link_preview=False,
                          parse_mode='html')
    except BaseException:
        await event.reply(text, link_preview=False, parse_mode='html')
Exemple #25
0
    async def mal(self, ctx, *, query):
        jikan = AioJikan()

        try:
            result = await jikan.search("anime", query)
        except APIException:
            await ctx.send("Problem connecting to the API. Please try again.")
            await jikan.close()
            return

        #taking first result for now
        if len(result["results"]) > 0:
            result = result["results"][0]
        else:
            await ctx.send(f"No results for <{query}>.")
            await jikan.close()
            return

        try:
            anime = await jikan.anime(result.get("mal_id"))
        except APIException:
            await ctx.send("Problem connecting to the API. Please try again.")
            await jikan.close()
            return

        title = anime.get("title")
        title_japanese = anime.get("title_japanese")
        anime_type = anime.get("type")
        url = anime.get("url")
        image = anime.get("image_url")
        airing = anime.get("airing")
        aired = anime["aired"].get("string")
        synopsis = anime.get("synopsis")
        score = anime.get("score")
        broadcast = "N/A"
        if airing:
            broadcast = anime.get("broadcast")
        if (episodes := anime.get("episodes")) is None:
            episodes = "N/A"
Exemple #26
0
    async def random_async(profile, pages=8):
        async with AioJikan() as jikan:

            if profile:
                person_list = await jikan.user(profile, request='animelist')
                anime = await jikan.anime(
                    rnd.choice(person_list['anime'])['mal_id'])

            else:
                pages = 8 if pages < 1 else pages
                page_no = rnd.randint(1, pages)
                item_no = rnd.randint(0, 49)

                page = await jikan.top('anime',
                                       page=page_no,
                                       subtype='bypopularity')
                anime = await jikan.anime(page['top'][item_no]['mal_id'])

            try:
                return Entry(anime)

            except AssertionError:
                return await Entry.random_async(profile, pages)
Exemple #27
0
class WeebCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.logger = logging.getLogger("TempleBot.weeb")
        self.british_timezone = pytz.timezone('Europe/London')
        self.logger.info("Opening MAL API event loop.")
        self.jikan_aio = AioJikan()
        self.cog_config = self.bot.get_cog_config("anime_manga_search_config")
        self.message_reaction_waiting_h_table = {}
        self.current_mal_req_count_ps = 0
        self.current_mal_req_count_pm = 0
        # self.logger.info("Loaded WeebCog")

    @commands.command(name="weeb_search", hidden=True)
    async def weeb_search_command(self, ctx):
        ctx.message.content = ctx.message.content.strip(self.bot.command_prefix).strip("weeb_search ")
        try:
            await self.anime_title_request_func(ctx.message, ctx.message)
        except jikanpy.exceptions.APIException:
            self.logger.exception("jikanpy.exceptions.APIException raised, attempting API "
                                  "restart.")
            await self.jikan_aio.close()
            self.jikan_aio = AioJikan()
            await self.anime_title_request_func(ctx.message, ctx.message)
        asyncio.create_task(self.mal_rate_limit_down_counter())

    @commands.Cog.listener()
    async def on_message(self, message):
        if message.author.bot:
            return
        elif message.guild is None:
            return
        elif str(message.guild.id) not in self.cog_config["anime_manga_channel_id"].keys():
            return None
        elif str(message.channel.id) in self.cog_config["anime_manga_channel_id"][str(message.guild.id)]:
            search_regex = r"(^{.+}$|^\[.+\]$)"
            self.logger.debug(f"{message.content}")
            if re.search(search_regex, message.content) is not None:
                # We now have a totally valid query of either anime or manga, so it's going to be
                # repackaged and allowed to invoke the search function.
                message.content = self.bot.command_prefix + "weeb_search " + message.content
                self.logger.debug(f"{message.content}")
                await self.bot.process_commands(message)

    def cog_unload(self):
        asyncio.run(self.jikan_aio.close())

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, raw_reaction_event):
        try:
            if raw_reaction_event.member.bot:
                return
        except AttributeError:
            pass

        message_id_in_use = None
        for waiting_message in self.message_reaction_waiting_h_table.values():
            if raw_reaction_event.message_id == waiting_message["msg_id"]:
                message_id_in_use = waiting_message

        if message_id_in_use is None:
            return

        allowed_emoji = ["0⃣", "1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "🇽"]

        if raw_reaction_event.emoji.name not in allowed_emoji:
            return

        reverse_word_to_numeral_hash_table = {"0⃣": 0, "1⃣": 1, "2⃣": 2, "3⃣": 3, "4⃣": 4, "5⃣": 5, "🇽": 999}

        if self.message_reaction_waiting_h_table[message_id_in_use["msg_rand_id"]]["user_id"] != \
                raw_reaction_event.user_id:
            return

        self.message_reaction_waiting_h_table[message_id_in_use["msg_rand_id"]]["user_reaction"] = \
            reverse_word_to_numeral_hash_table[raw_reaction_event.emoji.name]
        self.message_reaction_waiting_h_table[message_id_in_use["msg_rand_id"]]["user_reacted"] = True

    async def mal_rate_limit_down_counter(self):
        await asyncio.sleep(2)
        self.current_mal_req_count_ps -= 1
        self.logger.debug("Reduced per second count.")
        await asyncio.sleep(58)
        self.current_mal_req_count_pm -= 1
        self.logger.debug("Reduced per minute count.")

    async def anime_title_request_func(self, message_class, initial_command):

        def m_a_type(msg_object):
            if msg_object.content.startswith("["):
                return "manga"
            elif msg_object.content.startswith("{"):
                return "anime"
            else:
                return None

        req_type = m_a_type(message_class)
        query_term = message_class.content.strip("{}[]")

        weeb_shit_channel = message_class.channel
        self.logger.debug(query_term)

        paused = True
        while paused:
            if self.current_mal_req_count_pm >= 30:
                await asyncio.sleep(self.current_mal_req_count_pm - 30)
            elif self.current_mal_req_count_ps >= 2:
                await asyncio.sleep(1)
            else:
                paused = False

        self.current_mal_req_count_pm += 1
        self.current_mal_req_count_ps += 1

        self.logger.debug("Making API request.")
        r_obj_raw = await self.jikan_aio.search(search_type=req_type, query=query_term)
        self.logger.debug("API Request complete.")

        # PLACEHOLDER FOR BETTER RESULT OPTIONS
        w_to_n_h_tab = {0: "zero", 1: "one", 2: "two", 3: "three", 4: "four", 5: "five"}
        item_selection_embed = discord.Embed(title=f"TempleBot {m_a_type(message_class).capitalize()} Selection.")
        options_list_string = ""
        number_to_title = {}

        if len(r_obj_raw["results"]) == 0:
            await weeb_shit_channel.send("No results found")
            self.logger.debug(f"{r_obj_raw}")
            return

        try:
            for i in range(5):
                options_list_string += f":{w_to_n_h_tab[i]}: - {r_obj_raw['results'][i]['title']}\n"
        except Exception:
            pass

        options_list_string += f":regional_indicator_x: - None of the above"
        item_selection_embed.add_field(name="Are any of these correct?",
                                       value=options_list_string)

        initial_option_message = await weeb_shit_channel.send(embed=item_selection_embed)

        msg_rand_id = random.randint(0, 100000)
        while msg_rand_id in self.message_reaction_waiting_h_table.keys():
            msg_rand_id = random.randint(0, 100000)
        self.message_reaction_waiting_h_table[msg_rand_id] = {"number_to_title": number_to_title,
                                                              "msg_id": initial_option_message.id,
                                                              "msg_rand_id": msg_rand_id,
                                                              "user_reacted": False,
                                                              "user_reaction": 0,
                                                              "user_id": message_class.author.id}
        unicode_emote_hash_table = {":zero:": "0⃣", ":one:": "1⃣", ":two:": "2⃣",
                                    ":three:": "3⃣", ":four:": "4⃣", "five": "5⃣"}
        try:
            for i in range(5):
                emoji_name = f":{w_to_n_h_tab[i]}:"
                number_to_title[f"{emoji_name}"] = r_obj_raw['results'][i]
        except Exception:
            pass

        self.logger.debug(f"{number_to_title}")
        early_reacted = False
        for emote in number_to_title.keys():
            if self.message_reaction_waiting_h_table[msg_rand_id]["user_reacted"]:
                early_reacted = True
                break
            await initial_option_message.add_reaction(unicode_emote_hash_table[emote])
        if not early_reacted:
            await initial_option_message.add_reaction("\N{Regional Indicator Symbol Letter X}")

        loop_sleep_time_s = 0.05
        max_loop_runtime_s = 30
        loop_runtime_s = 0
        while not self.message_reaction_waiting_h_table[msg_rand_id]["user_reacted"]:
            await asyncio.sleep(loop_sleep_time_s)
            loop_runtime_s += loop_sleep_time_s
            if loop_runtime_s >= max_loop_runtime_s:
                await initial_option_message.delete()
                return

        if self.message_reaction_waiting_h_table[msg_rand_id]["user_reaction"] == 999:
            await initial_option_message.delete()
            return

        r_obj = r_obj_raw['results'][self.message_reaction_waiting_h_table[msg_rand_id]["user_reaction"]]
        # if r_obj['title'] in CONFIG_VAR.blocked_mal_search_results or (
        #         r_obj["rated"].lower() == 'rx' and CONFIG_VAR.explicit_search_protection_on):
        #     await initial_option_message.delete()
        #     await initial_command.delete()
        #     return

        prepro_img_url = r_obj['image_url'].rsplit("?", 1)[0].rsplit(".", 1)
        new_img_url = prepro_img_url[0] + "l." + prepro_img_url[1]

        async with aiohttp.ClientSession() as session:
            async with session.get(new_img_url) as target_image_res:
                if target_image_res.status == 200:
                    found_image = True
                else:
                    found_image = False
                colour_dec_split = [38, 66, 133]

        item_embed = discord.Embed(title=(r_obj['title'] + " [" + r_obj['type'] + "]"), url=r_obj['url'],
                                   timestamp=discord.Embed.Empty,
                                   colour=discord.Colour.from_rgb(r=colour_dec_split[0],
                                                                  g=colour_dec_split[1],
                                                                  b=colour_dec_split[2]))

        if req_type == "anime":
            new_media_obj = await self.jikan_aio.anime(r_obj["mal_id"])
        else:
            new_media_obj = await self.jikan_aio.manga(r_obj["mal_id"])

        self.british_timezone = pytz.timezone('Europe/London')
        now = datetime.now(self.british_timezone)

        def date_ordinal_letter(day_num: int) -> str:
            if 4 <= day_num <= 20 or 24 <= day_num <= 30:
                return "th"
            else:
                return ["st", "nd", "rd"][int(str(day_num)[-1]) - 1]

        brit_day_in = now.strftime('%d').lstrip("0")
        now_brit_day = brit_day_in + date_ordinal_letter(int(brit_day_in))
        now_brit = now.strftime(f'%a %b {now_brit_day}, %Y at %H:%M:%S')

        """
        embed_pregen_dict = {
            "title": r_obj['title']+" ["+r_obj['type']+"]",
            "url": r_obj['url'],
            "type": "rich",
            "timestamp": discord.Embed.Empty,
            "color": int(colour_dec_concat),
            "description": discord.Embed.Empty,
            "footer": {
                "text": f"Data scraped with JikanPy | {now_brit} {now.tzname()}",
                "icon_url": "https://i.imgur.com/fSPtnoP.png"
            },
            "image": {},
            "video": {},
            "provider": {}
        }"""

        def id_letter(req_form):
            if req_form == "anime":
                return "a"

            return "m"

        if r_obj["synopsis"] == "":
            r_obj["synopsis"] = f"No synopsis information has been added to this title. " \
                                f"Help improve the MAL database by adding a synopsis " \
                                f"[here](https://myanimelist.net/dbchanges.php?{id_letter(req_type)}" \
                                f"id={r_obj['mal_id']}&t=synopsis)."

        # test_from_dict_embed = discord.Embed.from_dict(embed_pregen_dict)
        # test_from_dict_embed.set_author(name="Pytato/GCHQBot",
        #                                 icon_url="https://i.imgur.com/5zaQwWr.jpg",
        #                                 url="https://github.com/Pytato/GCHQBot")
        # test_from_dict_embed.add_field(name="Synopsis:", value=r_obj['synopsis'], inline=False)
        # test_from_dict_embed.set_thumbnail(url=new_img_url)

        item_embed.set_footer(text=f"Data scraped with JikanPy | {now_brit} {now.tzname()}",
                              icon_url="https://i.imgur.com/fSPtnoP.png")
        item_embed.set_author(name="Pytato/TempleBot", icon_url="https://lithi.io/file/XVKH.png",
                              url="https://github.com/Pytato/TempleBot")
        if found_image:
            item_embed.set_thumbnail(url=new_img_url)

        char_limit = 300
        if len(r_obj["synopsis"]) > char_limit:
            if r_obj["synopsis"][char_limit - 1] == ".":
                r_obj["synopsis"] = r_obj["synopsis"][:(char_limit - 2)].rstrip(" ") + "..."
            r_obj["synopsis"] = r_obj["synopsis"][:(char_limit - 1)].rstrip(" ") + "..."

        item_embed.add_field(name="Synopsis:", value=r_obj['synopsis'], inline=False)

        date_format = "%Y-%m-%d"
        now = datetime.now()

        start_obj = None

        try:
            if r_obj['end_date'] is None:
                end = "?"
            else:
                end = r_obj['end_date'].split("T")[0]
        except KeyError:
            end = "?"
        try:
            if r_obj['start_date'] is None:
                start = "?"
            else:
                start = r_obj['start_date'].split("T")[0]
                start_obj = datetime.strptime(start, date_format)
        except KeyError:
            start = "?"

        rating_hash_table = {
            "G - All Ages": "G",
            "PG - Children": "PG",
            "PG-13 - Teens 13 or older": "PG-13",
            "R - 17+ (violence & profanity)": "R",
            "R+ - Mild Nudity": "R+",
            "Rx - Hentai": "Rx",
            "No Rating": "No Rating"
        }
        try:
            rating = rating_hash_table[r_obj['rated']]
        except KeyError:
            rating = "No Rating"

        if req_type == "anime":
            if r_obj['episodes'] == 0:
                r_obj['episodes'] = "?"

            if r_obj['airing']:
                release_status = "Airing"
                if start_obj > now and start != "?":
                    release_status = "Not Yet Airing"
            else:
                release_status = "Finished"
                if start == "?" or start_obj > now:
                    release_status = "Not Yet Airing"

            item_embed.add_field(name="Airing Details:",
                                 value=f"From: {start}\n"
                                       f"To: {end}\n"
                                       f"Status: {release_status}\n"
                                       f"Episode Count: {r_obj['episodes']}", inline=True)
            try:
                item_embed.add_field(name="Other Details:",
                                     value=f"Score: {r_obj['score']}\n"
                                           f"Age Rating: {rating}\n"
                                           f"Studio: {new_media_obj['studios'][0]['name']}\n"
                                           f"Members: " + "{:,}".format(r_obj['members']),
                                     inline=True)
            except IndexError:
                item_embed.add_field(name="Other Details:",
                                     value=f"Score: {r_obj['score']}\n"
                                           f"Age Rating: {rating}\n"
                                           f"Studio: Not Yet Defined\n"
                                           f"Members: " + "{:,}".format(r_obj['members']),
                                     inline=True)

        else:
            if r_obj['volumes'] == 0:
                r_obj['volumes'] = "?"

            if r_obj['publishing']:
                release_status = "Publishing"
                if start_obj > now and start != "?":
                    release_status = "Not Yet Publishing"
            else:
                release_status = "Finished"
                if start == "?" or start_obj > now:
                    release_status = "Not Yet Publishing"

            try:
                r_obj['rated']
            except KeyError:
                r_obj['rated'] = "No Rating"

            item_embed.add_field(name="Publishing Details:",
                                 value=f"From: {start}\n"
                                       f"To: {end}\n"
                                       f"Status: {release_status}\n"
                                       f"Volume Count: {r_obj['volumes']}", inline=True)
            item_embed.add_field(name="Other Details:",
                                 value=f"Score: {r_obj['score']}\n"
                                       f"Age Rating: {rating}\n"
                                       f"My Anime List ID: {r_obj['mal_id']}\n"
                                       f"Members: " + "{:,}".format(r_obj['members']), inline=True)

        await initial_option_message.delete()
        # await initial_command.delete()
        await weeb_shit_channel.send(embed=item_embed)
        await _clean_temp_files()
Exemple #28
0
from jikanpy import AioJikan
import asyncio
from pprint import pprint

loop = asyncio.get_event_loop()

aio_jikan = AioJikan(loop=loop)


async def main(loop):
    mushishi = await aio_jikan.anime(457)
    pprint(mushishi)

    fma = await aio_jikan.manga(25)
    pprint(fma)

    ginko = await aio_jikan.character(425)
    pprint(ginko)

    naruto = await aio_jikan.search(search_type='anime', query='naruto')
    pprint(naruto)

    winter_2018 = await aio_jikan.season(year=2018, season='winter')
    pprint(winter_2018)

    monday = await aio_jikan.schedule(day='monday')
    pprint(monday)

    top_anime = await aio_jikan.top(type='anime')
    pprint(top_anime)
Exemple #29
0
 def __init__(self, bot):
     self.bot = bot
     self.neko_client = NekoClient(self.bot.aiohttp_session, self.bot.loop)
     self.jikan = AioJikan(session=self.bot.aiohttp_session,
                           loop=self.bot.loop)
Exemple #30
0
async def profile(client, message, *args):
    if len(args) == 0:
        await message.channel.send(f"Usage: {PREFIX}profile <MAL User>")
        return
    search_str = " ".join(args)
    try:
        jikan = AioJikan()
        profile = await jikan.user(username=search_str, request="profile")
    except APIException:
        await message.channel.send("Username not found on MAL, or account is private.")
        return
    embed = discord.Embed(
        title="{0}'s MAL Profile".format(search_str),
        url=profile["url"],
        color=message.author.colour,
    )
    if profile["image_url"]:
        embed.set_thumbnail(url=profile["image_url"])
    if profile["gender"]:
        embed.add_field(name="Gender", value=profile["gender"])
    if profile["birthday"]:
        birthday = datetime.datetime.fromisoformat(profile["birthday"]).strftime(
            "%A, %d %B, %Y"
        )
        embed.add_field(name="Birthday", value=birthday)
    if profile["location"]:
        embed.add_field(name="Location", value=profile["location"])
    if profile["joined"]:
        joined = datetime.datetime.fromisoformat(profile["joined"]).strftime(
            "%A, %d %B, %Y"
        )
        embed.add_field(name="Joined MAL", value=joined)
    astats = profile["anime_stats"]
    anime_stats = f"""
Days of anime watched: {astats['days_watched']}
Mean score: {astats['mean_score']}
Watching: {astats['watching']}
Completed: {astats['completed']}
On Hold: {astats['on_hold']}
Dropped: {astats['dropped']}
Plan to Watch: {astats['plan_to_watch']}
Rewatched: {astats['rewatched']}
Episodes Watched: {astats['episodes_watched']}
Total: {astats['total_entries']}
    """
    mstats = profile["manga_stats"]
    manga_stats = f"""
Days of manga read: {mstats['days_read']}
Mean score: {mstats['mean_score']}
Reading: {mstats['reading']}
Completed: {mstats['completed']}
On Hold: {mstats['on_hold']}
Dropped: {mstats['dropped']}
Plan to Read: {mstats['plan_to_read']}
Reread: {mstats['reread']}
Chapters Read: {mstats['chapters_read']}
Volumes Read: {mstats['volumes_read']}
Total: {mstats['total_entries']}
    """
    embed.add_field(name="Anime Stats", value=anime_stats, inline=False)
    embed.add_field(name="Manga Stats", value=manga_stats, inline=False)
    if profile["favorites"]["anime"]:
        afavs = profile["favorites"]["anime"]
        anime_favorites = ", ".join(
            [
                "[{0}]({1})".format(
                    i["name"].replace(",", ""), i["url"].replace("_", r"\_")
                )
                for i in afavs
            ]
        )
    else:
        anime_favorites = "No anime favorites set."
    if profile["favorites"]["manga"]:
        mfavs = profile["favorites"]["manga"]
        manga_favorites = ", ".join(
            [
                "[{0}]({1})".format(
                    i["name"].replace(",", ""), i["url"].replace("_", r"\_")
                )
                for i in mfavs
            ]
        )
    else:
        manga_favorites = "No manga favorites set."
    if profile["favorites"]["characters"]:
        cfavs = profile["favorites"]["characters"]
        favorite_chars = ", ".join(
            [
                "[{0}]({1})".format(
                    i["name"].replace(",", ""), i["url"].replace("_", r"\_")
                )
                for i in cfavs
            ]
        )
    else:
        favorite_chars = "No favorite characters set."
    embed.add_field(name="Anime Favorites", value=anime_favorites, inline=False)
    embed.add_field(name="Manga Favorites", value=manga_favorites, inline=False)
    embed.add_field(name="Favorite Characters", value=favorite_chars, inline=False)
    about = profile["about"]
    if about:
        if len(about) > 500:
            about = about[:500] + "..."
        embed.add_field(name="About Them", value=about)
    await message.channel.send(embed=embed)