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-16 19:51:33 +00:00
await ctx . message . add_reaction ( ' 🌙 ' )
2017-10-17 03:47:02 +00:00
await self . bot . get_channel ( u . config [ ' info_channel ' ] ) . send ( ' **Shutting down** 🌙 . . . ' )
2017-10-13 02:26:57 +00:00
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self . bot . logout ( )
2017-10-15 16:58:16 +00:00
u . close ( self . bot . loop )
2017-10-15 01:52:21 +00:00
print ( ' \n / / / / / / / / / / / / \n D I S C O N N E C T E D \n \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \n ' )
# u.notify('D I S C O N N E C T E D')
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 ) :
2017-10-16 19:51:33 +00:00
await ctx . message . add_reaction ( ' 💤 ' )
2017-10-15 01:52:21 +00:00
print ( ' \n | | | | | | | | | | \n R E S T A R T I N G \n | | | | | | | | | | \n ' )
2017-10-17 03:47:02 +00:00
await self . bot . get_channel ( u . config [ ' info_channel ' ] ) . send ( ' **Restarting** 💤 . . . ' )
# u.notify('R E S T A R T I N G')
2017-10-16 20:52:54 +00:00
u . temp [ ' restart_ch ' ] = ctx . channel . id
u . temp [ ' restart_msg ' ] = ctx . message . id
u . dump ( u . temp , ' temp/temp.pkl ' )
2017-10-13 02:26:57 +00:00
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self . bot . logout ( )
2017-10-15 16:58:16 +00:00
u . close ( self . bot . loop )
2017-10-13 02:26:57 +00:00
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-16 19:51:33 +00:00
await ctx . message . add_reaction ( ' ✉️ ' )
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-16 18:07:10 +00:00
@commands.command ( name = ' ,status ' , aliases = [ ' ,presence ' , ' ,game ' ] , hidden = True )
2017-10-14 01:53:44 +00:00
@commands.is_owner ( )
@checks.del_ctx ( )
2017-10-16 18:07:10 +00:00
async def status ( self , ctx , * , game = None ) :
if game is not None :
await self . bot . change_presence ( game = d . Game ( name = game ) )
u . config [ ' playing ' ] = game
u . dump ( u . config , ' config.json ' , json = True )
else :
await self . bot . change_presence ( game = None )
u . config [ ' playing ' ] = ' None '
u . dump ( u . config , ' config.json ' , json = True )
2017-10-16 22:50:27 +00:00
await ctx . message . add_reaction ( ' ✅ ' )
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
2017-10-17 03:47:02 +00:00
output = m . content [ 10 : - 2 ]
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-15 01:52:21 +00:00
if msg . content == ' exit ' and msg . author is ctx . author :
2017-10-14 01:53:44 +00:00
raise exc . Abort
2017-10-15 01:52:21 +00:00
elif msg . author is ctx . author and msg . channel is ctx . channel :
2017-10-13 02:26:57 +00:00
return True
else :
return False
2017-10-11 06:59:06 +00:00
try :
2017-10-16 19:51:33 +00:00
await ctx . message . add_reaction ( ' ✅ ' )
2017-10-11 06:59:06 +00:00
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
2017-10-17 03:47:02 +00:00
await exe . delete ( )
2017-10-14 01:53:44 +00:00
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 :
2017-10-16 19:51:33 +00:00
await ctx . message . add_reaction ( ' ✅ ' )
2017-10-11 06:59:06 +00:00
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