"""This file contains the Genshin Discord Cog extension. """ import discord from discord.ext import commands from discord import NotFound from time import time from asyncio import exceptions from py_files.src.gaming_libraries import genshin_kqm as kqm class Genshin(commands.Cog): """ This class provides functions related to Genshin Impact. """ def __init__(self, bot): self.bot = bot self._infographs = kqm.kqm_infographics() self._guides = kqm.kqm_guides() self._kqm_characters = self._infographs.keys() self._embed_colors = (255, 226, 136) # r, g, b color values self._sent_ids = set() # for reaction remove self._kqm_access_time = time() # prevents scraping kqm too frequently. @commands.command(name='kqm') async def kqm_guide(self, ctx, *argv): """ Sends the requested kqm infographic for the given character. """ # process user input user_input = '' for arg in argv: user_input += arg + ' ' user_input = user_input.strip() # get character name character = user_input for avail_name in self._kqm_characters: if user_input.lower() in avail_name.lower(): character = avail_name # get character details info_details = self._infographs.get(character) guide_details = self._guides.get(character) curr_time = time() half_day = 43200 time_check = (curr_time - self._kqm_access_time) > half_day # check if kqm got updated if no character found if info_details == None and time_check: self._infographs = kqm.kqm_infographics() self._kqm_characters = self._infographs.keys() # try searching for character again info_details = self._infographs.get(character) # check if kqm got updated if no character found if guide_details == None and time_check: self._guides = kqm.kqm_guides() # try searching for character again guide_details = self._guides.get(character) # character not found if info_details == None and guide_details == None: await ctx.send(f'There are no guides or infographics for {character} from KeqingMains.') return # character found, stores character info as Discord embed "pages" embed_pages = [] guide_url = None card_img = None info_img = None role = None r, g, b = self._embed_colors # retrive guide details if guide_details != None: guide_url = guide_details[0] card_img = guide_details[1] # first page of embed if possible embed_desc = 'Guide from KeqingMains' disc_embed = discord.Embed.from_dict({'title':character, 'url':guide_url, 'description':embed_desc}) disc_embed.set_image(url=card_img) embed_pages.append(disc_embed) # retrieve infographic details if info_details != None: for char in info_details: role = char[0] info_img = char[1] # add pages to list disc_embed = discord.Embed.from_dict({'title':character, 'url':guide_url, 'description':role}) disc_embed.set_image(url=info_img) embed_pages.append(disc_embed) # add footer and color for page, embed in enumerate(embed_pages): footer_note = str(page + 1) + '/' + str(len(embed_pages)) embed.set_footer(text=footer_note) embed.color = discord.Color.from_rgb(r, g, b) # send embeds await self._manage_pages(ctx, embed_pages) async def _manage_pages(self, ctx, embed_pages): """ Adds left and right arrow emojis to the given msg. """ # send first page of embed page = 0 msg = await ctx.send(embed=embed_pages[page]) self._sent_ids.add(msg.id) # add reactions reactions = ['⬅️', '➡️'] for emoji in reactions: await msg.add_reaction(emoji) # start time t0 = time() # checks if reacted def check(reaction, user): return str(reaction.emoji) in reactions \ and user != self.bot.user \ and reaction.message.id == msg.id # waits for reaction while True: # stop function after 60 sec of inactivity try: msg1 = await self.bot.wait_for('reaction_add', check=check, timeout=60.0) except exceptions.TimeoutError: return reaction_emoji = str(msg1[0]) # turn page back if reaction_emoji == reactions[0]: if (page > 0): page -= 1 await msg.edit(embed=embed_pages[page]) # turn page forward else: if (page < len(embed_pages) - 1): page += 1 await msg.edit(embed=embed_pages[page]) if time() - t0 >= 60: self._sent_ids.pop(msg.id) return @commands.Cog.listener() async def on_reaction_add(self, reaction, user): """ Performs operations based on reactions in the text channel """ message = reaction.message # check if author is a bot if user == self.bot.user: return if message.id in self._sent_ids: try: await reaction.remove(user) except NotFound: pass async def setup(bot): await bot.add_cog(Genshin(bot))