From 777b113950234b42078f357ab8778934ee0eea04 Mon Sep 17 00:00:00 2001 From: louis chauvet Date: Wed, 31 Oct 2018 19:21:05 +0100 Subject: [PATCH] First Commit for survey --- .gitignore | 4 +- log_config.json | 4 +- main.py | 43 ++++-- modules/help.py | 2 +- modules/survey.py | 384 ++++++++++++++++++++++++++++++++++++++++++++++ traductions.py | 66 ++++++-- 6 files changed, 472 insertions(+), 31 deletions(-) create mode 100644 modules/survey.py diff --git a/.gitignore b/.gitignore index 6e4d29d..16ebab5 100644 --- a/.gitignore +++ b/.gitignore @@ -110,4 +110,6 @@ venv.bak/ foBot_config/* # Pi file (too big) -modules/pi/pi.txt \ No newline at end of file +modules/pi/pi.txt + +*.log* \ No newline at end of file diff --git a/log_config.json b/log_config.json index 00e0c27..898f0e5 100644 --- a/log_config.json +++ b/log_config.json @@ -20,7 +20,7 @@ "level": "INFO", "formatter": "simple", "filename": "info.log", - "maxBytes": 10485760, + "maxBytes": 1048576, "backupCount": 20, "encoding": "utf8" }, @@ -30,7 +30,7 @@ "level": "ERROR", "formatter": "simple", "filename": "errors.log", - "maxBytes": 10485760, + "maxBytes": 1048576, "backupCount": 20, "encoding": "utf8" }, diff --git a/main.py b/main.py index b3c8775..c2943a7 100644 --- a/main.py +++ b/main.py @@ -10,13 +10,22 @@ import pymysql as mariadb import os # Setup database +# db_connection = mariadb.connect(host=os.environ.get('FOBOT_DATABASE_HOST', '127.0.0.1'), +# port=os.environ.get('FOBOT_DATABASE_PORT', 3307), +# user=os.environ['FOBOT_DATABASE_USER'], +# password=os.environ['FOBOT_DATABASE_PASSWORD'], +# db=os.environ.get('FOBOT_DATABASE_NAME', 'fobot'), +# charset='utf8mb4', +# cursorclass=mariadb.cursors.DictCursor) + db_connection = mariadb.connect(host='127.0.0.1', - port=3307, - user=os.environ['FOBOT_DATABASE_USER'], - password=os.environ['FOBOT_DATABASE_PASSWORD'], - db='fobot', - charset='utf8mb4', - cursorclass=mariadb.cursors.DictCursor) + port=3307, + user='root', + password='sfkr4m37', + db='fobot', + charset='utf8mb4', + cursorclass=mariadb.cursors.DictCursor) + def to_str(entier): @@ -76,7 +85,7 @@ class Guild: self.id = guild_id self.bot = bot self.config = {"modules": ["modules"], - "prefix": "§", + "prefix": "!", "master_admins": [318866596502306816], "lang": "FR_fr" } @@ -88,24 +97,24 @@ class Guild: def load_config(self): with self.bot.database.cursor() as cursor: # Create guild table if it not exists - sql_create = """CREATE TABLE IF NOT EXISTS {guild_id} ( + sql_create = """CREATE TABLE IF NOT EXISTS {guild_id}main ( id int(5) NOT NULL AUTO_INCREMENT PRIMARY KEY, name varchar(50) NOT NULL, content JSON CHECK (JSON_VALID(content)) - );""".format(guild_id=to_str(self.id)) + );""".format(guild_id=self.id) cursor.execute(sql_create) # Load config row - sql_content = """SELECT id,name,content FROM {guild_id} WHERE name='config';""".format( - guild_id=to_str(self.id)) + sql_content = """SELECT id,name,content FROM {guild_id}main WHERE name='config';""".format( + guild_id=self.id) cursor.execute(sql_content) result = cursor.fetchone() if result is None: - sql_insert = """INSERT INTO {guild_id} (name) VALUES ('config');""".format(guild_id=to_str(self.id)) + sql_insert = """INSERT INTO {guild_id}main (name) VALUES ('config');""".format(guild_id=self.id) cursor.execute(sql_insert) self.save_config() # Refetch config - sql_content = """SELECT id,name,content FROM {guild_id} WHERE name='config';""".format( - guild_id=to_str(self.id)) + sql_content = """SELECT id,name,content FROM {guild_id}main WHERE name='config';""".format( + guild_id=self.id) cursor.execute(sql_content) result = cursor.fetchone() @@ -114,8 +123,8 @@ class Guild: def save_config(self): with self.bot.database.cursor() as cursor: - sql = r"""UPDATE {guild_id} SET content='{configjson}' WHERE name='config';""".format( - guild_id=to_str(self.id), + sql = r"""UPDATE {guild_id}main SET content='{configjson}' WHERE name='config';""".format( + guild_id=self.id, configjson=re.escape(json.dumps(self.config))) cursor.execute(sql) self.bot.database.commit() @@ -149,7 +158,7 @@ class Guild: if not msg.author.bot: for module in self.modules: await module.on_message(msg) - print(msg.content) + print(msg.guild, msg.content) return diff --git a/modules/help.py b/modules/help.py index e886b30..7d08369 100644 --- a/modules/help.py +++ b/modules/help.py @@ -45,7 +45,7 @@ class MainClass: texte += "\n" texte += exemple[0].format(prefix=self.guild.config["prefix"]) texte += ": " - texte += exemple[1] + texte += exemple[1].format(prefix=self.guild.config["prefix"]) await msg.channel.send(texte) else: await msg.channe.send(tr.tr[self.guild.config["lang"]]["errors"]["CommandNotFoundError"].format(command=fonction)) diff --git a/modules/survey.py b/modules/survey.py new file mode 100644 index 0000000..2b1c469 --- /dev/null +++ b/modules/survey.py @@ -0,0 +1,384 @@ +import os +import time + +import discord +import traductions as tr + + +def to_str(entier): + return str(entier).replace("1", "a").replace("2", "b").replace("3", "c").replace("4", "d").replace("5", "e") \ + .replace("6", "f").replace("7", "g").replace("8", "h").replace("9", "i").replace("0", "j") + + +class MainClass: + name = "survey" + + def __init__(self, guild): + self.guild = guild + self.current_surveys = {} + self.create_table() + + def create_table(self): + with self.guild.bot.database.cursor() as cursor: + create_survey_table_sql = "CREATE TABLE IF NOT EXISTS {guild_id}surveys (" \ + " id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY," \ + " title VARCHAR(2000) NOT NULL," \ + " depart BIGINT," \ + " duree BIGINT" \ + ");".format(guild_id=self.guild.id) + create_choices_table_sql = "CREATE TABLE IF NOT EXISTS {guild_id}survey_choices (" \ + " id int(20) NOT NULL AUTO_INCREMENT PRIMARY KEY," \ + " survey int(20) NOT NULL," \ + " content VARCHAR(1000)," \ + " attachment BLOB(67108864)," \ + " attachment_name VARCHAR(1000)" \ + ");".format(guild_id=self.guild.id) + create_vote_table_sql = "CREATE TABLE IF NOT EXISTS {guild_id}survey_votes (" \ + " id int NOT NULL AUTO_INCREMENT PRIMARY KEY," \ + " choice BIGINT NOT NULL," \ + " user_id VARCHAR(20) NOT NULL" \ + ");".format(guild_id=self.guild.id) + cursor.execute(create_choices_table_sql) + cursor.execute(create_survey_table_sql) + cursor.execute(create_vote_table_sql) + self.guild.bot.database.commit() + + async def vote(self, msg, command, args): + try: + await msg.delete() + except discord.Forbidden: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["DiscordForbiddenError"]) + if len(args) != 1: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"]) + return + try: + id_vote = int(args[0]) + except ValueError: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"]) + return + + with self.guild.bot.database.cursor() as cursor: + # récupération de l'id du sondage + select_choice_sql = "SELECT survey FROM `{guild_id}survey_choices` WHERE id = %s;".format( + guild_id=self.guild.id) + cursor.execute(select_choice_sql, (id_vote)) + survey_id = [r["survey"] for r in cursor.fetchall()] + + if len(survey_id) == 0: # Le choix n'existe pas + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"]) + return + + with self.guild.bot.database.cursor() as cursor: + # Récupération de la date de fin du sondage + select_survey_sql = "SELECT depart, duree FROM `{guild_id}surveys` WHERE id=%s;".format( + guild_id=self.guild.id) + cursor.execute(select_survey_sql, (survey_id)) + r = cursor.fetchone() + if r["depart"] is not None: + fin = r["depart"] + r["duree"] + else: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotYetPostedError"]) + return + # Liste des précédents votes + select_prec_votes_sql = "SELECT choice FROM `{guild_id}survey_votes` WHERE user_id=%s;".format( + guild_id=self.guild.id) + cursor.execute(select_prec_votes_sql, (msg.author.id)) + list_votes = [r["choice"] for r in cursor.fetchall()] + # Liste des précédents sondages votés + list_surveys_sql = "SELECT survey FROM `{guild_id}survey_choices` WHERE id=%s".format( + guild_id=self.guild.id) + list_surveys = [] + for id_choice in list_votes: + cursor.execute(list_surveys_sql, (id_choice)) + list_surveys.append(cursor.fetchone()["survey"]) + + if fin < time.time(): # Sondage terminé + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyCompletedError"]) + return + if survey_id[0] in list_surveys: # Déjà voté + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AlreadyVote"]) + return + + # On peu voter, on insère dans la bdd + with self.guild.bot.database.cursor() as cursor: + sql_insert = "INSERT INTO `{guild_id}survey_votes` (choice, user_id) VALUES (%s, %s);" \ + .format(guild_id=self.guild.id) + cursor.execute(sql_insert, (id_vote, msg.author.id)) + self.guild.bot.database.commit() + await msg.channel.send(tr.tr[self.guild.config["lang"]]["modules"]["survey"]["vote"] + .format(id_auteur=msg.author.id)) + + async def add_choice(self, msg, command, args): + # L'utilisateur est un administrateur du bot + if msg.author.id not in self.guild.config["master_admins"]: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"]) + return + # Vérification du nombre de paramètres + if len(args) < 2 or (len(args) < 1 and len(msg.attachments) < 1): + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"]) + return + + try: # Tentative de conversion en nombre + survey_id = int(args[0]) + except ValueError: + msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"]) + return + + # Vérification de l'existance du sondage + with self.guild.bot.database.cursor() as cursor: + sql_id = "SELECT id FROM `{guild_id}surveys`".format(guild_id=self.guild.id) + cursor.execute(sql_id, ()) + liste_id = [r["id"] for r in cursor.fetchall()] + + if survey_id not in liste_id: # Le sondage n'existe pas + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"]) + return + + # Verification que le sondage n'a pas déjà été publié + with self.guild.bot.database.cursor() as cursor: + sql_depart = "SELECT depart FROM `{guild_id}surveys` WHERE id = %s".format(guild_id=self.guild.id) + cursor.execute(sql_depart, (survey_id)) + depart = cursor.fetchone()["depart"] + if depart is not None: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AlreadySendSurvey"]) + return + + content = " ".join(args[1:]) + # Ecriture du fichier temporaire + with open("temp_attachement" + str(survey_id), "w") as temp_file: + temp_file.write("") + file_name = "" + # Si un fichier est présent dans le message on le sauvegarde + if len(msg.attachments) > 0: + attachment = msg.attachments[0] + if attachment.size > 67108864: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AttachementTooBigError"]) + return + with open("temp_attachement" + str(survey_id), "wb") as temp_file: + await attachment.save(temp_file) + file_name = attachment.filename + # On insère le choix dans la base de données + with self.guild.bot.database.cursor() as cursor: + sql_insert = "INSERT INTO `{guild_id}survey_choices` (survey, content, attachment, attachment_name) VALUES (%s, %s, %s, %s)".format( + guild_id=self.guild.id) + with open("temp_attachement" + str(survey_id), "rb") as temp_file: + cursor.execute(sql_insert, (survey_id, content, temp_file.read(), file_name)) + os.remove("temp_attachement" + str(survey_id)) + self.guild.bot.database.commit() + + async def create_survey(self, msg, command, args): + if msg.author.id not in self.guild.config["master_admins"]: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"]) + return + + if len(args) < 2: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"]) + return + else: + date_str = args[0] + content = " ".join(args[1:]) + + day_split = date_str.split("d") + if len(day_split) == 1 and "d" not in date_str: + jours = "0" + next_split = date_str + elif "d" in date_str and day_split[1] == "": + jours = day_split[0] + next_split = "0h0m0s" + else: + jours = day_split[0] + next_split = day_split[1] + + hour_split = next_split.split("h") + if len(hour_split) == 1 and "h" not in date_str: + heures = "0" + next_split = date_str + elif "h" in date_str and hour_split[1] == "": + heures = hour_split[0] + next_split = "0m0s" + else: + heures = hour_split[0] + next_split = hour_split[1] + + minute_split = next_split.split("m") + if len(minute_split) == 1 and "h" not in date_str: + minutes = "0" + next_split = date_str + elif "m" in date_str and minute_split[1] == "": + minutes = minute_split[0] + next_split = "0s" + else: + minutes = minute_split[0] + next_split = minute_split[1] + + second_split = next_split.split("s") + if len(second_split) == 1 and "s" not in date_str: + secondes = "0" + else: + secondes = second_split[0] + + try: + jours = int(jours) + heures = int(heures) + minutes = int(minutes) + secondes = int(secondes) + except ValueError: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"]) + return + + total = jours * 24 * 60 * 60 + heures * 60 * 60 + minutes * 60 + secondes # Durée du sondage + + with self.guild.bot.database.cursor() as cursor: + insert_sql = "INSERT INTO `{guild_id}surveys` (title, duree) VALUES (%s, %s);".format( + guild_id=self.guild.id) + cursor.execute(insert_sql, (content, total)) + self.guild.bot.database.commit() + await msg.channel.send(tr.tr[self.guild.config["lang"]]["modules"]["survey"]["create_survey"] + .format(id=cursor.lastrowid, prefix=self.guild.config["prefix"])) + + async def post_survey(self, msg, command, args): + if msg.author.id not in self.guild.config["master_admins"]: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"]) + return + + if len(args) != 1: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"]) + return + try: + survey_id = int(args[0]) + except ValueError: + msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"]) + return + # Vérification de l'existance du sondage + with self.guild.bot.database.cursor() as cursor: + sql_id = "SELECT id FROM `{guild_id}surveys`".format(guild_id=self.guild.id) + cursor.execute(sql_id) + liste_id = [r["id"] for r in cursor.fetchall()] + if survey_id not in liste_id: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"]) + return + # Verification que le sondage n'a pas déjà été publié + with self.guild.bot.database.cursor() as cursor: + sql_depart = "SELECT depart FROM `{guild_id}surveys` WHERE id = %s".format(guild_id=self.guild.id) + cursor.execute(sql_depart, (survey_id)) + depart = cursor.fetchone()["depart"] + if depart is not None: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AlreadySendSurvey"]) + return + # Envoi du sondage + with self.guild.bot.database.cursor() as cursor: + sql_update = "UPDATE `{guild_id}surveys` SET depart = %s WHERE id=%s" \ + .format(guild_id=self.guild.id) + cursor.execute(sql_update, (int(time.time()), survey_id)) + self.guild.bot.database.commit() + with self.guild.bot.database.cursor() as cursor: + sql_choices = "SELECT id from `{guild_id}survey_choices` WHERE survey=%s" \ + .format(guild_id=self.guild.id) + cursor.execute(sql_choices, (survey_id)) + choices_id = [r["id"] for r in cursor.fetchall()] + with self.guild.bot.database.cursor() as cursor: + sql_survey_title = "SELECT title, duree FROM `{guild_id}surveys` WHERE id = %s" \ + .format(guild_id=self.guild.id) + cursor.execute(sql_survey_title, (survey_id)) + result = cursor.fetchone() + # Envoi des messages de présentation + await msg.channel.send(tr.tr[self.guild.config["lang"]]["modules"]["survey"]["post_survey"]["presentation"] + .format(prefix=self.guild.config["prefix"], heures=int(result["duree"] / 3600))) + await msg.channel.send(result['title']) + # Envoi des message pour chaque choix + for choice_id in choices_id: + with self.guild.bot.database.cursor() as cursor: + sql_choice = "SELECT id,content, attachment, attachment_name FROM `{guild_id}survey_choices` WHERE id=%s" \ + .format(guild_id=self.guild.id) + cursor.execute(sql_choice, (choice_id)) + result = cursor.fetchone() + if result["attachment_name"]: + with open(result["attachment_name"], "wb") as temp_file: + temp_file.write(result["attachment"]) + with open(result["attachment_name"], "rb") as temp_file: + await msg.channel.send("`{prefix}vote {id}` " + .format(prefix=self.guild.config["prefix"], id=result["id"]) + result[ + "content"], + file=discord.File(temp_file, filename=str(result["attachment_name"]))) + else: + await msg.channel.send(content="`{prefix}vote {id}` " + .format(prefix=self.guild.config["prefix"], id=result["id"]) + result["content"]) + + async def post_result(self, msg, command, args): + # L'auteur est-t-il un admin? + if msg.author.id not in self.guild.config["master_admins"]: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"]) + return + # Nombre de paramètres + if len(args) != 1: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"]) + return + try: + survey_id = int(args[0]) + except ValueError: + msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"]) + return + # Vérification de l'existance du sondage + with self.guild.bot.database.cursor() as cursor: + sql_id = "SELECT id FROM `{guild_id}surveys`".format(guild_id=self.guild.id) + cursor.execute(sql_id) + liste_id = [r["id"] for r in cursor.fetchall()] + if survey_id not in liste_id: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"]) + return + # Vérification que le sondage est terminé + with self.guild.bot.database.cursor() as cursor: + # Récupération de la date de fin du sondage + select_survey_sql = "SELECT depart, duree FROM `{guild_id}surveys` WHERE id=%s;".format( + guild_id=self.guild.id) + cursor.execute(select_survey_sql, (survey_id)) + r = cursor.fetchone() + if r["depart"] is not None: + fin = r["depart"] + r["duree"] + else: + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotYetPostedError"]) + return + print(fin, time.time()) + if fin > time.time(): + await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotYetFinishedError"]) + return + + # Récupération des choix + with self.guild.bot.database.cursor() as cursor: + sql_select_choices = "SELECT id FROM `{guild_id}survey_choices` WHERE survey=%s;".format(guild_id=self.guild.id) + cursor.execute(sql_select_choices, (survey_id)) + choices = [r["id"] for r in cursor.fetchall()] + + # Récupération des votes + votes = [] + for id_choice in choices: + with self.guild.bot.database.cursor() as cursor: + select_votes_sql = "SELECT id FROM `{guild_id}survey_votes` WHERE choice=%s;".format(guild_id=self.guild.id) + cursor.execute(select_votes_sql, (id_choice)) + votes.append((id_choice,len(cursor.fetchall()))) + + votes.sort(key=lambda x:x[1]) + total = sum([x[1] for x in votes]) + texte = tr.tr[self.guild.config["lang"]]["modules"]["survey"]["result"]["text"]+"```" + i=0 + for vote in votes: + i+=1 + texte += "\n n°{i} - Choix {id_choix} - {nb_votes} ({pourcentage}%)"\ + .format(i=i, id_choix=vote[0], nb_votes=vote[1], pourcentage=vote[1]*100/total) + texte += "```" + await msg.channel.send(texte) + + 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 == "vote": + await self.vote(msg, command, args) + elif command == "add_choice": + await self.add_choice(msg, command, args) + elif command == "create_survey": + await self.create_survey(msg, command, args) + elif command == "post_survey": + await self.post_survey(msg, command, args) + elif command == "post_result": + await self.post_result(msg, command, args) + return diff --git a/traductions.py b/traductions.py index a5168c7..d3fd1fd 100644 --- a/traductions.py +++ b/traductions.py @@ -195,32 +195,68 @@ commande :smile: https://github.com/Fomys/foBot", } }, + "survey": { + "description": "Module permettant de faire des sondages", + "help": { + "create_survey": { + "description": "Créer un sondage et vous renvoie son id", + "examples": [ + ("`{prefix}create_survey 13d23h43m23s Que dites vous?`", + "Crée un sondage intitulé \"pain au chocolat ou chocolatine?\". Retourne un id.Il faut uti" + "liser la command `{prefix}add_choice` pour rajouter une option.") + ], + }, + "add_option": { + "description": "Rajoute une option àun sondage non commencé", + "examples": [ + ("`{prefix}add_option 146 Pain au chocolat`", "Ajoute l'option \"Pain au chocolat\" au sond" + "age numéro 146"), + ("`{prefix}add_option 146 Chocolatine`", "Ajoute l'option \"Chocolatine\" au sondage numéro" + " 146") + ], + }, + }, + "create_survey": "Le sondage {id} viens d'être créé. Utilisez la commande `{prefix}add_choice {id} \"Op" + "tion\"` pout ajouter une option au sondage (vous pouvez mettre un piècre jointe). Une" + " fois toutes les options ajoutées, utilisez la commande `{prefix}post_survey {id}` da" + "ns le channel où vous voulez poster le sondage. Le sondage commencera lorsque vous fe" + "rez la commande `{prefix}post_survey {id}`", + "post_survey":{ + "presentation":"Un nouveau sondage a été créé. Votez pour le choix que vous préférez avec la comman" + "de `{prefix}vote choix` en remplaçant choix par le numéro de l'option pour laquelle" + " vous votez. Ce sondage se termine dans {heures} heures. Bon vote!", + }, + "vote": "<@{id_auteur}> votre vote a bien été pris en compte", + "result": { + "text":"Voici les résultats pour le sondage" + } + }, }, "errors": { - "LangNotFoundError": "La langue {lang} est introuvable, tapez {prefix}list_lang pour voir les langues " - "disponibles.", + "LangNotFoundError": "La langue {lang} est introuvable, tapez {prefix}list_lang pour voir les langues dispo" + "nibles.", "PermissionError": "Vous n'avez pas la permission de faire cette action.", "ModuleNotFoundOrDeactivatedError": { "title": "Erreur", "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 m" + "odules disponibles.", }, "ModuleNotFoundError": { "title": "Erreur", "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 " - "disponibles.", - "text": "Le module {module} n'existe pas, tapez {prefix}list_modules pour voir la liste des modules " - "disponibles.", + "value": "Celui-ci n'existe pas. Tapez {prefix}list_modules pour voir la liste des modules disponibles." + "", + "text": "Le module {module} n'existe pas, tapez {prefix}list_modules pour voir la liste des modules dis" + "ponibles.", }, "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 " "modifiables.", "NotEnoughParamError": "Il manque un ou plusieurs parametres à la commande.", - "NoMentionsError": "Vous devez mentioner un utilisateur pour le rajouter à la liste des administrateurs " - "du bot.", + "NoMentionsError": "Vous devez mentioner un utilisateur pour le rajouter à la liste des administrateurs du " + "bot.", "OreNotFoundError": "{ore} n'est pas un minerais valide.", "NotIntError": "{number} n'est pas un nombre entier valide.", "ItemNotFoundError": "{item} n'extiste pas dans deeptown", @@ -230,6 +266,16 @@ commande :smile: https://github.com/Fomys/foBot", "ForbiddenRegexError": "Vous n'avez pas le droit d'utiliser les caractères `*` et `+` dans une regex.", "RegexTooLongError": "La regex ne doit pas faire plus e 50 caractères", "PiFileError": "Les décimales de pi sont indisponibles, veuillez réessayer plus tard...", + "AttachementTooBigError": "Le fichier join est trop volumineux, veuillez le compresser avant de réessayer", + "SurveyNotExistsError": "Le sondage que vous demandez n'existe pas.", + "NotANumberError": "La valeur que vous avezpassé en paramètre n'est pas un nombre valide.", + "AlreadySendSurvey": "Le sondage que vous essayez de poster a déjà été posté", + "SurveyCompletedError": "Le sondage que vous demandez est terminé", + "AlreadyVote": "Vous avez déjà voté pour ce sondage", + "NotYetPostedError": "Le sondage que vous demandez n'a pas encore été publié", + "NotYetFinishedError": "Le sondage que vous demandez n'est pas fini, pour éviter d'influencer les autres vo" + "tes les résultats ne seront disponibles que à la fin.", + "DiscordForbiddenError": "Je n'ai pas les droits pour supprimer le message." }, }, }