diff --git a/src/cogs/todo.py b/src/cogs/todo.py new file mode 100644 index 0000000..8f67603 --- /dev/null +++ b/src/cogs/todo.py @@ -0,0 +1,104 @@ +from discord.ext import commands +from discord_slash import cog_ext +from utils.todo import ToDo, embedListeToDo +from utils.core import getMentionInString, isSlash, mySendHidden +from utils.core import addReaction, mentionToUser +from utils.time import nowUTC + +def setup(client): + """Adding Cog to bot""" + client.add_cog(ToDoDiscord(client)) + +class ToDoDiscord(commands.Cog, name="ToDo"): + """Commandes relatives aux To Do.""" + def __init__(self, client): + self.client = client + + @commands.command(name='todo') + async def _todo(self, ctx, *todo): + """Met en place un To Do.⁢⁢⁢⁢⁢\n ➡ Syntaxe: {PREFIX}todo """ + _, fromSlash, todo = isSlash(todo) + if len(todo) > 0: + todo = " ".join(todo) + else: + todo = None + + if not todo: + return await mySendHidden(ctx, fromSlash, "Tu n'as pas spécifié de message.") + else: + now = int(nowUTC()) + messageID = None + if fromSlash != True: + messageID = ctx.message.id + todoID = ToDo().ajout(messageID, todo, now, ctx.author.id) + if fromSlash != True: + await addReaction(ctx.message, 0) + return await mySendHidden(ctx, fromSlash, f"To Do **`#{todoID[0][0]}`** enrengistré !.") + @cog_ext.cog_slash(name="todo", description = "Met en place un To Do.") + async def __todo(self, ctx, todo): + """Slash command""" + return await self._todo(ctx, todo, True) + + @commands.command(name='todolist', aliases=["tdl"]) + async def _todolist(self, ctx, *arg): + """Affiche la liste des To Do's d'un utilisateur.⁢⁢⁢⁢⁢\n ➡ Syntaxe: {PREFIX}todolist/tdl [utilisateur]""" + _, fromSlash, arg = isSlash(arg) + utilisateur = ctx.author + page = 1 + erreur = False + if len(arg) > 0: + for i in range(0, len(arg)): + try: + utilisateur = self.client.get_user(mentionToUser(getMentionInString(arg[i])[0])) + except: + try: + page = int(arg[i]) + except: + erreur = True + if erreur == True: + return await mySendHidden(ctx, fromSlash, "Veuillez renseigné un utilisateur ou un numéro de page valide.") + + if fromSlash != True: + await addReaction(ctx.message, 0) + + embed, pageMAX = await embedListeToDo(utilisateur, page) + message = await ctx.send(embed = embed) + if pageMAX > 1: + for emoji in ["⬅️", "➡️"]: + await message.add_reaction(emoji) + else: + await message.add_reaction("🔄") + @cog_ext.cog_slash(name="todolist", description = "Affiche la liste des To Do's d'un utilisateur.") + async def __todolist(self, ctx, userorpage = None): + """Slash command""" + if userorpage == None: + return await self._todolist(ctx, True) + else: + return await self._todolist(ctx, userorpage, True) + + @commands.command(name='tododelete', aliases=["tdd"]) + async def _tododelete(self, ctx, *id): + """Suppprime un To Do.⁢⁢⁢⁢⁢\n ➡ Syntaxe: {PREFIX}tododelete/tdd """ + id, fromSlash, _ = isSlash(id) + if id: + try: + id = int(id) + except: + return await mySendHidden(ctx, fromSlash, "L'ID renseigné n'est pas valide.") + else: + return await ctx.send("Veuillez renseigner un ID.") + + verification = ToDo().appartenance(ctx.author.id, id) + if verification: + ToDo().suppression(id) + if fromSlash != True: + await addReaction(ctx.message, 0) + return await mySendHidden(ctx, fromSlash, f"To Do **#{id}** supprimé !") + else: + if fromSlash != True: + await addReaction(ctx.message, 2) + return await mySendHidden(ctx, fromSlash, "To Do non trouvé, ou peut-être qu'il ne vous appartiens pas.") + @cog_ext.cog_slash(name="tododelete", description = "Suppprime un To Do.") + async def __tododelete(self, ctx, id): + """Slash command""" + return await self._tododelete(ctx, id, True) diff --git a/src/main.py b/src/main.py index 2704bbd..584dd24 100644 --- a/src/main.py +++ b/src/main.py @@ -5,6 +5,7 @@ from os import listdir, rename, getcwd from discord_slash import SlashCommand from discord.ext import commands from utils.reminder import Reminder +from utils.todo import ToDo from utils.core import load, addReaction from utils.page import listReaction keys = load(["PREFIX", "TOKEN_DISCORD", "DEACTIVATE"]) @@ -49,6 +50,7 @@ async def on_ready(): """Triggered when the bot is ready to operate""" await client.change_presence(status = discord.Status.online, activity = discord.Activity(name = f"{customPrefix}help", type = discord.ActivityType.playing)) Reminder().creationTable() + ToDo().creationTable() print("Bot prêt.") @client.event diff --git a/src/utils/todo.py b/src/utils/todo.py new file mode 100644 index 0000000..37bb378 --- /dev/null +++ b/src/utils/todo.py @@ -0,0 +1,92 @@ +from utils.db import Database +from discord import Embed, Colour +from utils.time import nowUTC, intToDatetime, timedeltaToString, timestampScreen + +class ToDo(Database): + def __init__(self): + super().__init__(r"db/bot.sqlite3") + + def creationTable(self): + """Créer la table qui stocke les To Do.""" + requete = """ + CREATE TABLE IF NOT EXISTS todo ( + id INTEGER PRIMARY KEY, + message_id INTEGER, + todo_str TEXT, + creation_int INTEGER, + user_id INTEGER + ); + """ + self.requete(requete) + + def ajout(self, messageID: int, todo: str, creation: int, userID: int): + """Ajoute un To Do.""" + requete = """ + INSERT INTO todo ( + message_id, todo_str, creation_int, user_id + ) VALUES ( + ?, ?, ?, ? + ); + """ + self.requete(requete, [messageID, todo, creation, userID]) + return self.affichageResultat(self.requete("SELECT last_insert_rowid();")) + + def suppression(self, id: int): + """Supprime un To Do.""" + requete = """ + DELETE FROM todo + WHERE id = ? + """ + self.requete(requete, id) + + def liste(self, userID: int): + """Retourne la liste des To Do d'un utilisateur.""" + requete = """ + SELECT id, todo_str, creation_int FROM todo + WHERE user_id = ? + """ + return self.affichageResultat(self.requete(requete, userID)) + + def appartenance(self, userID: int, id: int): + """Vérifie qu'un To Do appartiens à un utilisateur. Renvois False si le To Do n'existe pas.""" + requete = """ + SELECT EXISTS ( + SELECT 1 FROM todo + WHERE id = ? AND user_id = ? + ) + """ + return True if self.affichageResultat(self.requete(requete, [id, userID]))[0][0] == 1 else False + +async def embedListeToDo(utilisateur, page, color = None, refresh_message = None): + """Fais l'embed d'une page pour l'affichage de la liste des To Do d'un utilisateur.""" + todos = ToDo().liste(utilisateur.id) + pageMAX = -(-len(todos) // 5) + + if refresh_message: + if len(todos) > 0: + if pageMAX > 1 and refresh_message.reactions[0] != "⬅️": + for emoji in ["⬅️", "➡️"]: + await refresh_message.add_reaction(emoji) + else: + return (False, False) + + if pageMAX == 1: + page = 1 # force page 1 + if color == None: + color = Colour.random() + s = "'s" + embed = Embed(description = f"**To Do{s if len(todos) > 1 else ''} de {utilisateur.mention}** • Page {page}/{pageMAX}", color = color) + embed.set_thumbnail(url = utilisateur.avatar_url_as(size = 64)) + limit = 5 * page + if len(todos) > 0 and page <= pageMAX: + curseur = limit - 4 + for todo in todos[limit - 5:]: + if curseur <= limit: + texte = todo[1] + if len(texte) > 1024: + texte = f"{texte[:1021]}..." + embed.add_field(value = texte, name = f"#{todo[0]} • Fais le {timestampScreen(intToDatetime(todo[2]))}", inline = False) + curseur += 1 + else: + embed.add_field(name = "\u200b", value = f"L'utilisateur n'a aucun To Do ou page n°{page} vide !") + return (embed, pageMAX)