async def delete_location(ctx, location_type, name): channel = ctx.channel guild = ctx.guild deleted = 0 with KyogreDB._db.atomic() as txn: try: locationresult = ( LocationTable.get((LocationTable.guild == guild.id) & (LocationTable.name == name))) location = LocationTable.get_by_id(locationresult) TrainerReportRelation.update(location=None)\ .where(TrainerReportRelation.location == location.id).execute() loc_reg = (LocationRegionRelation.get( LocationRegionRelation.location_id == locationresult)) if location_type == "stop": deleted = PokestopTable.delete().where( PokestopTable.location_id == locationresult).execute() elif location_type == "gym": deleted = GymTable.delete().where( GymTable.location_id == locationresult).execute() deleted += LocationRegionRelation.delete().where( LocationRegionRelation.id == loc_reg).execute() deleted += location.delete_instance() txn.commit() except Exception as e: await channel.send(e) txn.rollback() return deleted
async def _update_db_research_report(self, guild, message, updated): report, report_relation = None, None try: report_relation = TrainerReportRelation.get( TrainerReportRelation.message == message.id) report = ResearchTable.get( ResearchTable.trainer_report_id == report_relation.id) except Exception as e: self.bot.logger.info( f"Failed to update research table entry with error: {e}") if report is None or report_relation is None: return self.bot.logger.info( f"No Research report found in db to update. Message id: {message.id}" ) quest_dict = self.bot.guild_dict[guild.id]['questreport_dict'].get( message.id, None) if quest_dict is None: return self.bot.logger.info( f"No quest_dict found in guild_dict. " f"Cannot update research report. Message id: {message.id}") report.quest_id = quest_dict['quest_id'] report.reward = quest_dict['reward'] report.save() report_relation.location_id = quest_dict['location_id'] report_relation.updated = updated report_relation.save()
async def _cancel_db_research_report(self, message): try: report_relation = TrainerReportRelation.get( TrainerReportRelation.message == message.id) except Exception as e: return self.bot.logger.info( f"Failed to cancel research table entry with error: {e}") report_relation.cancelled = 'True' report_relation.save()
async def cancel_and_delete(ctx, i): report = TrainerReportRelation.get_by_id(i) report.cancelled = True report.save() message_id = report.message message = await ctx.channel.fetch_message(message_id) try: await message.delete() except (discord.errors.Forbidden, discord.errors.HTTPException): pass
async def _add_db_sighting_report(self, ctx, message): channel = ctx.channel guild = channel.guild author = ctx.author wild_dict = self.bot.guild_dict[guild.id]['wildreport_dict'][message.id] created = round(message.created_at.timestamp()) __, __ = GuildTable.get_or_create(snowflake=guild.id) __, __ = TrainerTable.get_or_create(snowflake=author.id, guild=guild.id) report = TrainerReportRelation.create(created=created, trainer=author.id, location=wild_dict['location_id'], message=message.id) try: SightingTable.create(trainer_report=report, pokemon=wild_dict['pokemon_id']) except Exception as e: self.bot.logger.info(f"Failed to create sighting table entry with error: {e}")
async def _check_existing(stop): epoch = datetime.datetime(1970, 1, 1) day_start = datetime.datetime.utcnow().replace(hour=6, minute=0, second=0, microsecond=0) day_end = datetime.datetime.utcnow().replace(hour=22, minute=0, second=0, microsecond=0) day_start = (day_start - epoch).total_seconds() day_end = (day_end - epoch).total_seconds() result = (TrainerReportRelation.select( TrainerReportRelation.id, TrainerReportRelation.created, LocationTable.id.alias('location_id'), LocationTable.name.alias('location_name'), HideoutTable.rocket_leader.alias('leader'), HideoutTable.first_pokemon, HideoutTable.second_pokemon, HideoutTable.third_pokemon, LocationTable.latitude, LocationTable.longitude, TrainerReportRelation.message, TrainerReportRelation.trainer).join( LocationTable, on=(TrainerReportRelation.location_id == LocationTable.id) ).join( LocationRegionRelation, on=(LocationTable.id == LocationRegionRelation.location_id) ).join( RegionTable, on=(RegionTable.id == LocationRegionRelation.region_id)).join( HideoutTable, on=(TrainerReportRelation.id == HideoutTable.trainer_report_id)). where((LocationTable.name == stop.name) & (TrainerReportRelation.created > day_start) & (TrainerReportRelation.created < day_end) & (TrainerReportRelation.cancelled == False)).order_by( TrainerReportRelation.created)) results = result.objects(HideoutInstance) if len(results) > 0: return result.objects(HideoutInstance)[0] return None
async def _add_db_research_report(self, ctx, message): channel = ctx.channel guild = channel.guild author = ctx.author quest_dict = self.bot.guild_dict[guild.id]['questreport_dict'][ message.id] created = round(message.created_at.timestamp()) __, __ = GuildTable.get_or_create(snowflake=guild.id) __, __ = TrainerTable.get_or_create(snowflake=author.id, guild=guild.id) report = TrainerReportRelation.create( created=created, trainer=author.id, location=quest_dict['location_id'], message=message.id) try: ResearchTable.create(trainer_report=report, quest=quest_dict['quest_id'], reward=quest_dict['reward']) except Exception as e: self.bot.logger.info( f"Failed to create research table entry with error: {e}")
def get_single_hideout(report_id): result = (TrainerReportRelation.select( TrainerReportRelation.id, TrainerReportRelation.created, LocationTable.id.alias('location_id'), LocationTable.name.alias('location_name'), HideoutTable.rocket_leader.alias('leader'), HideoutTable.first_pokemon, HideoutTable.second_pokemon, HideoutTable.third_pokemon, LocationTable.latitude, LocationTable.longitude, TrainerReportRelation.message, TrainerReportRelation.trainer).join( LocationTable, on=(TrainerReportRelation.location_id == LocationTable.id) ).join( LocationRegionRelation, on=(LocationTable.id == LocationRegionRelation.location_id) ).join( RegionTable, on=(RegionTable.id == LocationRegionRelation.region_id)).join( HideoutTable, on=(TrainerReportRelation.id == HideoutTable.trainer_report_id)).where( TrainerReportRelation.id == report_id)) return result.objects(HideoutInstance)[0]
async def _lure(self, ctx, type, *, location): """**Usage**: `!lure <type> <location>` Location should be the name of a Pokestop. Valid lure types are: normal, glacial, mossy, magnetic""" content = f"{type} {location}" message = ctx.message guild = message.guild channel = message.channel author = message.author location_matching_cog = self.bot.cogs.get('LocationMatching') subscriptions_cog = self.bot.cogs.get('Subscriptions') if len(content.split()) <= 1: self.bot.help_logger.info( f"User: {ctx.author.name}, channel: {ctx.channel}, error: Insufficient info." ) return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description= 'Give more details when reporting! Usage: **!lure <type> <location>**' )) report_time = message.created_at + datetime.timedelta( hours=self.bot.guild_dict[ guild.id]['configure_dict']['settings']['offset']) report_time_int = round(report_time.timestamp()) timestamp = report_time.strftime('%Y-%m-%d %H:%M:%S') luretype = content.split()[0].strip(',') pokestop = ' '.join(content.split()[1:]) query = LureTypeTable.select() if id is not None: query = query.where(LureTypeTable.name == luretype) query = query.execute() result = [d for d in query] if len(result) != 1: self.bot.help_logger.info( f"User: {ctx.author.name}, channel: {ctx.channel}, error: Lure type: {luretype} not found." ) return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description= 'Unable to find the lure type provided, please try again.')) luretype = result[0] utils_cog = self.bot.cogs.get('Utilities') lure_regions = utils_cog.get_channel_regions(channel, 'lure') stops = location_matching_cog.get_stops(guild.id, lure_regions) if stops: stop = await location_matching_cog.match_prompt( channel, author.id, pokestop, stops) if not stop: self.bot.help_logger.info( f"User: {ctx.author.name}, channel: {ctx.channel}, error: Pokestop not found with name: {pokestop}." ) return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description="Unable to find that Pokestop. " "Please check the name and try again!")) report = TrainerReportRelation.create(guild=ctx.guild.id, created=report_time_int, trainer=author.id, location=stop.id) lure = LureTable.create(trainer_report=report) LureTypeRelation.create(lure=lure, type=luretype) lure_embed = discord.Embed( title= f'Click here for my directions to the {luretype.name.capitalize()} lure!', description= f"Ask {author.display_name} if my directions aren't perfect!", url=stop.maps_url, colour=discord.Colour.purple()) lure_embed.set_footer(text='Reported by {author} - {timestamp}'.format( author=author.display_name, timestamp=timestamp), icon_url=author.avatar_url_as( format=None, static_format='jpg', size=32)) lurereportmsg = await channel.send( f'**{luretype.name.capitalize()}** lure reported by ' f'{author.display_name} at {stop.name}', embed=lure_embed) listmgmt_cog = self.bot.cogs.get('ListManagement') await listmgmt_cog.update_listing_channels(guild, 'lure', edit=False, regions=lure_regions) details = { 'regions': lure_regions, 'type': 'lure', 'lure_type': luretype.name, 'location': stop } send_channel = subscriptions_cog.get_region_list_channel( guild, stop.region, 'lure') if send_channel is None: send_channel = message.channel await subscriptions_cog.send_notifications_async( 'lure', details, send_channel, [message.author.id]) self.bot.event_loop.create_task( self.lure_expiry_check(lurereportmsg, report.id)) clean_list = self.bot.guild_dict[ ctx.guild.id]['configure_dict'].setdefault('channel_auto_clean', []) if ctx.channel.id in clean_list: await ctx.message.delete()
async def _invasion(self, ctx, *, info=None): """**Usage**: `!rocket <pokestop name> [,rocket leader, pokemon names]` Report a Team Rocket Leader invasion at a pokestop!. Rocket Leader and their Pokemon Lineup are optional and can be updated later.""" message = ctx.message channel = message.channel author = message.author guild = message.guild info = re.split(r',+\s+', info) stopname = info[0] report_time = message.created_at + \ datetime.timedelta(hours=self.bot.guild_dict[guild.id]['configure_dict']['settings']['offset']) epoch = datetime.datetime(1970, 1, 1) report_time_int = (report_time - epoch).total_seconds() utilities_cog = self.bot.cogs.get('Utilities') subscriptions_cog = self.bot.cogs.get('Subscriptions') location_matching_cog = self.bot.cogs.get('LocationMatching') utils_cog = self.bot.cogs.get('Utilities') regions = utils_cog.get_channel_regions(channel, 'hideout') stops = location_matching_cog.get_stops(guild.id, regions) stop = await location_matching_cog.match_prompt( channel, author.id, stopname, stops) if not stop: self.bot.help_logger.info( f"User: {ctx.author.name}, channel: {ctx.channel}, error: No Pokestop found {stopname}." ) return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description=f"No pokestop found with name '**{stopname}**' " f"either. Try reporting again using the exact pokestop name!"), delete_after=15) existing = await self._check_existing(stop) if existing: if existing.leader and existing.second_pokemon and existing.third_pokemon: return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description= f"Hideout for **{stop.name}** has been completely reported already." ), delete_after=15) if not existing: existing = HideoutInstance(None, report_time_int, stop.id, stop.name, None, None, None, None, stop.latitude, stop.longitude, message.id, message.author.id) regions = [stop.region] leader = None pokemon_names = [None] pokemon_ids = [None] # Check through all the info sent in, pull out any leader names and pokemon names we find if len(info) > 1: for i in info[1:]: # if we find a leader name then we can also set the first pokemon # this assumption may change in the future if i.lower() in self.leader_strings: leader = i p_id = self.leader_map[leader.lower()] pkmn = Pokemon.get_pokemon(self.bot, p_id) pokemon_names[0] = pkmn.name pokemon_ids[0] = pkmn.id else: pkmn = Pokemon.get_pokemon(self.bot, i) if pkmn is not None: # if the name found is the one already known to be in the first slot then ignore if pkmn.id not in self.leader_map.values(): pokemon_names.append(pkmn.name) pokemon_ids.append(pkmn.id) # pad the id and names lists if len(pokemon_names) < 3: pokemon_names = (pokemon_names + 3 * [None])[:3] if len(pokemon_ids) < 3: pokemon_ids = (pokemon_ids + 3 * [None])[:3] # if there was a pre-existing report, make sure not to override leader set before if existing.leader: if leader and leader != existing.leader: await channel.send( f"**{existing.leader.capitalize()}** has already been reported for **{stop.name}**.", delete_after=30) leader = existing.leader pkmn = Pokemon.get_pokemon(self.bot, self.leader_map[leader.lower()]) pokemon_names[0] = pkmn.name pokemon_ids[0] = pkmn.id # don't override 2nd slot if already set if existing.second_pokemon: if pokemon_ids[1]: if pokemon_ids[1] != existing.second_pokemon: if pokemon_ids[2]: await channel.send( f"The second lineup slot has already been reported for **{stop.name}**.", delete_after=30) else: # but if the third slot was previously not set, we can fill that in now if not existing.third_pokemon: existing.third_pokemon = pokemon_ids[1] pkmn = Pokemon.get_pokemon(self.bot, existing.second_pokemon) pokemon_names[1] = pkmn.name pokemon_ids[1] = pkmn.id # don't override 3rd slot if already set. this may be unreachable if existing.third_pokemon: if pokemon_ids[2]: if pokemon_ids[2] != existing.second_pokemon: await channel.send( f"The third lineup slot has already been reported for **{stop.name}**", delete_after=30) pkmn = Pokemon.get_pokemon(self.bot, existing.third_pokemon) pokemon_names[2] = pkmn.name pokemon_ids[2] = pkmn.id if leader: leader = leader.lower() if existing.id: report = TrainerReportRelation.get_by_id(existing.id) HideoutTable.update(rocket_leader=leader, first_pokemon=pokemon_ids[0], second_pokemon=pokemon_ids[1], third_pokemon=pokemon_ids[2])\ .where(HideoutTable.trainer_report == report.id).execute() updated = True else: report = TrainerReportRelation.create(guild=ctx.guild.id, created=report_time_int, trainer=author.id, location=stop.id, cancelled=False) HideoutTable.create(trainer_report=report, rocket_leader=leader, first_pokemon=pokemon_ids[0], second_pokemon=pokemon_ids[1], third_pokemon=pokemon_ids[2]) updated = False hideout = self.get_single_hideout(report.id) inv_embed = await self._build_hideout_embed(ctx, hideout) listmgmt_cog = self.bot.cogs.get('ListManagement') if updated: hideout = self.get_single_hideout(report.id) message = await channel.fetch_message(hideout.message) try: await message.delete() except: pass invasionreportmsg = await channel.send( f'**Team Rocket Hideout** report at *{hideout.location_name}* updated!', embed=inv_embed) await utilities_cog.reaction_delay(invasionreportmsg, ['\u270f', '🚫']) TrainerReportRelation.update(message=invasionreportmsg.id) \ .where(TrainerReportRelation.id == report.id).execute() await listmgmt_cog.update_listing_channels(guild, 'hideout', edit=True, regions=regions) else: invasionreportmsg = await channel.send( f'**Team Rocket Hideout** reported at *{stop.name}*', embed=inv_embed) await utilities_cog.reaction_delay(invasionreportmsg, ['\u270f', '🚫']) details = {'regions': regions, 'type': 'hideout', 'location': stop} TrainerReportRelation.update(message=invasionreportmsg.id).where( TrainerReportRelation.id == report.id).execute() send_channel = subscriptions_cog.get_region_list_channel( guild, stop.region, 'invasion') if send_channel is None: send_channel = message.channel await subscriptions_cog.send_notifications_async( 'hideout', details, send_channel, [message.author.id]) await asyncio.sleep(1) await listmgmt_cog.update_listing_channels(guild, 'hideout', edit=False, regions=regions) clean_list = self.bot.guild_dict[ ctx.guild.id]['configure_dict'].setdefault('channel_auto_clean', []) if ctx.channel.id in clean_list: await ctx.message.delete()
async def modify_report(self, ctx, payload, report_id): channel = self.bot.get_channel(ctx.channel.id) try: message = await channel.fetch_message(payload.message_id) except (discord.errors.NotFound, AttributeError): return guild = message.guild try: user = guild.get_member(payload.user_id) except AttributeError: return utils_cog = self.bot.cogs.get('Utilities') regions = utils_cog.get_channel_regions(channel, 'hideout') prompt = f'Modifying details for **Team Rocket Hideout** at ' #**{stop}**\n' \ #f'Which item would you like to modify ***{user.display_name}***?' choices_list = ['Pokestop', 'Leader', 'Lineup'] match = await utils.ask_list(self.bot, prompt, channel, choices_list, user_list=user.id) if match in choices_list: updated = False report = TrainerReportRelation.get_by_id(report_id) # Changing pokestop if match == choices_list[0]: location_matching_cog = self.bot.cogs.get('LocationMatching') utils_cog = self.bot.cogs.get('Utilities') regions = utils_cog.get_channel_regions(channel, 'hideout') stops = location_matching_cog.get_stops(guild.id, regions) query_msg = await channel.send(embed=discord.Embed( colour=discord.Colour.gold(), description="What is the correct Location?")) try: stopmsg = await self.bot.wait_for( 'message', timeout=30, check=(lambda reply: reply.author == user)) except asyncio.TimeoutError: await query_msg.delete() stopmsg = None stop = None if not stopmsg: error = "took too long to respond" elif stopmsg.clean_content.lower() == "cancel": error = "cancelled the report" await stopmsg.delete() elif stopmsg: stop = await location_matching_cog.match_prompt( channel, user.id, stopmsg.clean_content, stops) if not stop: return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description= f"No pokestop found with name '**{stopmsg.clean_content}**' " f"either. Try reporting again using the exact pokestop name!" ), delete_after=15) if await self._check_existing(stop): return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description= f"A Team Rocket Hideout has already been reported for '**{stop.name}**'!" )) if stop: updated = True report.location_id = stop.id report.save() # Changing leader elif match == choices_list[1]: query_msg = await channel.send(embed=discord.Embed( colour=discord.Colour.gold(), description="What is the correct Leader?")) try: leadmsg = await self.bot.wait_for( 'message', timeout=30, check=(lambda reply: reply.author == user)) except asyncio.TimeoutError: await query_msg.delete() leadmsg = None if not leadmsg: error = "took too long to respond" elif leadmsg.clean_content.lower() == "cancel": error = "cancelled the report" await leadmsg.delete() else: if leadmsg.clean_content.lower() in self.leader_strings: updated = True report = TrainerReportRelation.get_by_id(report_id) HideoutTable.update(rocket_leader=leadmsg.clean_content.lower())\ .where(HideoutTable.trainer_report == report.id).execute() else: return await channel.send(embed=discord.Embed( colour=discord.Colour.red(), description=f"No Team Rocket Leader found with name " f"{leadmsg.clean_content}. Please start again."), delete_after=15) # Changing lineup elif match == choices_list[2]: query_msg = await channel.send(embed=discord.Embed( colour=discord.Colour.gold(), description="What is the correct Lineup?")) try: lineupmsg = await self.bot.wait_for( 'message', timeout=30, check=(lambda reply: reply.author == user)) except asyncio.TimeoutError: await query_msg.delete() lineupmsg = None if not lineupmsg: error = "took too long to respond" elif lineupmsg.clean_content.lower() == "cancel": error = "cancelled the report" await lineupmsg.delete() else: info = re.split(r',+\s+', lineupmsg.clean_content) pokemon_ids = [None] for i in info: pkmn = Pokemon.get_pokemon(self.bot, i) if pkmn is not None: if pkmn.id not in self.leader_map.values(): pokemon_ids.append(pkmn.id) if not pokemon_ids[0]: hideout = self.get_single_hideout(report.id) if hideout.leader and hideout.leader in self.leader_map: pokemon_ids[0] = self.leader_map[hideout.leader] if len(pokemon_ids) < 3: pokemon_ids = (pokemon_ids + 3 * [None])[:3] updated = True report = TrainerReportRelation.get_by_id(report_id) HideoutTable.update(first_pokemon=pokemon_ids[0], second_pokemon=pokemon_ids[1], third_pokemon=pokemon_ids[2]) \ .where(HideoutTable.trainer_report == report.id).execute() if updated: hideout = self.get_single_hideout(report.id) message = await channel.fetch_message(hideout.message) try: await message.delete() except: pass inv_embed = await self._build_hideout_embed(ctx, hideout) invasionreportmsg = await channel.send( f'**Team Rocket Hideout** report at *{hideout.location_name}* updated!', embed=inv_embed) utilities_cog = self.bot.cogs.get('Utilities') await utilities_cog.reaction_delay(invasionreportmsg, ['\u270f', '🚫']) TrainerReportRelation.update(message=invasionreportmsg.id) \ .where(TrainerReportRelation.id == report.id).execute() listmgmt_cog = self.bot.cogs.get('ListManagement') await listmgmt_cog.update_listing_channels(guild, 'hideout', edit=True, regions=regions) try: await message.remove_reaction(payload.emoji, user) except (discord.errors.NotFound): pass