2017-10-11 06:59:06 +00:00
import asyncio
import code
import io
2017-10-13 02:26:57 +00:00
import os
2017-10-11 06:59:06 +00:00
import re
import sys
import traceback as tb
import discord as d
2017-10-13 02:26:57 +00:00
import pyrasite as pyr
2017-10-11 06:59:06 +00:00
from discord . ext import commands
from misc import exceptions as exc
2017-10-13 02:26:57 +00:00
from misc import checks
from utils import utils as u
2017-10-11 06:59:06 +00:00
nl = re . compile ( ' \n ' )
2017-10-13 02:26:57 +00:00
class Bot :
2017-10-14 03:43:37 +00:00
def __init__ ( self , bot ) :
2017-10-13 02:26:57 +00:00
self . bot = bot
# Close connection to Discord - immediate offline
@commands.command ( name = ' ,die ' , aliases = [ ' ,d ' ] , brief = ' Kills the bot ' , description = ' BOT OWNER ONLY \n Closes the connection to Discord ' , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def die ( self , ctx ) :
2017-10-14 03:43:37 +00:00
if isinstance ( self . bot . get_channel ( u . config [ ' startup_channel ' ] ) , d . TextChannel ) :
await self . bot . get_channel ( u . config [ ' shutdown_channel ' ] ) . send ( ' **Shutting down...** 🌙 ' )
2017-10-13 02:26:57 +00:00
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
2017-10-14 19:29:35 +00:00
if u . session :
await u . session . close ( )
2017-10-13 02:26:57 +00:00
await self . bot . logout ( )
await self . bot . close ( )
2017-10-14 03:59:14 +00:00
print ( ' - - - - - - - ' )
2017-10-14 19:29:35 +00:00
print ( ' DISCONNECTED ' )
2017-10-13 02:26:57 +00:00
@commands.command ( name = ' ,restart ' , aliases = [ ' ,res ' , ' ,r ' ] , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def restart ( self , ctx ) :
print ( ' RESTARTING ' )
2017-10-14 03:59:14 +00:00
print ( ' - - - - - - - ' )
2017-10-14 03:43:37 +00:00
if isinstance ( self . bot . get_channel ( u . config [ ' startup_channel ' ] ) , d . TextChannel ) :
await self . bot . get_channel ( u . config [ ' shutdown_channel ' ] ) . send ( ' **Restarting...** 💤 ' )
2017-10-13 02:26:57 +00:00
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
2017-10-14 19:29:35 +00:00
if u . session :
await u . session . close ( )
2017-10-13 02:26:57 +00:00
await self . bot . logout ( )
await self . bot . close ( )
os . execl ( sys . executable , ' python3 ' , ' run.py ' )
# Invite bot to bot owner's server
@commands.command ( name = ' ,invite ' , aliases = [ ' ,inv ' , ' ,link ' ] , brief = ' Invite the bot ' , description = ' BOT OWNER ONLY \n Invite the bot to a server (Requires admin) ' , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def invite ( self , ctx ) :
2017-10-14 03:43:37 +00:00
await ctx . send ( ' 🔗 https://discordapp.com/oauth2/authorize?&client_id= {} &scope=bot&permissions= {} ' . format ( u . config [ ' client_id ' ] , u . config [ ' permissions ' ] ) , delete_after = 10 )
2017-10-13 02:26:57 +00:00
2017-10-14 01:53:44 +00:00
@commands.command ( aliases = [ ' presence ' , ' game ' ] , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def status ( self , ctx , game ) :
try :
if game is not None :
await self . bot . change_presence ( game = d . Game ( name = game ) )
else :
raise exc . NotFound
except exc . NotFound :
await ctx . send ( ' ❌ **No game given.** ' , delete_after = 10 )
2017-10-13 02:26:57 +00:00
2017-10-11 06:59:06 +00:00
class Tools :
def __init__ ( self , bot ) :
self . bot = bot
def format ( self , i = ' ' , o = ' ' ) :
2017-10-13 02:26:57 +00:00
if len ( o ) > 1 :
return ' >>> {} \n {} ' . format ( i , o )
else :
return ' >>> {} ' . format ( i )
2017-10-11 06:59:06 +00:00
async def generate ( self , d , i = ' ' , o = ' ' ) :
return await d . send ( ' ```python \n {} ``` ' . format ( self . format ( i , o ) ) )
2017-10-13 02:26:57 +00:00
2017-10-11 06:59:06 +00:00
async def refresh ( self , m , i = ' ' , o = ' ' ) :
global nl
output = m . content [ 10 : - 3 ]
2017-10-13 02:26:57 +00:00
if len ( nl . findall ( output ) ) < = 20 :
await m . edit ( content = ' ```python \n {} \n {} \n >>>``` ' . format ( output , self . format ( i , o ) ) )
else :
await m . edit ( content = ' ```python \n {} ``` ' . format ( self . format ( i , o ) ) )
2017-10-11 06:59:06 +00:00
async def generate_err ( self , d , o = ' ' ) :
return await d . send ( ' ``` \n {} ``` ' . format ( o ) )
2017-10-13 02:26:57 +00:00
2017-10-11 06:59:06 +00:00
async def refresh_err ( self , m , o = ' ' ) :
await m . edit ( content = ' ``` \n {} ``` ' . format ( o ) )
@commands.command ( name = ' ,console ' , aliases = [ ' ,con ' , ' ,c ' ] , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def console ( self , ctx ) :
def execute ( msg ) :
2017-10-14 01:53:44 +00:00
if msg . content == ' exit ' and msg . author is ctx . message . author :
raise exc . Abort
2017-10-13 02:26:57 +00:00
elif msg . author is ctx . message . author and msg . channel is ctx . message . channel :
return True
else :
return False
2017-10-11 06:59:06 +00:00
try :
console = await self . generate ( ctx )
exception = await self . generate_err ( ctx )
2017-10-13 05:24:57 +00:00
while not self . bot . is_closed ( ) :
2017-10-13 02:26:57 +00:00
try :
2017-10-14 01:53:44 +00:00
exe = await self . bot . wait_for ( ' message ' , check = execute )
except exc . Abort :
raise exc . Abort
finally :
await exe . delete ( )
try :
sys . stdout = io . StringIO ( )
sys . stderr = io . StringIO ( )
2017-10-13 02:26:57 +00:00
exec ( exe . content )
except Exception :
2017-10-14 01:53:44 +00:00
await self . refresh_err ( exception , tb . format_exc ( limit = 1 ) )
finally :
await self . refresh ( console , exe . content , sys . stdout . getvalue ( ) )
sys . stdout = sys . __stdout__
sys . stderr = sys . __stderr__
except exc . Abort :
2017-10-11 06:59:06 +00:00
await ctx . send ( ' ↩️ **Exited console.** ' )
finally :
sys . stdout = sys . __stdout__
sys . stderr = sys . __stderr__
print ( ' Reset sys output. ' )
@commands.command ( name = ' arbitrary ' , aliases = [ ' ,arbit ' , ' ,ar ' ] )
@commands.is_owner ( )
@checks.del_ctx ( )
async def arbitrary ( self , ctx , * , exe ) :
try :
sys . stdout = io . StringIO ( )
exec ( exe )
await self . generate ( ctx , exe , sys . stdout . getvalue ( ) )
except Exception :
2017-10-13 02:26:57 +00:00
await ctx . send ( ' ``` \n {} ``` ' . format ( tb . format_exc ( limit = 1 ) ) )
2017-10-11 06:59:06 +00:00
tb . print_exc ( limit = 1 )
finally :
sys . stdout = sys . __stdout__
print ( ' Reset stdout. ' )
@commands.group ( aliases = [ ' ,db ' ] , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def debug ( self , ctx ) :
console = await self . generate ( ctx )
2017-10-13 02:26:57 +00:00
2017-10-11 06:59:06 +00:00
@debug.command ( name = ' inject ' , aliases = [ ' inj ' ] )
async def _inject ( self , ctx , * , input_ ) :
pass
2017-10-13 02:26:57 +00:00
2017-10-11 06:59:06 +00:00
@debug.command ( name = ' inspect ' , aliases = [ ' ins ' ] )
async def _inspect ( self , ctx , * , input_ ) :
pass