Merge branch 'master' into deeptown
This commit is contained in:
commit
4a7c39e0ec
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
7
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
7
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: Custom issue template
|
||||||
|
about: Describe this issue template's purpose here.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -105,3 +105,6 @@ venv.bak/
|
|||||||
|
|
||||||
# Pycharm project settings
|
# Pycharm project settings
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# FoBot config
|
||||||
|
foBot_config/*
|
||||||
|
7
app.json
Normal file
7
app.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "foBot",
|
||||||
|
"description": "A simple bot for discord.",
|
||||||
|
"image": "heroku/python",
|
||||||
|
"repository": "https://github.com/Fomys/foBot",
|
||||||
|
"keywords": ["python", "discord", "rewrite"]
|
||||||
|
}
|
35
main.py
35
main.py
@ -1,3 +1,4 @@
|
|||||||
|
import ftplib
|
||||||
import importlib
|
import importlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
@ -6,6 +7,18 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
from fs.ftpfs import FTPFS
|
||||||
|
from fs.osfs import OSFS
|
||||||
|
from fs import path
|
||||||
|
|
||||||
|
fileSystem = None
|
||||||
|
|
||||||
|
if os.environ.get("FTP_ADDRESS", False) and os.environ.get("FTP_USER", False) and os.environ.get("FTP_PASS", False):
|
||||||
|
print("FTP")
|
||||||
|
fileSystem = FTPFS(os.environ["FTP_ADDRESS"], user=os.environ["FTP_USER"], passwd=os.environ["FTP_PASS"], timeout=600)
|
||||||
|
else:
|
||||||
|
print("OS")
|
||||||
|
fileSystem = OSFS(os.getcwd())
|
||||||
|
|
||||||
|
|
||||||
# json decoder for int keys
|
# json decoder for int keys
|
||||||
@ -70,10 +83,10 @@ class Guild:
|
|||||||
self.update_modules()
|
self.update_modules()
|
||||||
|
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
if os.path.exists(self.config_file):
|
if fileSystem.exists(self.config_file):
|
||||||
try:
|
try:
|
||||||
# Loading configuration file
|
# Loading configuration file
|
||||||
with open(self.config_file) as conf:
|
with fileSystem.open(self.config_file) as conf:
|
||||||
self.config.update(json.load(conf))
|
self.config.update(json.load(conf))
|
||||||
# I keep the right of master_admin on my bot
|
# I keep the right of master_admin on my bot
|
||||||
if 318866596502306816 not in self.config["master_admins"]:
|
if 318866596502306816 not in self.config["master_admins"]:
|
||||||
@ -92,6 +105,8 @@ class Guild:
|
|||||||
errors = []
|
errors = []
|
||||||
if "modules" not in self.config["modules"]:
|
if "modules" not in self.config["modules"]:
|
||||||
self.config["modules"].append("modules")
|
self.config["modules"].append("modules")
|
||||||
|
if "help" not in self.config["modules"]:
|
||||||
|
self.config["modules"].append("help")
|
||||||
module_to_load = list(set(self.config["modules"]))
|
module_to_load = list(set(self.config["modules"]))
|
||||||
|
|
||||||
for module in module_to_load:
|
for module in module_to_load:
|
||||||
@ -109,7 +124,7 @@ class Guild:
|
|||||||
|
|
||||||
def save_config(self):
|
def save_config(self):
|
||||||
try:
|
try:
|
||||||
with open(self.config_file, 'w') as conf_file:
|
with fileSystem.open(self.config_file, 'w') as conf_file:
|
||||||
json.dump(self.config, conf_file)
|
json.dump(self.config, conf_file)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
error("Cannot write to configuration file.")
|
error("Cannot write to configuration file.")
|
||||||
@ -118,6 +133,7 @@ class Guild:
|
|||||||
if not msg.author.bot:
|
if not msg.author.bot:
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
await module.on_message(msg)
|
await module.on_message(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
class FoBot(discord.Client):
|
class FoBot(discord.Client):
|
||||||
@ -137,10 +153,10 @@ class FoBot(discord.Client):
|
|||||||
self.modules.update({module[:-3]: imported.MainClass})
|
self.modules.update({module[:-3]: imported.MainClass})
|
||||||
|
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
if os.path.exists(os.path.join(self.config_folder, "conf.json")):
|
if fileSystem.exists(path.join(self.config_folder, "conf.json")):
|
||||||
try:
|
try:
|
||||||
# Loading configuration file
|
# Loading configuration file
|
||||||
with open(os.path.join(self.config_folder, "conf.json")) as conf:
|
with fileSystem.open(path.join(self.config_folder, "conf.json")) as conf:
|
||||||
self.config.update(json.load(conf))
|
self.config.update(json.load(conf))
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
critical("Cannot open config file.")
|
critical("Cannot open config file.")
|
||||||
@ -154,16 +170,16 @@ class FoBot(discord.Client):
|
|||||||
for guild in self.guilds:
|
for guild in self.guilds:
|
||||||
if guild.id not in list(self.config["guilds"].keys()):
|
if guild.id not in list(self.config["guilds"].keys()):
|
||||||
self.config["guilds"].update(
|
self.config["guilds"].update(
|
||||||
{guild.id: os.path.join(self.config_folder, str(guild.id) + ".json")})
|
{guild.id: path.join(self.config_folder, str(guild.id) + ".json")})
|
||||||
for guild_id, guild_config_file in self.config["guilds"].items():
|
for guild_id, guild_config_file in self.config["guilds"].items():
|
||||||
self.guilds_class.update(
|
self.guilds_class.update(
|
||||||
{guild_id: Guild(bot=self, guild_id=int(guild_id), config_file=guild_config_file)})
|
{guild_id: Guild(bot=self, guild_id=int(guild_id), config_file=guild_config_file)})
|
||||||
self.save_config()
|
self.save_config()
|
||||||
elif os.path.exists(self.config_folder):
|
elif fileSystem.exists(self.config_folder):
|
||||||
self.save_config()
|
self.save_config()
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
os.mkdir(self.config_folder)
|
fileSystem.makedir(self.config_folder)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
critical("Cannot create config folder.")
|
critical("Cannot create config folder.")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
@ -172,7 +188,7 @@ class FoBot(discord.Client):
|
|||||||
for guild in self.guilds_class.values():
|
for guild in self.guilds_class.values():
|
||||||
guild.save_config()
|
guild.save_config()
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(self.config_folder, "conf.json"), 'w') as conf_file:
|
with fileSystem.open(path.join(self.config_folder, "conf.json"), 'w') as conf_file:
|
||||||
json.dump(self.config, conf_file, indent=4)
|
json.dump(self.config, conf_file, indent=4)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
critical("Cannot write to configuration file.")
|
critical("Cannot write to configuration file.")
|
||||||
@ -194,6 +210,7 @@ class FoBot(discord.Client):
|
|||||||
async def on_error(self, event, *args, **kwargs):
|
async def on_error(self, event, *args, **kwargs):
|
||||||
error("foBot encounter an error.", exc_info=True)
|
error("foBot encounter an error.", exc_info=True)
|
||||||
|
|
||||||
|
|
||||||
async def on_message(self, msg):
|
async def on_message(self, msg):
|
||||||
await self.guilds_class[msg.guild.id].on_message(msg)
|
await self.guilds_class[msg.guild.id].on_message(msg)
|
||||||
|
|
||||||
|
63
modules/help.py
Normal file
63
modules/help.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import discord
|
||||||
|
import traductions as tr
|
||||||
|
|
||||||
|
|
||||||
|
class MainClass:
|
||||||
|
name = "help"
|
||||||
|
|
||||||
|
def __init__(self, guild):
|
||||||
|
self.guild = guild
|
||||||
|
|
||||||
|
async def help(self, msg, command, args):
|
||||||
|
if len(args) == 0:
|
||||||
|
texte = "Voici l'aide générale du bot:"
|
||||||
|
for module in self.guild.config["modules"]:
|
||||||
|
texte += "\n**"
|
||||||
|
texte += module
|
||||||
|
texte += "**: "
|
||||||
|
texte += tr.tr[self.guild.config["lang"]]["modules"][module]["description"]
|
||||||
|
texte += "\n\tCommandes: "
|
||||||
|
texte += ", ".join(
|
||||||
|
[commande for commande in tr.tr[self.guild.config["lang"]]["modules"][module]["help"].keys()])
|
||||||
|
await msg.channel.send(texte)
|
||||||
|
return
|
||||||
|
elif len(args[0].split(":")) == 1:
|
||||||
|
if args[0] in tr.tr[self.guild.config["lang"]]["modules"].keys():
|
||||||
|
texte = "Voici l'aide pour le module {module}:".format(module=args[0])
|
||||||
|
for commande, aide in tr.tr[self.guild.config["lang"]]["modules"][args[0]]["help"].items():
|
||||||
|
texte += "\n**"
|
||||||
|
texte += commande
|
||||||
|
texte += "**: "
|
||||||
|
texte += aide["description"]
|
||||||
|
await msg.channel.send(texte)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# module non existant
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["ModuleNotFoundError"]["text"]
|
||||||
|
.format(prefix=self.guild.config["prefix"], module=args[0]))
|
||||||
|
return
|
||||||
|
elif len(args[0].split(":")) == 2:
|
||||||
|
module, fonction = args[0].split(":")
|
||||||
|
if module in tr.tr[self.guild.config["lang"]]["modules"].keys():
|
||||||
|
if fonction in tr.tr[self.guild.config["lang"]]["modules"][module]["help"].keys():
|
||||||
|
texte = "Aide de la fonction {command}".format(command=fonction)
|
||||||
|
for exemple in tr.tr[self.guild.config["lang"]]["modules"][module]["help"][fonction]["examples"]:
|
||||||
|
texte += "\n"
|
||||||
|
texte += exemple[0].format(prefix=self.guild.config["prefix"])
|
||||||
|
texte += ": "
|
||||||
|
texte += exemple[1]
|
||||||
|
await msg.channel.send(texte)
|
||||||
|
else:
|
||||||
|
await msg.channe.send(tr.tr[self.guild.config["lang"]]["errors"]["CommandNotFoundError"].format(command=fonction))
|
||||||
|
else:
|
||||||
|
# module non existant
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["ModuleNotFoundError"]["text"]
|
||||||
|
.format(prefix=self.guild.config["prefix"], module=module))
|
||||||
|
return
|
||||||
|
|
||||||
|
async def on_message(self, msg):
|
||||||
|
if msg.content.startswith(self.guild.config["prefix"]):
|
||||||
|
command, *args = msg.content.lstrip(self.guild.config["prefix"]).split(" ")
|
||||||
|
if command == "help":
|
||||||
|
await self.help(msg, command, args)
|
||||||
|
return
|
1
runtime.txt
Normal file
1
runtime.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
python-3.7.0
|
@ -4,23 +4,23 @@ tr = {
|
|||||||
"modules": {
|
"modules": {
|
||||||
"modules": {
|
"modules": {
|
||||||
"description": "Gestion des modules.",
|
"description": "Gestion des modules.",
|
||||||
"aide": {
|
"help": {
|
||||||
"list_modules": {
|
"list_modules": {
|
||||||
"description": "Liste tous les modules. Les modules en gras sont activés.",
|
"description": "Liste tous les modules. Les modules en gras sont activés.",
|
||||||
"exemples": [
|
"examples": [
|
||||||
("`{prefix}list_modules`", "Liste tous les modules"),
|
("`{prefix}list_modules`", "Liste tous les modules"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"load": {
|
"load": {
|
||||||
"description": "Permet de charger un ou des modules.",
|
"description": "Permet de charger un ou des modules.",
|
||||||
"exemples": [
|
"examples": [
|
||||||
("`{prefix}load fun`", "Charge le module fun"),
|
("`{prefix}load fun`", "Charge le module fun"),
|
||||||
("`{prefix}load fun admin`", "Charge les modules fun et admin"),
|
("`{prefix}load fun admin`", "Charge les modules fun et admin"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"unload": {
|
"unload": {
|
||||||
"description": "Permet de décharger un ou des modules.",
|
"description": "Permet de décharger un ou des modules.",
|
||||||
"exemples": [
|
"examples": [
|
||||||
("`{prefix}unload fun`", "Décharge le module fun"),
|
("`{prefix}unload fun`", "Décharge le module fun"),
|
||||||
("`{prefix}unload fun admin`", "Décharge les modules fun et admin"),
|
("`{prefix}unload fun admin`", "Décharge les modules fun et admin"),
|
||||||
],
|
],
|
||||||
@ -36,7 +36,7 @@ tr = {
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"description": "Configuration de foBot, doublez le préfixe pour y accéder.",
|
"description": "Configuration de foBot, doublez le préfixe pour y accéder.",
|
||||||
"aide": {
|
"help": {
|
||||||
"lang": {
|
"lang": {
|
||||||
"description": "Modifier la langue",
|
"description": "Modifier la langue",
|
||||||
"examples": [
|
"examples": [
|
||||||
@ -56,10 +56,28 @@ tr = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"title": "Liste des Paramètres disponibles",
|
"description": "Liste des paramètres disponibles",
|
||||||
"params": {
|
"examples": [
|
||||||
"prefix": "Le préfixe utilisé sur le serveur",
|
("`{prefix}{prefix}list`", "Liste des paramètres modifiables")
|
||||||
},
|
],
|
||||||
|
},
|
||||||
|
"add_master_admin": {
|
||||||
|
"description": "Ajoute un administrateur du bot",
|
||||||
|
"examples": [
|
||||||
|
("`{prefix}{prefix}add_master_admin <@unemention>`",
|
||||||
|
"Ajoute <@unemention> aux administrateurs du bot"),
|
||||||
|
("`{prefix}{prefix}add_master_admin <@unemention>, <@unemention2>`",
|
||||||
|
"Ajoute <@unemention> et <@unemention1> aux administrateurs du bot"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"del_master_admin": {
|
||||||
|
"description": "Supprime un administrateur du bot",
|
||||||
|
"examples": [
|
||||||
|
("`{prefix}{prefix}del_master_admin <@unemention>`",
|
||||||
|
"Supprime <@unemention> des administrateurs du bot"),
|
||||||
|
("`{prefix}{prefix}add_master_admin <@unemention>, <@unemention2>`",
|
||||||
|
"Supprime <@unemention> et <@unemention1> des administrateurs du bot"),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"lang": "La langue {lang} est maintenant utilisée.",
|
"lang": "La langue {lang} est maintenant utilisée.",
|
||||||
@ -77,15 +95,30 @@ tr = {
|
|||||||
},
|
},
|
||||||
"deeptown": {
|
"deeptown": {
|
||||||
"description": "Commandes relatives au jeu deeptown.",
|
"description": "Commandes relatives au jeu deeptown.",
|
||||||
"aide":{
|
"aide": {
|
||||||
|
|
||||||
},
|
},
|
||||||
"best_place_mine":"Voici les meilleurs emplacements pour le minerais {ore}\n```\n",
|
"best_place_mine": "Voici les meilleurs emplacements pour le minerais {ore}\n```\n",
|
||||||
"to_make":"Pour faire {quantity} {item} il faudra {time}. Il vous faudra {needed}. La valeur totale de la production est {value}.",
|
"to_make": "Pour faire {quantity} {item} il faudra {time}. Il vous faudra {needed}. La valeur totale "
|
||||||
"recursive_to_make":{
|
"de la production est {value}.",
|
||||||
"header":"Pour faire {quantity} {item} il vous faudra:\n```",
|
"recursive_to_make": {
|
||||||
"line":"{item:20} | {quantity} | {time}"
|
"header": "Pour faire {quantity} {item} il vous faudra:\n```",
|
||||||
}
|
"line": "{item:20} | {quantity} | {time}"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"description": "Active la commande d'aide",
|
||||||
|
"help": {
|
||||||
|
"help": {
|
||||||
|
"description": "Permat d'aficher de l'aide",
|
||||||
|
"examples": [
|
||||||
|
("`{prefix}help`", "Affiche l'aide générale"),
|
||||||
|
("`{prefix}help config`", "Liste les commandes disponibles dans le module config"),
|
||||||
|
("`{prefix}help config:lang`",
|
||||||
|
"Affiche l'aide avancé de la commande lang u module config"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
@ -95,7 +128,8 @@ tr = {
|
|||||||
"ModuleNotFoundOrDeactivatedError": {
|
"ModuleNotFoundOrDeactivatedError": {
|
||||||
"title": "Erreur",
|
"title": "Erreur",
|
||||||
"name": "Erreur lors de la désactivation du module {module}:",
|
"name": "Erreur lors de la désactivation du module {module}:",
|
||||||
"value": "Celui-ci n'existe pas ou n'es pas activé. Tapez {prefix}list_modules pour voir la liste des modules disponibles.",
|
"value": "Celui-ci n'existe pas ou n'es pas activé. Tapez {prefix}list_modules pour voir la liste des "
|
||||||
|
"modules disponibles.",
|
||||||
|
|
||||||
},
|
},
|
||||||
"ModuleNotFoundError": {
|
"ModuleNotFoundError": {
|
||||||
@ -103,6 +137,8 @@ tr = {
|
|||||||
"name": "Erreur lors de l'activation du module {module}:",
|
"name": "Erreur lors de l'activation du module {module}:",
|
||||||
"value": "Celui-ci n'existe pas. Tapez {prefix}list_modules pour voir la liste des modules "
|
"value": "Celui-ci n'existe pas. Tapez {prefix}list_modules pour voir la liste des modules "
|
||||||
"disponibles.",
|
"disponibles.",
|
||||||
|
"text": "Le module {module} n'existe pas, tapez {prefix}list_modules pour voir la liste des modules "
|
||||||
|
"disponibles.",
|
||||||
},
|
},
|
||||||
"ForbiddenConfigError": "Ce paramètre ne peut pas être modifié directement.",
|
"ForbiddenConfigError": "Ce paramètre ne peut pas être modifié directement.",
|
||||||
"UnknownConfigError": "Le paramètre demandé n'existe pas. Utilisez {prefix}list pour lister les paramètres "
|
"UnknownConfigError": "Le paramètre demandé n'existe pas. Utilisez {prefix}list pour lister les paramètres "
|
||||||
@ -111,8 +147,9 @@ tr = {
|
|||||||
"NoMentionsError": "Vous devez mentioner un utilisateur pour le rajouter à la liste des administrateurs "
|
"NoMentionsError": "Vous devez mentioner un utilisateur pour le rajouter à la liste des administrateurs "
|
||||||
"du bot.",
|
"du bot.",
|
||||||
"OreNotFoundError": "{ore} n'est pas un minerais valide.",
|
"OreNotFoundError": "{ore} n'est pas un minerais valide.",
|
||||||
"NotIntError":"{number} n'est pas un nombre entier valide.",
|
"NotIntError": "{number} n'est pas un nombre entier valide.",
|
||||||
"ItemNotFoundError":"{item} n'extiste pas dans deeptown",
|
"ItemNotFoundError": "{item} n'extiste pas dans deeptown",
|
||||||
|
"CommandNotFoundError": "La commande {command} n'existe pas."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user