2017-05-04 05:22:27 +02:00
from config import config
2017-05-04 07:16:49 +02:00
from titanembeds . database import DatabaseInterface
2017-05-04 05:22:27 +02:00
import discord
2017-05-27 23:13:00 +02:00
from discord . ext import commands
2017-05-04 07:16:49 +02:00
import aiohttp
import asyncio
2017-05-14 23:05:51 +02:00
import sys
2017-05-15 00:09:38 +02:00
import logging
2017-05-15 00:19:15 +02:00
logging . basicConfig ( filename = ' titanbot.log ' , level = logging . INFO , format = ' %(asctime)s %(message)s ' , datefmt = ' % m/ %d / % Y % I: % M: % S % p ' )
2017-05-15 00:09:38 +02:00
logging . getLogger ( ' TitanBot ' )
logging . getLogger ( ' sqlalchemy ' )
2017-05-04 05:22:27 +02:00
2017-05-27 23:49:41 +02:00
bot = commands . Bot ( command_prefix = config [ ' command-prefix ' ] )
2017-05-28 00:23:27 +02:00
database = None
2017-05-28 00:11:35 +02:00
def _cleanup ( ) :
2017-05-27 23:38:28 +02:00
try :
2017-05-28 00:11:35 +02:00
bot . loop . run_until_complete ( logout ( ) )
2017-05-27 23:38:28 +02:00
except : # Can be ignored
pass
pending = asyncio . Task . all_tasks ( )
gathered = asyncio . gather ( * pending )
try :
gathered . cancel ( )
2017-05-27 23:51:41 +02:00
bot . loop . run_until_complete ( gathered )
2017-05-27 23:38:28 +02:00
gathered . exception ( )
except : # Can be ignored
pass
@bot.event
2017-05-28 00:25:25 +02:00
async def on_ready ( ) :
2017-05-27 23:38:28 +02:00
print ( ' Titan [DiscordBot] ' )
print ( ' Logged in as the following user: ' )
2017-05-28 00:13:41 +02:00
print ( bot . user . name )
print ( bot . user . id )
2017-05-27 23:38:28 +02:00
print ( ' ------ ' )
2017-05-28 00:13:41 +02:00
await bot . change_presence (
2017-05-27 23:38:28 +02:00
game = discord . Game ( name = " Embed your Discord server! Visit https://TitanEmbeds.tk/ " ) , status = discord . Status . online
)
try :
2017-05-28 00:27:22 +02:00
database = DatabaseInterface ( bot , config [ " database-uri " ] + " ?charset=utf8mb4 " )
2017-05-28 00:30:14 +02:00
global database
2017-05-27 23:38:28 +02:00
except Exception :
2017-05-28 00:25:25 +02:00
logger . error ( " Unable to connect to specified database! " )
2017-05-27 23:38:28 +02:00
traceback . print_exc ( )
2017-05-28 00:22:30 +02:00
await bot . logout ( )
2017-05-27 23:38:28 +02:00
return
if " no-init " not in sys . argv :
2017-05-28 00:13:41 +02:00
for server in bot . servers :
2017-05-28 00:25:25 +02:00
await database . update_guild ( server )
2017-05-27 23:38:28 +02:00
if server . large :
2017-05-28 00:13:41 +02:00
await bot . request_offline_members ( server )
server_bans = await bot . get_bans ( server )
2017-05-27 23:38:28 +02:00
for member in server . members :
banned = member . id in [ u . id for u in server_bans ]
2017-05-28 00:25:25 +02:00
await database . update_guild_member (
2017-05-27 23:38:28 +02:00
member ,
True ,
banned
)
2017-05-28 00:25:25 +02:00
await database . flag_unactive_guild_members ( server . id , server . members )
await database . flag_unactive_bans ( server . id , server_bans )
await database . remove_unused_guilds ( bot . servers )
2017-05-27 23:38:28 +02:00
else :
print ( " Skipping indexing server due to no-init flag " )
@bot.event
2017-05-28 00:17:07 +02:00
async def on_message ( message ) :
await database . push_message ( message )
2017-05-27 23:38:28 +02:00
if message . server :
2017-05-28 00:13:41 +02:00
await bot . process_commands ( message )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_message_edit ( message_before , message_after ) :
await database . update_message ( message_after )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_message_delete ( message ) :
await database . delete_message ( message )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_server_join ( guild ) :
2017-05-27 23:38:28 +02:00
await asyncio . sleep ( 1 )
if not guild . me . server_permissions . administrator :
2017-05-20 03:45:38 +02:00
await asyncio . sleep ( 1 )
2017-05-28 00:13:41 +02:00
await bot . leave_server ( guild )
2017-05-27 23:38:28 +02:00
return
2017-05-28 00:25:25 +02:00
await database . update_guild ( guild )
2017-05-27 23:38:28 +02:00
for channel in guild . channels :
2017-05-28 00:13:41 +02:00
async for message in bot . logs_from ( channel , limit = 50 , reverse = True ) :
2017-05-28 00:25:25 +02:00
await database . push_message ( message )
2017-05-27 23:38:28 +02:00
for member in guild . members :
2017-05-28 00:25:25 +02:00
await database . update_guild_member ( member , True , False )
2017-05-28 00:13:41 +02:00
banned = await bot . get_bans ( guild )
2017-05-27 23:38:28 +02:00
for ban in banned :
2017-05-28 00:25:25 +02:00
await database . update_guild_member ( ban , False , True )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_server_remove ( guild ) :
await database . remove_guild ( guild )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_server_update ( guildbefore , guildafter ) :
await database . update_guild ( guildafter )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_server_role_create ( role ) :
2017-05-28 00:13:41 +02:00
if role . name == bot . user . name and role . managed :
2017-05-27 23:38:28 +02:00
await asyncio . sleep ( 2 )
2017-05-28 00:25:25 +02:00
await database . update_guild ( role . server )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_server_role_delete ( role ) :
2017-05-27 23:38:28 +02:00
if role . server . me not in role . server . members :
return
2017-05-28 00:25:25 +02:00
await database . update_guild ( role . server )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_server_role_update ( rolebefore , roleafter ) :
await database . update_guild ( roleafter . server )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_channel_delete ( channel ) :
await database . update_guild ( channel . server )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_channel_create ( channel ) :
await database . update_guild ( channel . server )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_channel_update ( channelbefore , channelafter ) :
await database . update_guild ( channelafter . server )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_member_join ( member ) :
await database . update_guild_member ( member , active = True , banned = False )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_member_remove ( member ) :
await database . update_guild_member ( member , active = False , banned = False )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_member_update ( memberbefore , memberafter ) :
await database . update_guild_member ( memberafter )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_member_ban ( member ) :
2017-05-28 00:13:41 +02:00
if bot . user . id == member . id :
2017-05-27 23:38:28 +02:00
return
2017-05-28 00:25:25 +02:00
await database . update_guild_member ( member , active = False , banned = True )
2017-05-27 23:38:28 +02:00
@bot.event
2017-05-28 00:25:25 +02:00
async def on_member_unban ( server , user ) :
await database . unban_server_user ( user , server )
2017-05-27 23:38:28 +02:00
@commands.command ( pass_context = True )
async def ban ( ctx , self ) :
message = ctx . message
if not message . author . server_permissions . ban_members :
2017-05-28 00:13:41 +02:00
await bot . send_message ( message . channel , message . author . mention + " I ' m sorry, but you do not have permissions to ban guest members. " )
2017-05-27 23:38:28 +02:00
return
serverid = message . server . id
content = message . content . strip ( )
if len ( content . split ( ) ) == 2 :
2017-05-28 00:13:41 +02:00
await bot . send_message ( message . channel , message . author . mention + " Please provide a username-query (or optionally a discriminator) to ban a guest user. \n Example: `ban Titan#0001` " )
2017-05-27 23:38:28 +02:00
return
content = content . split ( )
username = content [ 2 ] [ : content [ 2 ] . find ( " # " ) ] if " # " in content [ 2 ] else content [ 2 ]
discriminator = int ( content [ 2 ] [ content [ 2 ] . find ( " # " ) + 1 : ] ) if " # " in content [ 2 ] else None
2017-05-28 00:25:25 +02:00
reason = await database . ban_unauth_user_by_query ( message . server . id , message . author . id , username , discriminator )
2017-05-28 00:13:41 +02:00
await bot . send_message ( message . channel , message . author . mention + " " + reason )
2017-05-27 23:38:28 +02:00
@commands.command ( pass_context = True )
async def kick ( ctx , self ) :
message = ctx . message
if not message . author . server_permissions . kick_members :
2017-05-28 00:13:41 +02:00
await bot . send_message ( message . channel , message . author . mention + " I ' m sorry, but you do not have permissions to kick guest members. " )
2017-05-27 23:38:28 +02:00
return
serverid = message . server . id
content = message . content . strip ( )
if len ( content . split ( ) ) == 2 :
2017-05-28 00:13:41 +02:00
await bot . send_message ( message . channel , message . author . mention + " Please provide a username-query (or optionally a discriminator) to kick a guest user. \n Example: `kick Titan#0001` " )
2017-05-27 23:38:28 +02:00
return
content = content . split ( )
username = content [ 2 ] [ : content [ 2 ] . find ( " # " ) ] if " # " in content [ 2 ] else content [ 2 ]
discriminator = int ( content [ 2 ] [ content [ 2 ] . find ( " # " ) + 1 : ] ) if " # " in content [ 2 ] else None
2017-05-28 00:25:25 +02:00
reason = await database . revoke_unauth_user_by_query ( message . server . id , username , discriminator )
2017-05-28 00:13:41 +02:00
await bot . send_message ( message . channel , message . author . mention + " " + reason )
2017-05-28 00:08:33 +02:00
try :
bot . loop . run_until_complete ( bot . run ( config [ " bot-token " ] ) )
except discord . errors . LoginFailure :
print ( " Invalid bot token in config! " )
finally :
try :
2017-05-28 00:11:35 +02:00
_cleanup ( )
2017-05-28 00:08:33 +02:00
except Exception as e :
print ( " Error in cleanup: " , e )
bot . loop . close ( )