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
2017-10-20 20:24:43 +00:00
from contextlib import suppress
2017-10-11 06:59:06 +00:00
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
2017-10-13 02:26:57 +00:00
class Bot :
2017-10-20 20:24:43 +00:00
def __init__ ( self , bot ) :
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-30 04:20:40 +00:00
await ctx . message . add_reaction ( ' 🌙 ' )
2017-10-20 20:24:43 +00:00
2017-10-30 04:20:40 +00:00
await self . bot . get_channel ( u . config [ ' info_channel ' ] ) . send ( ' **Shutting down** 🌙 . . . ' )
2017-10-20 20:24:43 +00:00
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self . bot . logout ( )
u . close ( self . bot . loop )
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')
@commands.command ( name = ' ,restart ' , aliases = [ ' ,res ' , ' ,r ' ] , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def restart ( self , ctx ) :
2017-10-30 04:20:40 +00:00
await ctx . message . add_reaction ( ' 💤 ' )
2017-10-20 20:24:43 +00:00
print ( ' \n | | | | | | | | | | \n R E S T A R T I N G \n | | | | | | | | | | \n ' )
2017-10-30 04:20:40 +00:00
await self . bot . get_channel ( u . config [ ' info_channel ' ] ) . send ( ' **Restarting** 💤 . . . ' )
2017-10-20 20:24:43 +00:00
# u.notify('R E S T A R T I N G')
u . temp [ ' restart_ch ' ] = ctx . channel . id
u . temp [ ' restart_msg ' ] = ctx . message . id
u . dump ( u . temp , ' temp.pkl ' )
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self . bot . logout ( )
u . close ( self . bot . loop )
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-30 04:20:40 +00:00
await ctx . message . add_reaction ( ' ✉️ ' )
2017-10-20 20:24:43 +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 )
@commands.command ( name = ' ,status ' , aliases = [ ' ,presence ' , ' ,game ' ] , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
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-30 04:20:40 +00:00
await ctx . message . add_reaction ( ' ✅ ' )
2017-10-16 22:50:27 +00:00
2017-10-13 02:26:57 +00:00
2017-10-11 06:59:06 +00:00
class Tools :
2017-10-20 20:24:43 +00:00
def __init__ ( self , bot ) :
self . bot = bot
2017-10-17 23:04:45 +00:00
2017-10-20 20:24:43 +00:00
def format ( self , i = ' ' , o = ' ' ) :
if len ( o ) > 1 :
return ' >>> {} \n {} ' . format ( i , o )
else :
return ' >>> {} ' . format ( i )
2017-10-17 23:04:45 +00:00
2017-10-20 20:24:43 +00:00
async def generate ( self , d , i = ' ' , o = ' ' ) :
return await d . send ( ' ```python \n {} ``` ' . format ( self . format ( i , o ) ) )
2017-10-17 23:04:45 +00:00
2017-10-20 20:24:43 +00:00
async def refresh ( self , m , i = ' ' , o = ' ' ) :
2017-10-20 20:24:19 +00:00
output = m . content [ 9 : - 3 ]
if len ( re . findall ( ' \n ' , output ) ) < = 20 :
2017-10-20 20:24:43 +00:00
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 ) ) )
async def generate_err ( self , d , o = ' ' ) :
return await d . send ( ' ``` \n {} ``` ' . format ( o ) )
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 ) :
if msg . content . startswith ( ' exe ' ) and msg . author is ctx . author and msg . channel is ctx . channel :
results . cancel ( )
return True
return False
def evaluate ( msg ) :
if msg . content . startswith ( ' eval ' ) and msg . author is ctx . author and msg . channel is ctx . channel :
results . cancel ( )
return True
return False
def exit ( reaction , user ) :
2017-10-30 04:20:40 +00:00
if reaction . emoji == ' ↩️ ' and user is ctx . author and reaction . message . id == ctx . message . id :
2017-10-20 20:24:43 +00:00
results . cancel ( )
raise exc . Abort
return False
2017-10-11 06:59:06 +00:00
try :
2017-10-20 20:24:43 +00:00
console = await self . generate ( ctx )
exception = await self . generate_err ( ctx )
2017-10-30 04:20:40 +00:00
await ctx . message . add_reaction ( ' ↩️ ' )
2017-10-20 20:24:43 +00:00
while not self . bot . is_closed ( ) :
try :
results = await asyncio . gather ( [ self . bot . wait_for ( ' message ' , check = execute ) , self . bot . wait_for ( ' message ' , check = evaluate ) , self . bot . wait_for ( ' reaction_add ' , check = exit ) ] , return_exceptions = True )
print ( results )
except exc . Execute :
try :
sys . stdout = io . StringIO ( )
sys . stderr = io . StringIO ( )
exec ( exe . content )
except Exception :
await self . refresh_err ( exception , tb . format_exc ( limit = 1 ) )
finally :
await self . refresh ( console , exe . content , sys . stdout . getvalue ( ) if sys . stdout . getvalue ( ) != console . content else None )
sys . stdout = sys . __stdout__
sys . stderr = sys . __stderr__
except exc . Evaluate :
try :
sys . stdout = io . StringIO ( )
sys . stderr = io . StringIO ( )
eval ( exe . content )
except Exception :
await self . refresh_err ( exception , tb . format_exc ( limit = 1 ) )
finally :
await self . refresh ( console , exe . content , sys . stdout . getvalue ( ) if sys . stdout . getvalue ( ) != console . content else None )
sys . stdout = sys . __stdout__
sys . stderr = sys . __stderr__
finally :
with suppress ( d . NotFound ) :
await exe . delete ( )
2017-10-14 01:53:44 +00:00
except exc . Abort :
2017-10-20 20:24:43 +00:00
pass
finally :
sys . stdout = sys . __stdout__
sys . stderr = sys . __stderr__
print ( ' Reset sys output. ' )
2017-10-30 04:20:40 +00:00
await ctx . message . add_reaction ( ' ✅ ' )
2017-10-20 20:24:43 +00:00
@commands.command ( name = ' arbitrary ' , aliases = [ ' ,arbit ' , ' ,ar ' ] )
@commands.is_owner ( )
@checks.del_ctx ( )
async def arbitrary ( self , ctx , * , exe ) :
2017-10-11 06:59:06 +00:00
try :
2017-10-20 20:24:43 +00:00
sys . stdout = io . StringIO ( )
exec ( exe )
await self . generate ( ctx , exe , sys . stdout . getvalue ( ) )
2017-10-11 06:59:06 +00:00
except Exception :
2017-10-20 20:24:43 +00:00
await ctx . send ( ' ``` \n {} ``` ' . format ( tb . format_exc ( limit = 1 ) ) )
2017-10-11 06:59:06 +00:00
finally :
2017-10-20 20:24:43 +00:00
sys . stdout = sys . __stdout__
print ( ' Reset stdout. ' )
2017-10-30 04:20:40 +00:00
await ctx . message . add_reaction ( ' ✅ ' )
2017-10-20 20:24:43 +00:00
@commands.group ( aliases = [ ' ,db ' ] , hidden = True )
@commands.is_owner ( )
@checks.del_ctx ( )
async def debug ( self , ctx ) :
console = await self . generate ( ctx )
@debug.command ( name = ' inject ' , aliases = [ ' inj ' ] )
async def _inject ( self , ctx , * , input_ ) :
pass
@debug.command ( name = ' inspect ' , aliases = [ ' ins ' ] )
async def _inspect ( self , ctx , * , input_ ) :
pass
2017-10-21 20:41:22 +00:00
# @commands.command(name='endpoint', aliases=['end'])
# async def get_endpoint(self, ctx, *args):
# await ctx.send(f'```\n{await u.fetch(f"https://{args[0]}/{args[1]}/{args[2]}", params={args[3]: args[4], "limit": 1}, json=True)}```')