tuxbot-bot/bot.py

223 lines
6.7 KiB
Python
Raw Normal View History

2019-12-29 23:48:11 +00:00
import contextlib
2019-05-29 22:59:20 +00:00
import datetime
import logging
2019-05-29 22:59:20 +00:00
import sys
2019-09-21 21:17:45 +00:00
from collections import deque, Counter
2019-12-16 17:12:10 +00:00
from typing import List
2019-05-29 22:59:20 +00:00
2018-12-03 00:26:23 +00:00
import aiohttp
2019-05-29 22:59:20 +00:00
import discord
import git
2019-05-29 22:59:20 +00:00
from discord.ext import commands
from utils import Config
from utils import Database
from utils import Texts
from utils import Version
description = """
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
"""
2020-01-01 22:44:46 +00:00
build = git.Repo(search_parent_directories=True).head.object.hexsha
version = (2, 1, 0)
log = logging.getLogger(__name__)
2019-07-28 18:55:00 +00:00
2019-12-16 17:12:10 +00:00
l_extensions: List[str] = [
'cogs.Admin',
'cogs.Help',
'cogs.Logs',
'cogs.Monitoring',
'cogs.Polls',
'cogs.Useful',
'cogs.User',
'jishaku',
2019-12-16 17:12:10 +00:00
]
2019-09-10 16:23:24 +00:00
async def _prefix_callable(bot, message: discord.message) -> list:
extras = [bot.cluster.get('Name') + '.']
if message.guild is not None:
2019-12-16 17:12:10 +00:00
if str(message.guild.id) in bot.prefixes:
extras.extend(
bot.prefixes.get(str(message.guild.id), "prefixes").split(
bot.config.get("misc", "Separator")
)
2019-12-16 17:12:10 +00:00
)
return commands.when_mentioned_or(*extras)(bot, message)
class TuxBot(commands.AutoShardedBot):
def __init__(self, database):
super().__init__(command_prefix=_prefix_callable, pm_help=None,
help_command=None, description=description,
help_attrs=dict(hidden=True),
2019-09-20 22:11:29 +00:00
activity=discord.Game(
name=Texts().get('Starting...'))
)
2019-09-21 21:17:45 +00:00
self.socket_stats = Counter()
self.command_stats = Counter()
2019-09-10 16:23:24 +00:00
self.uptime: datetime = datetime.datetime.utcnow()
self._prev_events = deque(maxlen=10)
2019-05-29 22:59:20 +00:00
self.session = aiohttp.ClientSession(loop=self.loop)
self.database = database
2019-05-29 22:59:20 +00:00
2019-12-16 17:12:10 +00:00
self.config = Config('./configs/config.cfg')
self.prefixes = Config('./configs/prefixes.cfg')
self.blacklist = Config('./configs/blacklist.cfg')
self.fallbacks = Config('./configs/fallbacks.cfg')
self.cluster = self.fallbacks.find('True', key='This', first=True)
self.version = Version(*version, pre_release='a5', build=build)
self.owner = int
2019-05-29 22:59:20 +00:00
for extension in l_extensions:
2019-12-16 17:12:10 +00:00
try:
self.load_extension(extension)
2019-12-16 17:12:10 +00:00
print(Texts().get("Extension loaded successfully : ")
+ extension)
log.info(Texts().get("Extension loaded successfully : ")
+ extension)
except Exception as e:
print(Texts().get("Failed to load extension : ")
+ extension, file=sys.stderr)
print(e)
2019-12-16 17:12:10 +00:00
log.error(Texts().get("Failed to load extension : ")
+ extension, exc_info=e)
2019-09-10 16:23:24 +00:00
async def is_owner(self, user: discord.User) -> bool:
return str(user.id) in self.config.get("permissions", "Owners").split(
', ')
2019-09-10 16:23:24 +00:00
async def on_socket_response(self, msg):
self._prev_events.append(msg)
2019-05-29 22:59:20 +00:00
2019-09-10 16:23:24 +00:00
async def on_command_error(self, ctx: discord.ext.commands.Context, error):
2019-05-29 22:59:20 +00:00
if isinstance(error, commands.NoPrivateMessage):
await ctx.author.send(
Texts().get("This command cannot be used in private messages.")
)
2019-09-10 16:37:38 +00:00
2019-05-29 22:59:20 +00:00
elif isinstance(error, commands.DisabledCommand):
await ctx.author.send(
2019-09-20 22:11:29 +00:00
Texts().get(
"Sorry. This command is disabled and cannot be used."
)
)
2019-09-10 16:37:38 +00:00
2019-09-10 16:23:24 +00:00
async def process_commands(self, message: discord.message):
ctx = await self.get_context(message)
if ctx.command is None:
return
await self.invoke(ctx)
2019-09-10 16:23:24 +00:00
async def on_message(self, message: discord.message):
2019-12-29 23:48:11 +00:00
if message.author.id in self.blacklist \
or (message.guild is not None
and message.guild.id in self.blacklist):
return
2019-12-29 23:48:11 +00:00
if message.author.bot and message.author.id != int(
self.config.get('bot', 'Tester')):
return
await self.process_commands(message)
2019-05-29 22:59:20 +00:00
async def on_ready(self):
if not hasattr(self, 'uptime'):
self.uptime = datetime.datetime.utcnow()
print('-' * 60)
print(Texts().get("Ready:") + f' {self.user} (ID: {self.user.id})')
print(self.version)
2019-05-29 22:59:20 +00:00
2019-09-10 16:23:24 +00:00
presence: dict = dict(status=discord.Status.dnd)
2019-12-16 17:12:10 +00:00
if self.config.get("bot", "Activity", fallback=None) is not None:
presence.update(
activity=discord.Game(
name=self.config.get("bot", "Activity")
)
)
print(f"Discord.py: {discord.__version__}")
2020-01-01 22:44:46 +00:00
print(f"Server: {self.cluster.get('Name')}")
print('-' * 60)
2019-09-10 16:23:24 +00:00
await self.change_presence(**presence)
self.owner = await self.fetch_user(
int(self.config.get('permissions', 'Owners').split(', ')[0])
)
2019-05-29 22:59:20 +00:00
@staticmethod
async def on_resumed():
print('resumed...')
@property
2019-09-10 16:23:24 +00:00
def logs_webhook(self) -> discord.Webhook:
webhook_config = self.config["webhook"]
webhook = discord.Webhook.partial(
id=webhook_config.get('ID'),
token=webhook_config.get('Token'),
adapter=discord.AsyncWebhookAdapter(
self.session
)
)
2019-09-10 16:37:38 +00:00
return webhook
2019-05-29 22:59:20 +00:00
async def close(self):
extensions = self.extensions.copy()
for extension in extensions:
self.unload_extension(extension)
await super().close()
2019-12-16 17:12:10 +00:00
await self.session.close()
2019-05-29 22:59:20 +00:00
def run(self):
2019-12-16 17:12:10 +00:00
super().run(self.config.get("bot", "Token"), reconnect=True)
@contextlib.contextmanager
def setup_logging():
try:
logging.getLogger('discord').setLevel(logging.INFO)
logging.getLogger('discord.http').setLevel(logging.WARNING)
log = logging.getLogger()
log.setLevel(logging.INFO)
handler = logging.FileHandler(filename='logs/tuxbot.log',
encoding='utf-8', mode='w')
fmt = logging.Formatter('[{levelname:<7}] [{asctime}]'
' {name}: {message}',
'%Y-%m-%d %H:%M:%S', style='{')
handler.setFormatter(fmt)
log.addHandler(handler)
yield
finally:
handlers = log.handlers[:]
for handler in handlers:
handler.close()
log.removeHandler(handler)
2019-12-16 17:12:10 +00:00
if __name__ == "__main__":
log = logging.getLogger()
print(Texts().get('Starting...'))
bot = TuxBot(Database(Config("./configs/config.cfg")))
2019-12-16 17:12:10 +00:00
try:
with setup_logging():
bot.run()
2019-12-16 17:12:10 +00:00
except KeyboardInterrupt:
bot.close()