async def version_feed(self): Message(2, '[VERSIONFEED] Version Feed Task active') while not self.bot.is_closed(): async with self.version_feed_lock: self.c.execute('SELECT * FROM apb_version_feed') servers = self.c.fetchall() versions = await utils.api_request(self.API_URL + 'version') for server in servers: try: live_version = server[2] otw_version = server[3] otw2_version = server[4] if await self.version_feed_check( live_version, versions['live']): await self.version_feed_update( versions['live'], 'live', server) if await self.version_feed_check( otw_version, versions['otw']): await self.version_feed_update( versions['otw'], 'otw', server) if await self.version_feed_check( otw2_version, versions['otw2']): await self.version_feed_update( versions['otw2'], 'otw2', server) except Exception as e: Message(3, "[VERSIONFEED] {0}".format(e)) Message(1, '[VERSIONFEED] LOOP COMPLETED (60 s)') await asyncio.sleep(60)
async def word_filter(self, msg): """ Checks message for blacklisted words / texts. 1. Get blacklisted words from db 2. check if case sensitive or not 3. Check if string is in the msg.content 4. Remove message / Keep message """ try: guildid = msg.guild.id except AttributeError: return blacklist = self.c.execute( 'SELECT Blacklisted, CaseSensitive FROM AMSBlacklist WHERE ServerID = ?', [msg.guild.id]).fetchall() for blacklisted in blacklist: try: if blacklisted[1] is 1 and blacklisted[ 0] in msg.content or blacklisted[ 1] is 0 and blacklisted[0].lower( ) in msg.content.lower(): await msg.delete() Message( 1, '[BLACKLIST][{0.guild}] REMOVED MESSAGE | USER {0.author} ({0.author.id}) ' .format(msg)) except discord.Forbidden: Message( 3, '[BLACKLIST][{0.guild}] NO PERMISSIONS : {0.channel} ({0.channel.id})' .format(msg))
async def add_user(self, ctx, user_id): try: self.c.execute('INSERT INTO users (ID) VALUES (?)', [user_id]) except Exception as e: await ctx.send(embed=discord.Embed(title='Error', description=str(e))) else: Message(2, '[DATABASE][ADD] USER : {}'.format(user_id))
async def bg_game_update(self): Message(2, '[GAMEUPDATE] Game Update Task active') while not self.bot.is_closed(): async with self.bg_game_update_lock: users, guilds = await self.get_users_and_guilds() GAMELIST = [ "apbvault.net", 'Use {}help'.format(PREFIX), '{}db [query]'.format(PREFIX), '{} users'.format(users), '{} guilds'.format(guilds) ] game = discord.Game(random.choice(GAMELIST)) await self.bot.change_presence(status=discord.Status.online, activity=game) Message(1, '[GAMEUPDATE] LOOP COMPLETED (900 s)') await asyncio.sleep(900)
def setup(bot): if ext is True: bot.add_cog(Imgur(bot)) else: Message( 2, '[EXTENSION] "imgur" not loaded. Missing imgurpython! (pip install imgurpython)' ) raise ImportError
def setup(bot): if ext is True: bot.add_cog(PUBG(bot)) else: Message( 2, '[EXTENSION] "pubg" not loaded. Missing pypubg! (pip install pypubg)' ) raise ImportError
async def _activitylog_remove(self, ctx): try: self.c.execute('UPDATE servers SET ActivityLogChannel = ? WHERE ID = ?', (0, ctx.message.guild.id)) except Exception as e: Message(3, '[ACTIVITYLOG]: {}'.format(e)) else: self.connection.commit() await ctx.send(embed=discord.Embed( title='Activity Log Channel', color=0xf4f142, description='Activity log channel was removed from this server!' ))
async def _admin_shutdown(self, ctx): """Shuts the bot down - Closes database connection - Logs out of Discord - Closes the bot """ await ctx.send(embed=discord.Embed(title='Bot Shutting Down...')) Message(2, '[BOT] Shutting down. Closing services...') self.connection.close() await self.bot.logout() await self.bot.close()
async def twitch_notify(self): Message(2, "[TWITCH] Notifier loop active") while not self.bot.is_closed(): async with self.notifier_task_lock: self.c.execute('SELECT * FROM servers') guilds = self.c.fetchall() for guild in guilds: srv = self.bot.get_guild(int(guild[0])) if guild[2] is not 0: try: Message(1, "[TWITCH] Guild {0} found.".format(srv)) self.c.execute( 'SELECT UserID FROM twitch WHERE ServerID = ?', [srv.id]) users = self.c.fetchall() Message( 1, "[TWITCH] Found {0} channels in guild {1}.". format(len(users), srv)) for user in users: stream = await self.get_stream(user[0]) if stream != None: if await self.twitch_notify_update( srv.id, stream) is True: Message( 1, "[TWITCH] Stream {0} live. Broadcasting..." .format(stream['channel'] ['display_name'])) await self.twitch_notify_message( stream, guild[2]) except Exception as e: Message(3, "[TWITICH] {}".format(e)) Message(1, "[TWITCH] Notifier loop completed (120 s)") await asyncio.sleep(120)
async def _status_username(self, ctx, *, username: str): """Update bot username""" try: self.c.execute('UPDATE bot SET UserName = ? WHERE ID = 0', [username]) await self.bot.user.edit(username=username) self.c.execute('UDPATE bot SET UserName = ?', [username]) except Exception as e: await ctx.send(discord.Embed(title='Error', description=str(e))) else: self.connection.commit() Message(2, '[BOT]Username updated to "{}"'.format(username)) await ctx.send(embed=discord.Embed( title='Username Update', description='"{}"'.format(username)))
async def _status_prefix(self, ctx, *, prefix: str): """Update bot prefix !!! NOT USED/WORKING RIGHT NOW !!! """ try: self.c.execute('UPDATE bot SET DefaultPrefix = ?', [prefix]) except Exception as e: await ctx.send(embed=discord.Embed( title='Error', description=str(e), color=0xFF0000)) else: self.connection.commit() Message(2, '[BOT]Status prefix updated to "{}"'.format(prefix)) await ctx.send(embed=discord.Embed( title='Prefix Update', description='"{}"'.format(prefix)))
async def _status_game(self, ctx, *, game: str): """Update bot game name""" try: self.c.execute('UPDATE bot SET DefaultGame = ? WHERE ID = 0', [game]) await self.bot.change_presence(game=discord.Game(name=game)) self.c.execute('UPDATE bot SET DefaultGame = ?', [game]) except Exception as e: await ctx.send(embed=discord.Embed( title='Error', description=str(e), color=0xFF0000)) else: self.connection.commit() Message(2, '[BOT]Status game updated to "{}"'.format(game)) await ctx.send(embed=discord.Embed( title='Game Update', description='"{}"'.format(game)))
async def on_command_error(ctx, error): if type(error).__name__ == 'CommandNotFound': return Message(3, '[COMMAND] {0.command} : {1}'.format(ctx, error)) if ctx.guild is not None: fmt = '**{0.guild} ({0.guild.id})**\n'\ '{0.author} ({0.author.id})\n\n'.format(ctx) else: fmt = '**{0.author} ({0.author.id})**\n\n'.format(ctx) fmt += 'Error in command "{0.command}"\n'\ '{1}'.format(ctx, error) user = bot.get_user(OWNER_ID) await user.send(fmt)
async def twitch_notify_message(self, stream, channel_id): try: channel = self.bot.get_channel(int(channel_id)) e = discord.Embed(title='Now Live: {}'.format( stream['channel']['display_name']), description=await self.twitch_filter(stream['channel']['status']), url=stream['channel']['url'], timestamp=stream['created_at'], color=0x6441A5) e.set_author(name='Twitch Alert', icon_url=self.TWITCH_LOGO) e.set_thumbnail(url=stream['channel']['logo']) e.add_field(name='Playing', value=stream['game']) e.set_footer(text='Stream started') await channel.send(embed=e) except Exception as e: Message(3, '[TWITCH] {}'.format(e))
async def version_feed_update(self, version, patch_server, server): try: self.c.execute( 'UPDATE apb_version_feed SET Version{0} = "{1}" WHERE ID = {2}' .format(patch_server, version, server[0])) e = discord.Embed( title='{0} Client Update'.format(patch_server.upper()), description='Client version updated to {0}'.format(version), color=0xFF0000, timestamp=datetime.now()) channel = self.bot.get_channel(int(server[1])) except Exception as e: Message(3, "[VERSIONFEED]".format(e)) else: self.connection.commit() await channel.send(embed=e)
async def log_message(self, msg): try: guildid = msg.guild.id except: guildid = 0 if len(msg.embeds) > 0: isembed = True else: isembed = False try: self.c.execute( 'INSERT INTO AMSlog VALUES (?,?,?,?,?,?,?,?)', (msg.id, guildid, msg.channel.id, msg.author.id, msg.content, msg.mention_everyone, msg.created_at, isembed)) self.connection.commit() except sqlite3.OperationalError: Message(3, '[AMS] DATABASE LOCKED!')
async def _status_avatar(self, ctx, *, image_link: str): """Update bot avatar image""" try: with aiohttp.ClientSession() as session: async with session.get(image_link) as resp: await self.bot.user.edit(avatar=await resp.read()) self.c.execute('UPDATE bot SET Avatar = ?', [image_link]) except ValueError as e: await ctx.send(embed=discord.Embed( title='Error: Image Error', description=str(e), color=0xFF0000) ) except Exception as e: await ctx.send(embed=discord.Embed( title='Error', description=e, color=0xFF0000)) else: self.connection.commit() Message(2, '[BOT]Avatar image updated.') await ctx.send(embed=discord.Embed(title='Avatar Image Updated'))
async def _fix(self, ctx): try: self.c.execute('INSERT INTO servers VALUES (?, ?, 0, 0, 1)', (ctx.message.guild.id, ctx.message.guild.name)) except sqlite3.IntegrityError as e: await ctx.send(embed=discord.Embed( title='Done', description='Server **{0.name}** is already in the database.'.format(ctx.message.guild), color=0x00FF00 )) except Exception as e: await ctx.send(embed=await embeds.default_exception(e)) else: self.connection.commit() Message(2, '[DATABASE][ADD][GUILD] {0.id} : {0.name}'.format(ctx.message.guild)) await ctx.send(embed=discord.Embed( title='Server readded', description='Server {0.name} readded to database.'.format(ctx.message.guild), color=0x00FF00 ))
async def timeout_check(self): Message(2, '[TIMEOUT] Timeout check active') while not self.bot.is_closed(): async with self.timeout_lock: self.c.execute('SELECT * FROM timeouts WHERE Enabled = 1') timeouts = self.c.fetchall() if len(timeouts) > 0: for timeout in timeouts: try: guild = self.bot.get_guild(int(timeout[1])) if guild is None: Message(3, '[TIMEOUT] Guild not found (ID: {}) | Removing server entries...'.format(str(timeout[1]))) self.c.execute('DELETE FROM timeouts WHERE ServerID = ?', [timeout[1]]) continue member = guild.get_member(int(timeout[2])) timeout_time = datetime.strptime(timeout[3], '%Y-%m-%d %H:%M:%S') + timedelta(minutes=timeout[4]) if member is not None: role = discord.utils.get(guild.roles, name='Blocked') if role is None: Message(2, '[TIMEOUT][{0}] ({0.id}) has no Blocked role. Removing timeout...'.format(guild)) self.c.execute('UPDATE timeouts SET Enabled = 0 WHERE ID = ?', [timeout[0]]) continue Message(1, '[TIMEOUT][{0}] MEMBER {1} | TIME {2}'.format(guild, member, timeout_time)) if timeout_time <= datetime.now(): await member.remove_roles(role) self.c.execute('UPDATE timeouts SET Enabled = 0 WHERE ID = ?', [timeout[0]]) else: await member.add_roles(role) else: if timeout_time <= datetime.now(): self.c.execute('UPDATE timeouts SET Enabled = 0 WHERE ID = ?', [timeout[0]]) Message(2, '[TIMEOUT][{0}] Removed missing member: {1} (timeout finished)'.format(guild, timeout[2])) except Exception as e: Message(3, '[TIMEOUT] {}'.format(e)) finally: self.connection.commit() Message(1, '[TIMEOUT] LOOP COMPLETED (15 s)') await asyncio.sleep(15)
async def on_ready(): Message(2, '[BOT] {0.name} : {0.id}'.format(bot.user)) Message(2, '[BOT]Library: Discord.py {}'.format(discord.__version__)) Message( 2, '[EXTENSION]Loading {0} extensions. Please wait...'.format(len(EXTS))) for ext in EXTS: try: bot.load_extension('ext.' + ext) Message(2, '[EXTENSION] "{0}" loaded.'.format(ext)) except ImportError as e: pass except Exception as e: Message( 3, '[EXTENSION]Failed to initialize extension "{}". Error: {}'. format(ext, e)) Message(2, '[EXTENSION]Loading complete.')
async def console_message(self, msg): Message( 1, '[AMS] {0.created_at} | ID : {0.id} | {0.guild} ({0.guild.id}) | {0.author} ({0.author.id}) | EVERYONE : {0.mention_everyone} | MESSAGE : "{0.content}"' .format(msg))
async def on_guild_join(guild): Message(2, '[BOT] Joined guild {0.name} : {0.id}'.format(guild)) Utils.add_guild(guild)
async def on_guild_remove(guild): Message(2, '[BOT] Left guild {0.name} : {0.id}'.format(guild)) Utils.del_guild(guild)
async def timeout_user(self, ctx, member: discord.Member, amount: int, *, reason: str = 'None'): """Timeout a user you don't like - Adds the "Blocked" role to the user - Adds an entry to the "timeouts" table if not exists already - Adds one point to the global timeout count - Adds one point to the server timeout count if user was timed out before """ try: role = discord.utils.get(ctx.message.guild.roles, name='Blocked') if role: self.c.execute('SELECT TimeoutCount FROM timeouts WHERE MemberID = ? AND ServerID = ?', (member.id, ctx.message.guild.id)) result = self.c.fetchone() if result is None: self.c.execute('SELECT MAX(ID) FROM timeouts') max_id = self.c.fetchone() next_id = 0 if max_id[0] is None else int(max_id[0]) + 1 self.c.execute('INSERT INTO timeouts VALUES ' '(?, ?, ?, ?, ?, 1, 1)', (next_id, ctx.message.guild.id, member.id, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), amount)) else: self.c.execute('UPDATE timeouts ' 'SET TimeoutTime = ?, TimeInMinutes = ?, TimeoutCount = (? + 1), ' 'Enabled = 1 ' 'WHERE ServerID = ? AND MemberID = ?', (datetime.now().strftime("%Y-%m-%d %H:%M:%S"), amount, result[0], ctx.message.guild.id, member.id)) update ='UPDATE users SET TimeoutCount = ((SELECT TimeoutCount FROM users WHERE ID = ?) + 1) WHERE ID = ?' if await self.user_exists(ctx, member.id) is True: self.c.execute(update, (member.id, member.id)) else: await self.add_user(ctx, member.id) self.c.execute(update, (member.id, member.id)) await member.add_roles(role) else: await ctx.send(embed=discord.Embed( title='Role Error', description='Blocked role is missing on this server!' )) except Exception as e: await ctx.send(embed=await embeds.default_exception(e)) else: self.connection.commit() await ctx.send(embed=discord.Embed( title='Timeout', description='User {0} is now silenced for {1} minutes'.format(member, amount) )) try: e = discord.Embed( title='Timeout', description='You got timed out for **{}** minutes on {}!\n**Reason**: {}'.format(amount, ctx.message.guild, reason), color=0xf4f142, timestamp=datetime.now() ) e.set_footer(text=ctx.message.author, icon_url=ctx.message.author.avatar_url) await member.send(embed=e) channelid = await self.get_activitylog_channel(ctx.message.guild.id) if channelid is not None: channel = ctx.message.guild.get_channel(channelid) e = discord.Embed( title='Timeout', description='{} got timed out for **{}** minutes!\n**Reason**: {}'.format(member, amount, reason), color=0xf4f142, timestamp=datetime.now() ) e.set_footer(text=ctx.message.author, icon_url=ctx.message.author.avatar_url) await channel.send(embed=e) except discord.errors.NotFound as e: Message(3, '[TIMEOUT][LOG] {}'.format(e))
async def on_guild_unavailable(guild): Message(2, '[BOT] Guild {0.name} : {0.id} is unavailable!'.format(guild))
async def news_feed(self): Message(2, '[NEWSFEED] APB News Feed active') while not self.bot.is_closed(): self.c.execute( 'SELECT ID, ChannelID, PostID, ShowMods FROM apb_news_feed') servers = self.c.fetchall() Message(1, "[NEWSFEED] Checking {0} guilds".format(len(servers))) for server in servers: Message( 1, "[NEWSFEED] Trying to get guild with ID {}.".format( int(server[0]))) guild = self.bot.get_guild(int(server[0])) if guild is None: Message(3, "[NEWSFEED] Guild {} not found.".format(server[0])) continue if int(server[1]) is not 0: Message( 1, "[NEWSFEED][{1}] Getting channel: {0} ".format( server[1], guild)) try: channel = guild.get_channel(int(server[1])) except discord.NotFound: continue if channel is None: Message( 3, "[NEWSFEED][{0}] Could not get channel.".format( guild)) continue else: continue Message( 1, "[NEWSFEED][{0}] Channel found: {1}".format( guild, channel)) postID = server[2] mods = server[3] if mods is 0: request_url = self.API_URL + 'tracker?mod=False¤tid={}&limit=1000'.format( postID) else: request_url = self.API_URL + 'tracker?currentid={}&limit=1000'.format( postID) Message( 1, "[NEWSFEED][{0}] Attempting API request: {1}".format( guild, request_url)) posts = [] posts = await utils.api_request(request_url) try: if posts > 200 and posts < 200: Message( 3, "[NEWSFEED]Request did not return JSON. Status: {}" .format(posts)) continue except: pass if len(posts) > 0 and not isinstance(posts, int): Message( 1, '[NEWSFEED][{0}] Processing {1} new posts'.format( guild, len(posts))) for post in reversed(posts): # separate the quote message and the admin message with BeautifulSoup soup = BeautifulSoup(post['content'], 'html.parser') desc_quote = soup.find('blockquote') if desc_quote is not None: desc_quote = soup.find('blockquote').get_text() for tag in soup.find_all('blockquote'): tag.replaceWith('') desc_admin = soup.find( 'div', attrs={ "class", "ipsType_break ipsType_richText ipsContained" }).get_text() else: desc_admin = soup.find( 'div', attrs={ "class", "ipsType_break ipsType_richText ipsContained" }).get_text() # Remove HTMl and non-ASCII symbols desc_admin = await self.rem_color_code(desc_admin) desc_admin = (''.join( [i if ord(i) < 128 else '' for i in desc_admin])) desc_admin = re.sub("\s\s+", " ", desc_admin) # combine final description (only admin rn) desc = desc_admin # Check if message is too long > add "Read more..." with link if too long if len(desc) >= 1000: desc = desc[:1000] desc += '\n [Read more...]({})'.format( post['postlink']) e = discord.Embed(title=post['threadname'], description=desc, url=post['threadlink'], color=0xFF0000, timestamp=datetime.strptime( post['pubdate'], "%Y-%m-%dT%H:%M:%SZ")) e.set_author( name=post['author']['name'], url=post['author']['profilelink'], icon_url=post['author']['imagelink'].replace( '//forums-cdn', 'https://forums-cdn')) try: await channel.send(embed=e) except discord.Forbidden: Message( 3, "[NEWSFEED][{0}] No permissions in {1}".format( guild, channel)) continue except discord.HTTPException as e: Message( 3, "[NEWSFEED][{0}] HTTPError: {1}".format( guild, str(e))) continue else: await asyncio.sleep(1) self.c.execute( 'UPDATE apb_news_feed SET PostID = ? WHERE ID = ?', (post['id'], server[0])) self.connection.commit() Message(1, '[NEWSFEED] LOOP COMPLETED (90 s)') await asyncio.sleep(90)