def __init__(self, ctx, id_, censored=False, evo=False): super().__init__(ctx, id_, evo) self.censored = censored if LIB.ids[self.id_].censored: self.monitored_emojis.add(':peach:') self.edit_embed() log.info(self.log_scope(PicMsg))
def edit_args(self, emoji): if emoji == ':peach:': log.info('uncensoring') new_args = self.__dict__ new_args["censored"] = not new_args["censored"] return new_args return super().edit_args(emoji)
def __init__(self, ctx, id_, evo=False, show_img=False): super().__init__(ctx, id_, evo) self.show_img = show_img for i in range(len(LIB.ids[self.id_].tokens_)): self.monitored_emojis.add(int_to_emoji(i)) self.monitored_emojis.add(':artist_palette:') self.edit_embed() log.info(self.log_scope(InfoMsg))
async def on_reaction_add(reaction, user): if reaction.message.author == bot.user and user != bot.user: emoji = demojize(reaction.emoji) log_msg = f'[{reaction.message.channel}, {reaction.message.guild}] ' \ f'{user} pressed {emoji} on msg `{reaction.message.embeds[0].title}` (id={reaction.message.id})' pad = '*' * len(log_msg) log.info(f'\n{pad}\n{log_msg}\n{pad}') MyMsg.on_emoji_toggle(reaction.message.id, emoji, user)
def __init__(self, ctx, id_, evo=False, lang='jp'): super().__init__(ctx, id_, evo) if ':dna:' in self.monitored_emojis: self.monitored_emojis.remove(':dna:') self.monitored_emojis.add(":speech_balloon:") self.lang = lang # The embed isn't built with edit_embed here, but when dispatching, because the bot needs to get the voice lines # online, so an async function is needed so that execution isn't blocked. log.info(self.log_scope(VoiceMsg))
def __init__(self, ctx, id_, evo=False): super().__init__(ctx) self.id_ = id_ self.evo = evo card = LIB.ids[self.id_] if card.type_ == "Follower": self.monitored_emojis.add(':dna:') for i in range(len(card.alts_)): self.monitored_emojis.add(chr_to_emoji(chr(ord('a') + i))) log.info(self.log_scope(CardMsg))
def edit_args(self, emoji): new_args = self.__dict__ if emoji == ':dna:': log.info('changing evo flag') new_args["evo"] = not new_args["evo"] return new_args if emoji in chr_emojis(self.monitored_emojis): new_args["id_"] = LIB.ids[self.id_].alts_[ord(emoji[-2]) - ord('a')] log.info(f'{new_args["id_"]=}') return new_args return super().edit_args(emoji)
def edit_embed(self): log.info(log_cls(PicMsg)) super().edit_embed() card = LIB.ids[self.id_] self.embed.set_image( url=card.pic(evo=self.evo, censored=self.censored)) alts_ = card.alts_ if alts_: footer_txt = "" for i, id_ in enumerate(alts_): chr_ = (chr(ord('a') + i)).upper() footer_txt += f'{chr_}: {LIB.ids[id_].expansion_}\n' self.embed.set_footer(text=f'Other artworks:\n{footer_txt}')
def edit_args(self, emoji): if emoji == ":speech_balloon:": new_args = self.__dict__ log.info('swapping language') new_args["lang"] = 'en' if new_args["lang"] == 'jp' else 'jp' return new_args if emoji in chr_emojis(self.monitored_emojis): id_ = LIB.ids[self.id_].alts_[ord(emoji[-2]) - ord('a')] log.info(f'{id_=}') asyncio.create_task( VoiceMsg(self.ctx, id_, self.evo, self.lang).dispatch()) return self.__dict__ return super().edit_args(emoji)
def edit_args(self, emoji): new_args = self.__dict__ if emoji == ':artist_palette:': log.info('swapping img flag') new_args["show_img"] = not new_args["show_img"] return new_args if emoji in int_emojis(self.monitored_emojis): # Sending the token as a separate message. tk_id = LIB.ids[self.id_].tokens_[int(emoji[-2])] log.info(f'sending info page of {tk_id=}') tk_msg = InfoMsg(self.ctx, tk_id) asyncio.create_task(tk_msg.dispatch()) return new_args return super().edit_args(emoji)
async def on_message(message): if message.content.startswith(bot.command_prefix): log_msg = f'[{message.channel}, {message.guild}] {message.author}: {message.content}' pad = '*' * len(log_msg) log.info(f'\n{pad}\n{log_msg}\n{pad}') # If the message contains a deck link, its deck code + image are posted. if f'{SITE}/deck' in message.content and message.author != bot.user: try: deck_hash = message.content.split('deck/')[1].split('lang')[0][:-1] except IndexError: deck_hash = message.content.split('hash=')[1].split('lang')[0][:-1] deck_code, _, deck_img = await deck_hash_assets(deck_hash) await message.channel.send(embed=discord.Embed().add_field(name='Deck Code', value=f'**{deck_code}**'), file=discord.File(deck_img, 'deck.png')) await bot.process_commands(message)
async def dispatch(self): """ Also initializes the embed before sending the message, as anticipated in the init. """ super().edit_embed() self.embed.title = emojize(':Japan:' if self.lang == 'jp' else ':United_Kingdom:') + f' {self.embed.title}' async with aiohttp.client.ClientSession() as s: async with s.get(f'{SITE}/api/voices/{self.id_}') as r: response = await r.read() voice_lines = json.loads(response) for game_action in voice_lines: for i, line in enumerate(voice_lines[game_action]): self.embed.add_field( name='\u200b', value=hyperlink(f'• {fmt_action(game_action, line)}', f'{SITE}/assets/audio/{self.lang}/{line}'), inline=False) log.info(self.log_scope(VoiceMsg)) await super().dispatch()
async def on_ready(): log.info(f'{bot.user} is active.') log.info(f'available commands: {", ".join(cmd.name for cmd in bot.commands)}') server_list = "\n".join(str(g) for g in bot.guilds) log.info(f'serving {len(bot.guilds)} servers:\n {server_list}') await bot.change_presence(activity=discord.Game(f'{bot.command_prefix}h / {bot.command_prefix}help')) await clean_history()
def fmt_action(action, line): action = { "plays": "On Play", "deaths": "On Death", "other": "Other", "evolves": "On Evolve", "attacks": "On Attack" }[action] no_special = re.compile(r'vo_(\d+)_(\d)\.mp3') if re.findall(no_special, line): return action special_self = re.findall( re.compile(r'vo_(\d+)_(\d)_([a-z]+)(_?)(\w*)\.mp3'), line) if special_self: self_effects = { 'enh': 'Enhance', 'ub': 'Union Burst', 'ubp': 'Union Burst Preamble', 'sb': 'Swordbound Art', 'ssb': 'Super Swordbound Art', 'sbp': 'Swordbound Art Preamble', 'ssbp': 'Super Swordbound Art Preamble' } code = special_self[0][2] try: return f'{action} ({self_effects[code]})' except KeyError: log.info(f'UNCAUGHT SPECIAL VOICE LINE {line}') return action special_other = re.findall(re.compile(r'vo_(\d+)_(\d)_(\d+)\.mp3'), line) if special_other: _, code, other_id = special_other[0] return action + (' (enemy ' if code == '7' else ' (ally ') + LIB.ids[int(other_id)].name_ + ')' else: log.info(f'UNCAUGHT SPECIAL VOICE LINE {line}') return action
async def search(ctx, *query, by_attrs, lax, begins) -> List[int]: """ An async extension of the Library class methods for card searches. Asks for user input with a MatchesMsg menu depending on the amount of matches. """ query = ' '.join(query) if by_attrs: matches = LIB.search_by_attributes(query, include_name=False) elif begins: matches = LIB.search_by_name(query, begins=True) elif lax: matches = LIB.search_by_name(query, lax=True) else: matches = LIB.search_by_name(query) if not matches: matches = LIB.search_by_attributes(query, include_name=True) log.info(f'{len(matches)} match{"es" if len(matches) != 1 else ""}') if len(matches) < 2 or len(matches) > MAX_TOGGLABLE_MATCHES: return matches else: matches_obj = MatchesMsg(ctx, matches) await matches_obj.dispatch() match = await matches_obj.wait_for_toggle() return match
import time import json import discord import aiohttp from typing import List, Tuple from natsort import natsorted from discord.ext import commands from emoji import emojize, demojize from Card import EXPANSIONS from MyMsg import NO_HELP, LIB, log, bot from MyMsg import chr_to_emoji, int_to_emoji, hyperlink, has_help from MyMsg import MyMsg, MatchesMsg, HelpMsg from CardMsg import PicMsg, InfoMsg, VoiceMsg log.info(sys.executable) log.info(os.path.abspath(__file__)) log.info(*sys.argv) MAINTAINER_ID = 186585846906880001 MAX_TOGGLABLE_MATCHES = 11 MAX_DISPLAYABLE_MATCHES = 30 SITE = 'https://shadowverse-portal.com' DEV = 0 # 0 on Raspberry. with open(f'token_{"testing" if DEV else "main"}.txt', 'r') as txt: TOKEN = txt.readline() # CARD COMMANDS ########################################################################################################