2018-08-11 01:50:18 +02:00
|
|
|
import importlib
|
2018-08-11 01:43:06 +02:00
|
|
|
import json
|
|
|
|
import logging
|
|
|
|
import logging.config
|
|
|
|
import os
|
2018-08-11 01:50:18 +02:00
|
|
|
import sys
|
|
|
|
|
|
|
|
import discord
|
|
|
|
|
2018-08-11 01:43:06 +02:00
|
|
|
|
2018-08-13 17:15:46 +02:00
|
|
|
# json decoder for int keys
|
|
|
|
class Decoder(json.JSONDecoder):
|
2018-08-17 17:07:49 +02:00
|
|
|
def decode(self, s, **kwargs):
|
2018-08-13 17:15:46 +02:00
|
|
|
result = super().decode(s) # result = super(Decoder, self).decode(s) for Python 2.x
|
|
|
|
return self._decode(result)
|
|
|
|
|
|
|
|
def _decode(self, o):
|
|
|
|
if isinstance(o, str):
|
|
|
|
try:
|
|
|
|
return int(o)
|
|
|
|
except ValueError:
|
|
|
|
return o
|
|
|
|
elif isinstance(o, dict):
|
|
|
|
return {k: self._decode(v) for k, v in o.items()}
|
|
|
|
elif isinstance(o, list):
|
|
|
|
return [self._decode(v) for v in o]
|
|
|
|
else:
|
|
|
|
return o
|
|
|
|
|
|
|
|
|
2018-08-17 17:07:49 +02:00
|
|
|
def setup_logging(default_path='log_config.json', default_level=logging.INFO, env_key='LOG_CFG'):
|
2018-08-11 01:43:06 +02:00
|
|
|
"""Setup logging configuration
|
|
|
|
"""
|
|
|
|
path = default_path
|
|
|
|
value = os.getenv(env_key, None)
|
|
|
|
if value:
|
|
|
|
path = value
|
|
|
|
if os.path.exists(path):
|
|
|
|
with open(path, 'rt') as f:
|
|
|
|
config = json.load(f)
|
|
|
|
logging.config.dictConfig(config)
|
|
|
|
else:
|
|
|
|
logging.basicConfig(level=default_level)
|
|
|
|
|
|
|
|
|
|
|
|
setup_logging()
|
|
|
|
|
|
|
|
log_discord = logging.getLogger('discord')
|
|
|
|
log_foBot = logging.getLogger('foBot')
|
|
|
|
|
|
|
|
debug = log_foBot.debug
|
|
|
|
info = log_foBot.info
|
|
|
|
warning = log_foBot.warning
|
|
|
|
error = log_foBot.error
|
|
|
|
critical = log_foBot.critical
|
2018-08-11 01:50:18 +02:00
|
|
|
|
|
|
|
|
2018-08-17 17:07:49 +02:00
|
|
|
class Guild:
|
2018-08-11 01:50:18 +02:00
|
|
|
def __init__(self, bot, guild_id, config_file):
|
|
|
|
self.id = guild_id
|
|
|
|
self.bot = bot
|
|
|
|
self.config_file = config_file
|
|
|
|
self.config = {"modules": ["modules"],
|
2018-08-17 17:07:49 +02:00
|
|
|
"prefix": "§",
|
|
|
|
"master_admins": [318866596502306816],
|
|
|
|
"lang": "FR_fr"
|
2018-08-11 01:50:18 +02:00
|
|
|
}
|
|
|
|
self.modules = []
|
|
|
|
self.load_config()
|
|
|
|
self.update_modules()
|
|
|
|
|
|
|
|
def load_config(self):
|
|
|
|
if os.path.exists(self.config_file):
|
|
|
|
try:
|
|
|
|
# Loading configuration file
|
|
|
|
with open(self.config_file) as conf:
|
|
|
|
self.config.update(json.load(conf))
|
2018-08-13 17:15:46 +02:00
|
|
|
# I keep the right of master_admin on my bot
|
2018-08-17 17:07:49 +02:00
|
|
|
if 318866596502306816 not in self.config["master_admins"]:
|
|
|
|
self.config["master_admins"].append(318866596502306816)
|
2018-08-13 17:15:46 +02:00
|
|
|
# Give the right of master_admin to guild owner
|
|
|
|
if self.bot.get_guild(self.id) is not None:
|
2018-08-17 17:07:49 +02:00
|
|
|
if self.bot.get_guild(self.id).owner.id not in self.config["master_admins"]:
|
|
|
|
self.config["master_admins"].append(self.bot.get_guild(self.id).owner.id)
|
2018-08-13 17:15:46 +02:00
|
|
|
self.save_config()
|
|
|
|
|
2018-08-11 01:50:18 +02:00
|
|
|
except PermissionError:
|
2018-08-17 17:07:49 +02:00
|
|
|
error("Cannot open config file for server %s." % self.id)
|
2018-08-11 01:50:18 +02:00
|
|
|
|
|
|
|
def update_modules(self):
|
|
|
|
self.modules = []
|
|
|
|
errors = []
|
2018-08-13 17:15:46 +02:00
|
|
|
if "modules" not in self.config["modules"]:
|
|
|
|
self.config["modules"].append("modules")
|
2018-08-17 17:07:49 +02:00
|
|
|
module_to_load = list(set(self.config["modules"]))
|
|
|
|
|
2018-08-15 13:00:58 +02:00
|
|
|
for module in module_to_load:
|
2018-08-11 01:50:18 +02:00
|
|
|
# Try to load all modules by name
|
2018-08-20 11:26:03 +02:00
|
|
|
if module not in self.bot.modules.keys():
|
2018-08-11 01:50:18 +02:00
|
|
|
# Module is not an existing module
|
|
|
|
self.config["modules"].remove(module)
|
|
|
|
# Write an error in log
|
|
|
|
error("Module %s doesn't exists." % module)
|
|
|
|
errors.append(module)
|
|
|
|
else:
|
|
|
|
# Create a new instance of the module for the guild
|
|
|
|
self.modules.append(self.bot.modules[module](guild=self))
|
|
|
|
return errors
|
|
|
|
|
|
|
|
def save_config(self):
|
|
|
|
try:
|
|
|
|
with open(self.config_file, 'w') as conf_file:
|
|
|
|
json.dump(self.config, conf_file)
|
|
|
|
except PermissionError:
|
|
|
|
error("Cannot write to configuration file.")
|
|
|
|
|
|
|
|
async def on_message(self, msg):
|
2018-08-17 17:07:49 +02:00
|
|
|
if not msg.author.bot:
|
|
|
|
for module in self.modules:
|
|
|
|
await module.on_message(msg)
|
2018-08-11 01:50:18 +02:00
|
|
|
|
|
|
|
|
|
|
|
class FoBot(discord.Client):
|
|
|
|
|
|
|
|
def __init__(self, config='foBot_config', *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.config_folder = config
|
|
|
|
self.config = {"guilds": {}}
|
|
|
|
self.guilds_class = {}
|
|
|
|
self.modules = {}
|
|
|
|
self.load_modules()
|
|
|
|
|
|
|
|
def load_modules(self):
|
|
|
|
for module in os.listdir('modules'):
|
2018-08-20 11:26:03 +02:00
|
|
|
if module != "__pycache__":
|
2018-08-13 17:15:46 +02:00
|
|
|
imported = importlib.import_module('modules.' + module[:-3])
|
|
|
|
self.modules.update({module[:-3]: imported.MainClass})
|
2018-08-11 01:50:18 +02:00
|
|
|
|
|
|
|
def load_config(self):
|
|
|
|
if os.path.exists(os.path.join(self.config_folder, "conf.json")):
|
|
|
|
try:
|
|
|
|
# Loading configuration file
|
|
|
|
with open(os.path.join(self.config_folder, "conf.json")) as conf:
|
|
|
|
self.config.update(json.load(conf))
|
|
|
|
except PermissionError:
|
|
|
|
critical("Cannot open config file.")
|
|
|
|
sys.exit()
|
|
|
|
info("Configuration for foBot loaded. Check for new guilds.")
|
2018-08-13 17:15:46 +02:00
|
|
|
# Change all str key of guild into int ones
|
|
|
|
guilds = {int(k): v for k, v in self.config["guilds"].items()}
|
|
|
|
del self.config["guilds"]
|
2018-08-17 17:07:49 +02:00
|
|
|
self.config.update({"guilds": guilds})
|
2018-08-11 01:50:18 +02:00
|
|
|
# Update configuration file if new servers are connected
|
|
|
|
for guild in self.guilds:
|
2018-08-13 17:15:46 +02:00
|
|
|
if guild.id not in list(self.config["guilds"].keys()):
|
2018-08-11 01:50:18 +02:00
|
|
|
self.config["guilds"].update(
|
2018-08-13 17:15:46 +02:00
|
|
|
{guild.id: os.path.join(self.config_folder, str(guild.id) + ".json")})
|
2018-08-11 01:50:18 +02:00
|
|
|
for guild_id, guild_config_file in self.config["guilds"].items():
|
2018-08-17 17:07:49 +02:00
|
|
|
self.guilds_class.update(
|
|
|
|
{guild_id: Guild(bot=self, guild_id=int(guild_id), config_file=guild_config_file)})
|
2018-08-13 17:15:46 +02:00
|
|
|
self.save_config()
|
2018-08-11 01:50:18 +02:00
|
|
|
elif os.path.exists(self.config_folder):
|
|
|
|
self.save_config()
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
os.mkdir(self.config_folder)
|
|
|
|
except PermissionError:
|
|
|
|
critical("Cannot create config folder.")
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
def save_config(self):
|
|
|
|
for guild in self.guilds_class.values():
|
|
|
|
guild.save_config()
|
|
|
|
try:
|
|
|
|
with open(os.path.join(self.config_folder, "conf.json"), 'w') as conf_file:
|
2018-08-13 17:15:46 +02:00
|
|
|
json.dump(self.config, conf_file, indent=4)
|
2018-08-11 01:50:18 +02:00
|
|
|
except PermissionError:
|
|
|
|
critical("Cannot write to configuration file.")
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
async def on_connect(self):
|
|
|
|
info("foBot is connected.")
|
|
|
|
|
|
|
|
async def on_ready(self):
|
|
|
|
info("foBot is ready to listen discord.")
|
|
|
|
info("Load foBot configuration.")
|
|
|
|
self.load_config()
|
|
|
|
self.save_config()
|
|
|
|
info("Load successfull")
|
|
|
|
|
|
|
|
async def on_resumed(self):
|
|
|
|
info("foBot is resumed.")
|
|
|
|
|
|
|
|
async def on_error(self, event, *args, **kwargs):
|
|
|
|
error("foBot encounter an error.", exc_info=True)
|
|
|
|
|
|
|
|
async def on_message(self, msg):
|
2018-08-13 17:15:46 +02:00
|
|
|
await self.guilds_class[msg.guild.id].on_message(msg)
|
2018-08-11 01:50:18 +02:00
|
|
|
|
|
|
|
|
|
|
|
myBot = FoBot()
|
2018-08-20 11:53:14 +02:00
|
|
|
myBot.run(os.environ.get("DISCORD_TOKEN", ""), max_messages=100000000)
|