2019-10-21 20:07:17 +00:00
import discord
import toml
import logging
import discord . ext . commands as commands
2020-05-12 16:08:03 +00:00
import discord . ext . tasks as tasks
2019-10-21 20:07:17 +00:00
import re
import asyncio
import json
2020-06-18 18:43:20 +00:00
import traceback
2020-09-10 17:51:38 +00:00
import random
2020-12-07 17:39:41 +00:00
import collections
2021-01-27 19:38:21 +00:00
import prometheus_client
import prometheus_async . aio
2020-12-07 17:39:41 +00:00
import typing
2021-02-25 17:48:06 +00:00
import sys
2019-10-21 20:07:17 +00:00
import tio
2020-04-18 12:14:31 +00:00
import db
2020-05-12 16:08:03 +00:00
import util
2021-02-25 17:48:06 +00:00
import eventbus
import irc_link
2020-11-01 17:32:02 +00:00
import achievement
2019-10-21 20:07:17 +00:00
2020-10-11 13:40:39 +00:00
config = util . config
2019-10-21 20:07:17 +00:00
logging . basicConfig ( level = logging . INFO , format = " %(levelname)s %(asctime)s %(message)s " , datefmt = " % H: % M: % S %d / % m/ % Y " )
2021-03-25 18:39:45 +00:00
intents = discord . Intents . default ( )
intents . members = True
2020-11-25 19:00:43 +00:00
2021-04-05 18:08:37 +00:00
bot = commands . Bot ( command_prefix = commands . when_mentioned_or ( config [ " prefix " ] ) , description = " AutoBotRobot, the most useless bot in the known universe. " + util . config . get ( " description_suffix " , " " ) ,
2021-03-25 18:39:45 +00:00
case_insensitive = True , allowed_mentions = discord . AllowedMentions ( everyone = False , users = True , roles = True ) , intents = intents )
2019-10-21 20:07:17 +00:00
bot . _skip_check = lambda x , y : False
2021-01-27 19:38:21 +00:00
messages = prometheus_client . Counter ( " abr_messages " , " Messages seen/handled by bot " )
command_invocations = prometheus_client . Counter ( " abr_command_invocations " , " Total commands invoked (includes failed) " )
2020-09-10 17:51:38 +00:00
@bot.event
async def on_message ( message ) :
2021-01-27 19:38:21 +00:00
messages . inc ( )
2020-09-10 17:51:38 +00:00
words = message . content . split ( " " )
if len ( words ) == 10 and message . author . id == 435756251205468160 :
await message . channel . send ( util . unlyric ( message . content ) )
else :
2020-10-11 13:40:39 +00:00
if message . author == bot . user or message . author . discriminator == " 0000 " : return
2020-09-10 17:51:38 +00:00
ctx = await bot . get_context ( message )
if not ctx . valid : return
2021-01-27 19:38:21 +00:00
command_invocations . inc ( )
2020-09-10 17:51:38 +00:00
await bot . invoke ( ctx )
2021-01-27 19:38:21 +00:00
command_errors = prometheus_client . Counter ( " abr_errors " , " Count of errors encountered in executing commands. " )
2020-09-10 17:51:38 +00:00
@bot.event
async def on_command_error ( ctx , err ) :
2020-10-11 13:40:39 +00:00
if isinstance ( err , ( commands . CommandNotFound , commands . CheckFailure ) ) : return
2021-03-25 17:56:29 +00:00
if isinstance ( err , commands . CommandInvokeError ) and isinstance ( err . original , ValueError ) :
return await ctx . send ( embed = util . error_embed ( str ( err . original ) , title = f " Error in { ctx . invoked_with } " ) )
2021-03-08 10:25:11 +00:00
# TODO: really should find a way to detect ALL user errors here?
2021-03-25 17:56:29 +00:00
if isinstance ( err , ( commands . UserInputError ) ) :
return await ctx . send ( embed = util . error_embed ( str ( err ) , title = f " Error in { ctx . invoked_with } " ) )
2020-09-10 17:51:38 +00:00
try :
2021-01-27 19:38:21 +00:00
command_errors . inc ( )
2020-09-10 17:51:38 +00:00
trace = re . sub ( " \n \n + " , " \n " , " \n " . join ( traceback . format_exception ( err , err , err . __traceback__ ) ) )
2021-03-25 17:56:29 +00:00
logging . error ( " Command error occured (in %s ) " , ctx . invoked_with , exc_info = err )
await ctx . send ( embed = util . error_embed ( util . gen_codeblock ( trace ) , title = f " Internal error in { ctx . invoked_with } " ) )
2020-11-01 17:32:02 +00:00
await achievement . achieve ( ctx . bot , ctx . message , " error " )
2021-05-30 19:10:54 +00:00
except Exception as e :
improve, deliver, create, develop, design, operate, manage, produce, modernize, complicate, nationalize, placate, evolve, alter, amend, change or obliterate code
2021-05-31 19:14:04 +00:00
logging . exception ( " Error in command error handling. " )
2020-09-10 17:51:38 +00:00
@bot.check
async def andrew_bad ( ctx ) :
return ctx . message . author . id != 543131534685765673
2020-05-12 16:08:03 +00:00
@bot.event
async def on_ready ( ) :
logging . info ( " Connected as " + bot . user . name )
2020-11-01 17:07:36 +00:00
await bot . change_presence ( status = discord . Status . online ,
2021-04-05 18:08:37 +00:00
activity = discord . Activity ( name = f " { config [ ' prefix ' ] } help " , type = discord . ActivityType . listening ) )
2020-05-12 16:08:03 +00:00
2021-01-27 20:35:32 +00:00
visible_users = prometheus_client . Gauge ( " abr_visible_users " , " Users the bot can see " )
def get_visible_users ( ) :
return len ( bot . users )
visible_users . set_function ( get_visible_users )
heavserver_members = prometheus_client . Gauge ( " abr_heavserver_members " , " Current member count of heavserver " )
2021-02-25 17:48:06 +00:00
heavserver_bots = prometheus_client . Gauge ( " abr_heavserver_bots " , " Current bot count of heavserver " )
2021-01-27 20:35:32 +00:00
def get_heavserver_members ( ) :
2021-02-25 17:48:06 +00:00
if not bot . get_guild ( util . config [ " heavserver " ] [ " id " ] ) : return 0
2021-01-27 20:35:32 +00:00
return len ( bot . get_guild ( util . config [ " heavserver " ] [ " id " ] ) . members )
2021-02-25 17:48:06 +00:00
def get_heavserver_bots ( ) :
if not bot . get_guild ( util . config [ " heavserver " ] [ " id " ] ) : return 0
return len ( [ None for member in bot . get_guild ( util . config [ " heavserver " ] [ " id " ] ) . members if member . bot ] )
2021-01-27 20:35:32 +00:00
heavserver_members . set_function ( get_heavserver_members )
2021-02-25 17:48:06 +00:00
heavserver_bots . set_function ( get_heavserver_bots )
2021-01-27 20:35:32 +00:00
guild_count = prometheus_client . Gauge ( " abr_guilds " , " Guilds the bot is in " )
def get_guild_count ( ) :
return len ( bot . guilds )
guild_count . set_function ( get_guild_count )
2020-04-18 12:14:31 +00:00
async def run_bot ( ) :
2020-10-11 13:40:39 +00:00
bot . database = await db . init ( config [ " database " ] )
2021-02-25 17:48:06 +00:00
await eventbus . initial_load ( bot . database )
2021-01-14 09:38:32 +00:00
for ext in util . extensions :
2021-03-25 17:56:29 +00:00
logging . info ( " Loaded %s " , ext )
2020-10-11 13:40:39 +00:00
bot . load_extension ( ext )
2020-04-18 12:14:31 +00:00
await bot . start ( config [ " token " ] )
2021-05-30 19:10:54 +00:00
if __name__ == " __main__ " :
2020-04-18 12:14:31 +00:00
loop = asyncio . get_event_loop ( )
2021-01-27 19:38:21 +00:00
loop . create_task ( prometheus_async . aio . web . start_http_server ( port = config [ " metrics_port " ] ) )
improve, deliver, create, develop, design, operate, manage, produce, modernize, complicate, nationalize, placate, evolve, alter, amend, change or obliterate code
2021-05-31 19:14:04 +00:00
loop . create_task ( run_bot ( ) )
2020-04-18 12:14:31 +00:00
try :
improve, deliver, create, develop, design, operate, manage, produce, modernize, complicate, nationalize, placate, evolve, alter, amend, change or obliterate code
2021-05-31 19:14:04 +00:00
loop . run_forever ( )
2020-04-18 12:14:31 +00:00
except KeyboardInterrupt :
loop . run_until_complete ( bot . logout ( ) )
2021-02-25 17:48:06 +00:00
sys . exit ( 0 )
2020-04-18 12:14:31 +00:00
finally :
2020-06-18 18:43:20 +00:00
loop . close ( )