async def scrawl(self, threads=5): logger.log('Scrawling Trackemon..', 'green') await self.client.wait_until_ready() # get arrays channels id need to post shout_out_channels = [] for server in self.client.servers: for channel in server.channels: if channel.name in self.config.get('scrawl_channels', []): shout_out_channels.append(discord.Object(channel.id)) if len(shout_out_channels) == 0: raise Exception("No channel to shout out!") while not self.client.is_closed: logger.log('Scrawling Trackemon..', 'green') self._retrieve_session_id() # use multiprocessing if 'pokemons' in self.config.get('scrawl_trackemon'): pokemon_names = self.config.get('scrawl_trackemon')['pokemons'] pool = ThreadPool(threads) messages = pool.starmap(self.scrawl_trackemon, zip( pokemon_names, itertools.repeat(self.session_id))) for message in messages: if len(message): for channel in shout_out_channels: await self.client.send_message(channel, message) # increase delay to finish task await asyncio.sleep(self.config.get('delay_scrawl', 300))
async def announcement(self): logger.log('Posting announcements..') announcement = self.config.get('announcement') message = announcement.get('message', None) delay = announcement.get('delay', 300) if not message: logger.log('Please config your announcement message', 'red') return await self.client.wait_until_ready() # get arrays channels id need to post announcement_channels = [] for server in self.client.servers: for channel in server.channels: if channel.name in self.config.get('channels', []): announcement_channels.append(discord.Object(channel.id)) while not self.client.is_closed: for channel in announcement_channels: await self.client.send_message(channel, message) await asyncio.sleep(delay)
def need_to_delete(self, message): except_roles = self.config.get('except_roles', []) # Do nothing if bot is sending message if message.author == self.client.user: return False """ Ignore if message from except roles """ for role in message.author.roles: if role.name in except_roles: return False """ Check if message contains lat/long & pokemon name """ pattern = "^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)(?=.*(Bulbasaur|bulbasaur|Ivysaur|ivysaur|Venusaur|venusaur|Charmander|charmander|Charmeleon|charmeleon|Charizard|charizard|Squirtle|squirtle|Wartortle|wartortle|Blastoise|blastoise|Caterpie|caterpie|Metapod|metapod|Butterfree|butterfree|Weedle|weedle|Kakuna|kakuna|Beedrill|beedrill|Pidgey|pidgey|Pidgeotto|pidgeotto|Pidgeot|pidgeot|Rattata|rattata|Raticate|raticate|Spearow|spearow|Fearow|fearow|Ekans|ekans|Arbok|arbok|Pikachu|pikachu|Raichu|raichu|Sandshrew|sandshrew|Sandslash|sandslash|Nidoran F|nidoran f|Nidorina|nidorina|Nidoqueen|nidoqueen|Nidoran M|nidoran m|Nidorino|nidorino|Nidoking|nidoking|Clefairy|clefairy|Clefable|clefable|Vulpix|vulpix|Ninetales|ninetales|Jigglypuff|jigglypuff|Wigglytuff|wigglytuff|Zubat|zubat|Golbat|golbat|Oddish|oddish|Gloom|gloom|Vileplume|vileplume|Paras|paras|Parasect|parasect|Venonat|venonat|Venomoth|venomoth|Diglett|diglett|Dugtrio|dugtrio|Meowth|meowth|Persian|persian|Psyduck|psyduck|Golduck|golduck|Mankey|mankey|Primeape|primeape|Growlithe|growlithe|Arcanine|arcanine|Poliwag|poliwag|Poliwhirl|poliwhirl|Poliwrath|poliwrath|Abra|abra|Kadabra|kadabra|Alakazam|alakazam|Machop|machop|Machoke|machoke|Machamp|machamp|Bellsprout|bellsprout|Weepinbell|weepinbell|Victreebel|victreebel|Tentacool|tentacool|Tentacruel|tentacruel|Geodude|geodude|Graveler|graveler|Golem|golem|Ponyta|ponyta|Rapidash|rapidash|Slowpoke|slowpoke|Slowbro|slowbro|Magnemite|magnemite|Magneton|magneton|Farfetchd|farfetchd|Doduo|doduo|Dodrio|dodrio|Seel|seel|Dewgong|dewgong|Grimer|grimer|Muk|muk|Shellder|shellder|Cloyster|cloyster|Gastly|gastly|Haunter|haunter|Gengar|gengar|Onix|onix|Drowzee|drowzee|Hypno|hypno|Krabby|krabby|Kingler|kingler|Voltorb|voltorb|Electrode|electrode|Exeggcute|exeggcute|Exeggutor|exeggutor|Cubone|cubone|Marowak|marowak|Hitmonlee|hitmonlee|Hitmonchan|hitmonchan|Lickitung|lickitung|Koffing|koffing|Weezing|weezing|Rhyhorn|rhyhorn|Rhydon|rhydon|Chansey|chansey|Tangela|tangela|Kangaskhan|kangaskhan|Horsea|horsea|Seadra|seadra|Goldeen|goldeen|Seaking|seaking|Staryu|staryu|Starmie|starmie|MrMime|mrmime|Scyther|scyther|Jynx|jynx|Electabuzz|electabuzz|Magmar|magmar|Pinsir|pinsir|Tauros|tauros|Magikarp|magikarp|Gyarados|gyarados|Lapras|lapras|Ditto|ditto|Eevee|eevee|Vaporeon|vaporeon|Jolteon|jolteon|Flareon|flareon|Porygon|porygon|Omanyte|omanyte|Omastar|omastar|Kabuto|kabuto|Kabutops|kabutops|Aerodactyl|aerodactyl|Snorlax|snorlax|Articuno|articuno|Zapdos|zapdos|Moltres|moltres|Dratini|dratini|Dragonair|dragonair|Dragonite|dragonite|Mewtwo|mewtwo|Mew|mew)).*$" reverse_pattern = "^(Bulbasaur|bulbasaur|Ivysaur|ivysaur|Venusaur|venusaur|Charmander|charmander|Charmeleon|charmeleon|Charizard|charizard|Squirtle|squirtle|Wartortle|wartortle|Blastoise|blastoise|Caterpie|caterpie|Metapod|metapod|Butterfree|butterfree|Weedle|weedle|Kakuna|kakuna|Beedrill|beedrill|Pidgey|pidgey|Pidgeotto|pidgeotto|Pidgeot|pidgeot|Rattata|rattata|Raticate|raticate|Spearow|spearow|Fearow|fearow|Ekans|ekans|Arbok|arbok|Pikachu|pikachu|Raichu|raichu|Sandshrew|sandshrew|Sandslash|sandslash|Nidoran F|nidoran f|Nidorina|nidorina|Nidoqueen|nidoqueen|Nidoran M|nidoran m|Nidorino|nidorino|Nidoking|nidoking|Clefairy|clefairy|Clefable|clefable|Vulpix|vulpix|Ninetales|ninetales|Jigglypuff|jigglypuff|Wigglytuff|wigglytuff|Zubat|zubat|Golbat|golbat|Oddish|oddish|Gloom|gloom|Vileplume|vileplume|Paras|paras|Parasect|parasect|Venonat|venonat|Venomoth|venomoth|Diglett|diglett|Dugtrio|dugtrio|Meowth|meowth|Persian|persian|Psyduck|psyduck|Golduck|golduck|Mankey|mankey|Primeape|primeape|Growlithe|growlithe|Arcanine|arcanine|Poliwag|poliwag|Poliwhirl|poliwhirl|Poliwrath|poliwrath|Abra|abra|Kadabra|kadabra|Alakazam|alakazam|Machop|machop|Machoke|machoke|Machamp|machamp|Bellsprout|bellsprout|Weepinbell|weepinbell|Victreebel|victreebel|Tentacool|tentacool|Tentacruel|tentacruel|Geodude|geodude|Graveler|graveler|Golem|golem|Ponyta|ponyta|Rapidash|rapidash|Slowpoke|slowpoke|Slowbro|slowbro|Magnemite|magnemite|Magneton|magneton|Farfetchd|farfetchd|Doduo|doduo|Dodrio|dodrio|Seel|seel|Dewgong|dewgong|Grimer|grimer|Muk|muk|Shellder|shellder|Cloyster|cloyster|Gastly|gastly|Haunter|haunter|Gengar|gengar|Onix|onix|Drowzee|drowzee|Hypno|hypno|Krabby|krabby|Kingler|kingler|Voltorb|voltorb|Electrode|electrode|Exeggcute|exeggcute|Exeggutor|exeggutor|Cubone|cubone|Marowak|marowak|Hitmonlee|hitmonlee|Hitmonchan|hitmonchan|Lickitung|lickitung|Koffing|koffing|Weezing|weezing|Rhyhorn|rhyhorn|Rhydon|rhydon|Chansey|chansey|Tangela|tangela|Kangaskhan|kangaskhan|Horsea|horsea|Seadra|seadra|Goldeen|goldeen|Seaking|seaking|Staryu|staryu|Starmie|starmie|MrMime|mrmime|Scyther|scyther|Jynx|jynx|Electabuzz|electabuzz|Magmar|magmar|Pinsir|pinsir|Tauros|tauros|Magikarp|magikarp|Gyarados|gyarados|Lapras|lapras|Ditto|ditto|Eevee|eevee|Vaporeon|vaporeon|Jolteon|jolteon|Flareon|flareon|Porygon|porygon|Omanyte|omanyte|Omastar|omastar|Kabuto|kabuto|Kabutops|kabutops|Aerodactyl|aerodactyl|Snorlax|snorlax|Articuno|articuno|Zapdos|zapdos|Moltres|moltres|Dratini|dratini|Dragonair|dragonair|Dragonite|dragonite|Mewtwo|mewtwo|Mew|mew)(?=.*(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)).*$" # Manage channel rare_spottings only if message.channel.name in self.config.get('channels', []): if not (re.match(pattern, message.content) or re.match( reverse_pattern, message.content)) or self._is_blacklisted( message.content): if self._is_whitelisted(message.content): return False # Log & print out log_message = 'Message has been deleted: {} - Author: {}'.format( message.content, message.author.name) logger.log(log_message) logging.warning(log_message) # Delete message return True
def _retrieve_session_id(self, delay=5): if not self.session_id: # get trackemon session session_id = self._get_trackemon_session() if not session_id: logger.log( 'Cannot retrieve session id for Trackemon.. Trying again', 'red') time.sleep(delay) return self._retrieve_session_id() else: self.session_id = session_id
async def on_ready(): """ Connected to bot """ logger.log('Logged in as') logger.log(client.user.name) logger.log(client.user.id) logger.log('------')
def scrawl_trackemon(self, pokemon_name, session_id): """ Scrawl api from trackemon.com """ session = self.bot.session api_root = 'http://www.trackemon.com/' # get pokemon id try: pokemon_id = getattr(Pokemon, pokemon_name.upper()).value except AttributeError: logger.log('Wrong pokemon name', 'red') sys.exit() api_endpoint = '{}fetch/rare?pokedexTypeId={}&sessionId={}' endpoint = api_endpoint.format(api_root, pokemon_id, session_id) logger.log(endpoint) try: response = session.get(endpoint) data = response.json() except: logger.log('Api is busy') return '' if not data: logger.log('There is no {}'.format(pokemon_name), 'yellow') else: logger.log('There are {} {}(s)'.format( len(data), pokemon_name), 'blue') message = '' for pokemon in data: expire_seconds = int(pokemon['expirationTime']) - time.time() # format message message += '`{}` {},{} - Expires in: {:.0f} seconds \n'.format( self._get_pokemon_name(pokemon['pokedexTypeId']), pokemon['latitude'], pokemon['longitude'], expire_seconds ) return message
def _get_trackemon_session(self): session = self.bot.session # get session_id by fetching root first_response = session.get('http://www.trackemon.com/') pattern = re.compile(r'sessionId\s=\s\'\w+\'') session_id_string = re.search( pattern, first_response.content.decode('utf-8')) if session_id_string: # Found string, split session id session_id = session_id_string.group().replace( 'sessionId = ', '').replace('\'', '') else: logger.log( 'Can\'t retrieve session id for api. Waiting for next scrawl..') # init session again return None return session_id
def scrawl_trackemon(self, pokemon_name, session_id): """ Scrawl api from trackemon.com """ session = self.bot.session api_root = 'http://www.trackemon.com/' # get pokemon id try: pokemon_id = getattr(Pokemon, pokemon_name.upper()).value except AttributeError: logger.log('Wrong pokemon name', 'red') sys.exit() api_endpoint = '{}fetch/rare?pokedexTypeId={}&sessionId={}' endpoint = api_endpoint.format(api_root, pokemon_id, session_id) logger.log(endpoint) try: response = session.get(endpoint) data = response.json() except: logger.log('Api is busy') return '' if not data: logger.log('There is no {}'.format(pokemon_name), 'yellow') else: logger.log('There are {} {}(s)'.format(len(data), pokemon_name), 'blue') message = '' for pokemon in data: expire_seconds = int(pokemon['expirationTime']) - time.time() # format message message += '`{}` {},{} - Expires in: {:.0f} seconds \n'.format( self._get_pokemon_name(pokemon['pokedexTypeId']), pokemon['latitude'], pokemon['longitude'], expire_seconds) return message
def _get_trackemon_session(self): session = self.bot.session # get session_id by fetching root first_response = session.get('http://www.trackemon.com/') pattern = re.compile(r'sessionId\s=\s\'\w+\'') session_id_string = re.search(pattern, first_response.content.decode('utf-8')) if session_id_string: # Found string, split session id session_id = session_id_string.group().replace('sessionId = ', '').replace( '\'', '') else: logger.log( 'Can\'t retrieve session id for api. Waiting for next scrawl..' ) # init session again return None return session_id
async def scrawl(self): await self.client.wait_until_ready() # get arrays channels id need to post shout_out_channels = [] for server in self.client.servers: for channel in server.channels: if channel.name in self.config.get('scrawl_channels', []): shout_out_channels.append(discord.Object(channel.id)) if len(shout_out_channels) == 0: raise Exception("No channel to shout out!") while not self.client.is_closed: logger.log('Scrawling PokeSnipers..', 'green') # Use scraper to bypass cloudflare ddos protection scraper = cfscrape.create_scraper() json_string = scraper.get( 'http://pokesnipers.com/api/v1/pokemon.json').content data = json.loads(json_string.decode('utf-8')) logger.log('Got {} pokemons from PokeSnipers'.format( len(data.get('results'))), 'blue') message = '' for pokemon in data.get('results'): until = time.mktime(time.strptime(pokemon.get('until'), '%Y-%m-%dT%H:%M:%S.%fZ')) # use utc timezone for pokesnipers expire_seconds = until - datetime.datetime.utcnow().timestamp() message += "`{}` {} - Expires in: {:.0f} seconds\n".format(pokemon.get('name'), pokemon.get('coords'), expire_seconds) if len(message): for channel in shout_out_channels: await self.client.send_message(channel, message) await asyncio.sleep(self.config.get('delay_scrawl', 300))
async def scrawl(self, threads=5): logger.log('Scrawling Trackemon..', 'green') await self.client.wait_until_ready() # get arrays channels id need to post shout_out_channels = [] for server in self.client.servers: for channel in server.channels: if channel.name in self.config.get('scrawl_channels', []): shout_out_channels.append(discord.Object(channel.id)) if len(shout_out_channels) == 0: raise Exception("No channel to shout out!") while not self.client.is_closed: logger.log('Scrawling Trackemon..', 'green') self._retrieve_session_id() # use multiprocessing if 'pokemons' in self.config.get('scrawl_trackemon'): pokemon_names = self.config.get('scrawl_trackemon')['pokemons'] pool = ThreadPool(threads) messages = pool.starmap( self.scrawl_trackemon, zip(pokemon_names, itertools.repeat(self.session_id))) for message in messages: if len(message): for channel in shout_out_channels: await self.client.send_message(channel, message) # increase delay to finish task await asyncio.sleep(self.config.get('delay_scrawl', 300))