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
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())
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)
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')
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')
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()
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)
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()
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"] ]
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)
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()
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)
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()
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)
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)
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)
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)
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)
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()
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)
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()
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')
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')
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"
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)
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()
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)
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)
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)