async def from_data(cls, bot, data): if data['location'].startswith('gym/'): loc_id = data['location'].split('/', maxsplit=1)[1] location = Gym(bot, int(loc_id)) elif data['location'].startswith('pokestop/'): loc_id = data['location'].split('/', maxsplit=1)[1] location = Pokestop(bot, int(loc_id)) else: city, arg = data['location'].split('/', maxsplit=1) location = PartialPOI(bot, city, arg) guild_id = data['guild'] pkmn_id = data['pkmn'] pkmn = Pokemon(bot, pkmn_id) wild_id = data['id'] caught_by = data.get('caught_by', []) reporter_id = data.get('reporter_id') wild = cls(wild_id, bot, guild_id, reporter_id, location, pkmn, caught_by=caught_by) wild.message_ids = data['messages'] for idstring in wild.message_ids: Wild.by_message[idstring] = wild wild.created = data['created'] wild.monitor_task = bot.loop.create_task(wild.monitor_status()) return wild
async def from_mod(cls, mod: Rocket): name = mod.name if isinstance(mod.location, Pokestop): directions_url = await mod.location.url() directions_text = await mod.location._name() else: directions_url = mod.location.url directions_text = mod.location._name + " (Unknown Location)" fields = {} if hasattr(mod, 'pokemon'): pkmn = [Pokemon(mod.bot, x) for x in mod.pokemon] pkmn_names = [await x.name() for x in pkmn] fields['Pokemon'] = "\n".join(pkmn_names) fields['Location'] = f'[{directions_text}]({directions_url})' img_url = mod.img_url() reporter = mod.guild.get_member(mod.reporter_id) if not reporter: reporter = await mod.guild.fetch_member(mod.reporter_id) reporter = reporter.display_name footer = f"Reported by {reporter}" reportdt = datetime.fromtimestamp(mod.created) color = mod.guild.me.color embed = formatters.make_embed(title=f"{name} Report", msg_colour=color, thumbnail=img_url, fields=fields, footer=footer) embed.timestamp = reportdt return cls(embed)
def from_data(cls, bot, data): guild_id = data['guild_id'] lister_id = data['lister_id'] listing_id = data['listing_id'] offered_pokemon = [ Pokemon.from_dict(bot, eval(x)) for x in data['offers'] ] wanted_pokemon = [] for want in data['wants']: want = eval(want) if want in ['obo', 'any']: continue want = Pokemon.from_dict(bot, want) wanted_pokemon.append(want) if 'any' in data['wants']: wanted_pokemon.append('any') if 'obo' in data['wants']: wanted_pokemon.append('obo') offer_list = [] if data['offer_list']: offer_list_data = [eval(x) for x in data['offer_list']] for x in offer_list_data: listed = Pokemon.from_dict(bot, x['listed']) if isinstance(x['offered'], dict): offered = Pokemon.from_dict(bot, x['offered']) else: offered = x['offered'] trader_id = x['trader'] msg = x['msg'] d = { 'trader': trader_id, 'listed': listed, 'offered': offered, 'msg': msg } offer_list.append(d) trade_id = data['id'] new_trade = cls(trade_id, bot, guild_id, lister_id, listing_id, offered_pokemon, wanted_pokemon) new_trade.offer_list = offer_list cls.by_listing[listing_id] = new_trade for offer in offer_list: cls.by_offer[offer['msg']] = new_trade return new_trade
async def get_wants(self): wants = [] if hasattr(self, 'pokemon'): pkmn = [Pokemon(self.bot, x) for x in self.pokemon] families = [await x._familyId() for x in pkmn] families = list(set(families)) for f in families: wants.append(Want(self.bot, f, self.guild_id)) wants.append(Want(self.bot, self.kind, self.guild_id)) return wants
async def from_research(cls, research): bot = research.bot task = research.task location = research.location reward = research.reward if isinstance(task, Task): task = task.id else: task = task.id.split('/', 1)[1] if '/' in reward: reward = ItemReward(research.bot, reward) desc = await reward.description() thumbnail = reward.img_url elif reward == 'unknown_encounter': desc = "Unknown Encounter" thumbnail = ("https://raw.githubusercontent.com/" "FoglyOgly/Meowth/new-core/meowth/images/misc/unknown_encounter.png") else: pkmn = Pokemon(bot, reward) desc = await pkmn.name() if await pkmn._shiny_available(): desc += " :sparkles:" type_emoji = await pkmn.type_emoji() desc += f" {type_emoji}" thumbnail = await pkmn.sprite_url() if isinstance(location, POI): directions_url = await location.url() directions_text = await location._name() else: directions_url = location.url directions_text = location._name + " (Unknown Pokestop)" title = "Field Research Report" fields = { 'Pokestop': f"[{directions_text}]({directions_url})", 'Task': task, 'Reward': desc + "\n<:silph:548259248442703895>Research tasks and rewards provided by [The Silph Road](https://thesilphroad.com/research-tasks)" } reporter = research.guild.get_member(research.reporter_id) if not reporter: reporter = await research.guild.fetch_member(research.reporter_id) color = research.guild.me.color reporter_name = reporter.display_name reporter_avy = reporter.avatar_url footer = f"Reported by {reporter_name} • Expires" icon_url = ("https://raw.githubusercontent.com/" "FoglyOgly/Meowth/new-core/meowth/images/misc/field-research.png") embed = formatters.make_embed(title=title, thumbnail=thumbnail, fields=fields, footer=footer, footer_icon=reporter_avy, icon=icon_url, msg_colour=color) embed.timestamp = datetime.utcfromtimestamp(research.expires_at) return cls(embed)
async def get_wants(self): wants = [] reward = self.reward if reward.startswith('partial'): return wants elif '/' in reward: reward = ItemReward(self.bot, reward) item = reward.item wants.append(item.id) elif reward == 'unknown_encounter': return wants else: pkmn = Pokemon(self.bot, reward) family = await pkmn._familyId() wants.append(family) wants = [Want(self.bot, x, self.guild_id) for x in wants] want_dict = {x: await x.mention() for x in wants} return want_dict
async def summary_str(self): task = self.task reward = self.reward location = self.location if '/' in reward: reward = ItemReward(self.bot, reward) desc = await reward.description() elif reward == 'unknown_encounter': desc = "Unknown Encounter" else: pkmn = Pokemon(self.bot, reward) desc = await pkmn.name() if await pkmn._shiny_available(): desc += " :sparkles:" type_emoji = await pkmn.type_emoji() desc += f" {type_emoji}" if isinstance(task, Task): task = task.id else: task = task.id.split('/', 1)[1] if isinstance(location, POI): directions_url = await location.url() directions_text = await location._name() if len(directions_text) > 25: directions_text = directions_text[:25] + "..." else: directions_url = location.url name = location._name if len(name) > 25: name = name[:25] + "..." directions_text = name + " (Unknown Pokestop)" summary_str = f"• Reward: {desc} • Task: {task} • Location: [{directions_text}]({directions_url})" return summary_str
async def research(self, ctx, reward: Optional[Union[Pokemon, ItemReward]], task: Optional[Task], *, location: Pokestop): """Report a Field Research task. **Arguments** *reward (optional):* Description of the reward for the research. Either a Pokemon or an item. *task (optional):* Either the text of the research task itself or the research category (e.g. `raid`). If a conversion to a Task cannot be made, Meowth asks you to select a category, then to select the specific task. *location:* Name of the Pokestop where the Field Research can be found. Meowth will automatically expire the research at midnight local time. The reporter will be awarded points for the number of users that obtain the task.""" tz = await ctx.tz() if reward and not task: task_matches = await self.possible_tasks(reward.id) if len(task_matches) == 1: task = Task(ctx.bot, task_matches[0]) elif len(task_matches) > 1: react_list = formatters.mc_emoji(len(task_matches)) display_dict = dict(zip(react_list, task_matches)) display_dict["\u2754"] = "Other" react_list.append("\u2754") embed = formatters.mc_embed(display_dict) multi = await ctx.send('Multiple possible Tasks found! Please select from the following list.', embed=embed) payload = await formatters.ask(ctx.bot, [multi], user_list=[ctx.author.id], react_list=react_list) if not payload: try: return await multi.delete() except: return task = display_dict[str(payload.emoji)] if task == 'Other': otherask = await ctx.send('What is the Task for this Research? Please type your answer below.') def check(m): return m.author == ctx.author and m.channel == ctx.channel reply = await ctx.bot.wait_for('message', check=check) arg = reply.content try: await reply.delete() await otherask.delete() except: pass task = PartialTask(ctx.bot, arg) else: task = Task(ctx.bot, task) try: await multi.delete() except: pass if not task: cats = await self.task_categories() content = "What category of Research Task is this? Select from the options below." react_list = formatters.mc_emoji(len(cats)) cat_dict = dict(zip(react_list, cats)) embed = formatters.mc_embed(cat_dict) multi = await ctx.send(content, embed=embed) payload = await formatters.ask(ctx.bot, [multi], user_list=[ctx.author.id], react_list=react_list) if not payload: try: return await multi.delete() except: return cat = cat_dict[str(payload.emoji)] try: await multi.delete() except: pass task = await Task.convert(ctx, cat, require_task=True) if isinstance(task, Task) and not reward: possible_rewards = await task.possible_rewards() if len(possible_rewards) == 1: reward = possible_rewards[0] else: react_list = formatters.mc_emoji(len(possible_rewards)) item_dict = {} pkmn_dict = {} for reward in possible_rewards: if '/' in reward: obj = ItemReward(ctx.bot, reward) desc = await obj.description() item_dict[desc] = reward else: pkmn = Pokemon(ctx.bot, reward) name = await pkmn.name() pkmn_dict[name] = reward reward_dict = dict(pkmn_dict, **item_dict) if len(pkmn_dict) > 1: react_list = formatters.mc_emoji(len(possible_rewards)+1) reward_dict['Unknown Encounter'] = 'unknown_encounter' choice_dict = dict(zip(react_list, reward_dict.values())) display_dict = dict(zip(react_list, reward_dict.keys())) embed = formatters.mc_embed(display_dict) embed.fields[0].value = embed.fields[0].value + "\n<:silph:548259248442703895>Research tasks and rewards provided by [The Silph Road](https://thesilphroad.com/research-tasks)" multi = await ctx.send('What is the reward for this task? Please select from the options below.', embed=embed) payload = await formatters.ask(ctx.bot, [multi], user_list=[ctx.author.id], react_list=react_list) if not payload: try: return await multi.delete() except: return reward = choice_dict[str(payload.emoji)] try: await multi.delete() except: pass elif not reward: msg = await ctx.send('What is the reward for this Research? Please type your response below.') def check(m): return m.author == ctx.author and m.channel == ctx.channel reply = await ctx.bot.wait_for('message', check=check) try: reward = await Pokemon.convert(ctx, reply.content) except: reward = None if not reward: try: reward = await ItemReward.convert(ctx, reply.content) except: reward = ItemReward(ctx.bot, f'partial/{reply.content}/1') try: await reply.delete() await msg.delete() except: pass if not isinstance(reward, str): reward = reward.id research_id = next(snowflake.create()) research = Research(research_id, ctx.bot, ctx.guild.id, ctx.author.id, task, location, reward, tz, time.time()) embed = await ResearchEmbed.from_research(research) embed = embed.embed wants = await research.get_wants() mentions = [wants.get(x) for x in wants if wants.get(x)] mention_str = "\u200b".join(mentions) if mention_str: reportcontent = mention_str + " - " else: reportcontent = "" stamp = ctx.bot.get_emoji(583375171847585823) map_icon = ctx.bot.get_emoji(597185467217346602) reportcontent += f"Field Research reported! Use {str(stamp)} to indicate that you picked up this task!" report_channels = [] report_channel = ReportChannel(ctx.bot, ctx.channel) msgs = [] if isinstance(location, Pokestop): research_table = ctx.bot.dbi.table('research') query = research_table.query() query.where(location=str(location.id), guild_id=ctx.guild.id) old_research = await query.get() if old_research: return await ctx.send("There is already a research task reported at this pokéstop!", delete_after=20) channel_list = await location.get_all_channels('research') report_channels.extend(channel_list) if report_channel not in report_channels: report_channels.append(report_channel) stamp = ctx.bot.get_emoji(583375171847585823) for channel in report_channels: try: msg = await channel.channel.send(reportcontent, embed=embed) await msg.add_reaction("\U0001F4DD") # Task emoji await msg.add_reaction(map_icon) await msg.add_reaction(stamp) except: continue idstring = f'{msg.channel.id}/{msg.id}' msgs.append(idstring) Research.by_message[idstring] = research research.message_ids = msgs await research.upsert() ctx.bot.loop.create_task(research.monitor_status())
async def on_raw_reaction_add(self, payload): idstring = f"{payload.channel_id}/{payload.message_id}" chn, msg = await ChannelMessage.from_id_string(self.bot, idstring) research = Research.by_message.get(idstring) if not research or payload.user_id == self.bot.user.id: return user = payload.member if payload.emoji.is_custom_emoji(): emoji = payload.emoji.id if isinstance(emoji, int): emoji = self.bot.get_emoji(emoji) await msg.remove_reaction(emoji, user) if emoji.id == 583375171847585823: if payload.user_id not in research.completed_by: research.completed_by.append(payload.user_id) if research.reward == 'unknown_encounter': if isinstance(research.task, Task): possible_rewards = await research.task.possible_rewards() pkmn_rewards = [x for x in possible_rewards if '/' not in x] pkmn = [Pokemon(self.bot, x) for x in pkmn_rewards] pkmn_dict = {await x.name(): x.id for x in pkmn} react_list = formatters.mc_emoji(len(pkmn)) choice_dict = dict(zip(react_list, pkmn_dict.values())) display_dict = dict(zip(react_list, pkmn_dict.keys())) embed = formatters.mc_embed(display_dict) embed.fields[0].value = embed.fields[0].value + "\n<:silph:548259248442703895>Research tasks and rewards provided by [The Silph Road](https://thesilphroad.com/research-tasks)" multi = await chn.send(f"{user.mention}: What is the reward for this task? Please select from the options below. If you don't know, just ignore this!", embed=embed) payload = await formatters.ask(self.bot, [multi], user_list=[user.id], react_list=react_list) if not payload: return await multi.delete() reward = choice_dict[str(payload.emoji)] try: await multi.delete() except: pass research.reward = reward elif emoji.id == 597185467217346602: askmsg = await chn.send(f"{user.mention}: Where is this Research located? Please type your response below. If you send a plain text response, I will check it against the Pokestops I know about. You can also send a Google Maps link!") def check(m): return m.author == user and m.channel == chn reply = await self.bot.wait_for('message', check=check) try: await askmsg.delete() await reply.delete() except discord.HTTPException: pass url_re = '(http(s?)://)?((maps\.google\./)|((www\.)?google\.com/maps/)|(goo.gl/maps/))\S*' match = re.search(url_re, reply.content) if match: url = match.group() return await research.update_url(url) else: ctx = await self.bot.get_context(reply, cls=Context) stop = await Pokestop.convert(ctx, reply.content) research.location = stop else: emoji = str(payload.emoji) await msg.remove_reaction(emoji, user) if emoji == '\U0001F4DD': askmsg = await chn.send(f"{user.mention}: What Research task is located here? Please type your response below.") def check(m): return m.author == user and m.channel == chn try: reply = await self.bot.wait_for('message', check=check, timeout=300) except asyncio.TimeoutError: return try: await askmsg.delete() await reply.delete() except discord.HTTPException: pass ctx = await self.bot.get_context(reply, cls=Context) task = await Task.convert(ctx, reply.content, require_task=True) research.task = task embed = await ResearchEmbed.from_research(research) for msgid in research.message_ids: try: chn, msg = await ChannelMessage.from_id_string(self.bot, msgid) await msg.edit(embed=embed.embed) except discord.HTTPException: pass return await research.upsert()