Compare commits

...
This repository has been archived on 2022-06-13. You can view files and clone it, but cannot push or open issues or pull requests.

12 commits
main ... dev-v2

Author SHA1 Message Date
0581be7f6d first attempt to add promice support 2021-11-02 01:58:53 +01:00
1f29ea0d1a Changes:
discord.py 1.7.3 -> enhanced discord py main branch
pytz 2021.1 -> 2021.3
remove discord py slash command
wavelink 0.9.10 -> pomice 1.1.1
discord together 1.1.1 -> 1.2.1
2021-11-02 01:58:31 +01:00
c3e11519c4 Update Lavalink main branch 2021-11-01 22:44:37 +01:00
ce7ad42bb9 Add mirror and fast clone method 2021-11-01 22:37:52 +01:00
7d30eae1f2 Fix issue wrong message when vol == 0 2021-10-11 13:30:01 +02:00
8c35af16ff fix typo 2021-09-22 20:08:06 +02:00
ef1816be20 Adding Feature in the list 2021-09-20 11:17:55 +02:00
abd62d7c6d check if DM are closed and don't stop at first error 2021-09-20 11:14:51 +02:00
dac6ed6112 remove debug print 2021-09-20 11:12:09 +02:00
1b7b4d0507 Addition of a recap of the ToDo's every Saturday at 9am 2021-09-20 11:07:45 +02:00
be47cc43b0 fix error when adding reaction in DM channel 2021-09-20 11:06:59 +02:00
f9c02e6c95 bump to 1.7 2021-09-20 09:12:02 +02:00
10 changed files with 296 additions and 1005 deletions

View file

@ -1,7 +1,8 @@
# Bot Discord # Bot Discord
[![Version](https://img.shields.io/badge/version-1.6-green?style=for-the-badge)](https://gitlab.com/ConfrerieDuKassoulait/KassouBot/-/releases) [![Version](https://img.shields.io/badge/version-1.7-green?style=for-the-badge)](https://gitlab.com/ConfrerieDuKassoulait/KassouBot/-/releases)
[![Build](https://img.shields.io/gitlab/pipeline/ConfrerieDuKassoulait/KassouBot/dev?style=for-the-badge)](https://gitlab.com/ConfrerieDuKassoulait/KassouBot/container_registry) [![Build](https://img.shields.io/gitlab/pipeline/ConfrerieDuKassoulait/KassouBot/dev?style=for-the-badge)](https://gitlab.com/ConfrerieDuKassoulait/KassouBot/container_registry)
[![Mirror](https://img.shields.io/badge/Mirror-brightgreen?style=for-the-badge)](https://git.kennel.ml/ConfrerieDuKassoulait/KassouBot)
## __Features__ ## __Features__
@ -9,7 +10,7 @@
- Slash commands support (use [Discord Interactions](https://github.com/goverfl0w/discord-interactions)). - Slash commands support (use [Discord Interactions](https://github.com/goverfl0w/discord-interactions)).
- Party games activities support (use [Discord Together](https://github.com/apurv-r/discord-together)). - Party games activities support (use [Discord Together](https://github.com/apurv-r/discord-together)).
- Music support (use [Lavalink](https://github.com/freyacodes/Lavalink) with the [Wavelink](https://github.com/PythonistaGuild/Wavelink) client). - Music support (use [Lavalink](https://github.com/freyacodes/Lavalink) with the [Wavelink](https://github.com/PythonistaGuild/Wavelink) client).
- Reminders and Todos list support. - Reminders and ToDos list support (with a weekly reminder of the ToDos list in DM).
- Poll support. - Poll support.
- Meme from reddit and NSFW pictures support. - Meme from reddit and NSFW pictures support.
- Basics commands and simple games, don't mind on opening an issue if you wan't your idea to be added to the bot. - Basics commands and simple games, don't mind on opening an issue if you wan't your idea to be added to the bot.
@ -77,6 +78,10 @@ To find Genius token, go to [this site](https://genius.com/api-clients), `login
## __Launching locally__ ## __Launching locally__
If you want to run it without Docker, clone the repo and his submodules by doing this command in the git folder: If you want to run it without Docker, clone the repo and his submodules by doing this command in the git folder:
```batch ```batch
git clone git@gitlab.com:ConfrerieDuKassoulait/KassouBot.git --recursive
```
If you already cloned the repo without the `--recursive` arg you can do that in the git folder :
```batch
git submodule update --force --recursive --init --remote git submodule update --force --recursive --init --remote
``` ```
Then create an .env file to store variables in the root folder (there is an example [here](https://gitlab.com/ConfrerieDuKassoulait/KassouBot/-/blob/main/.envexample)). Then create an .env file to store variables in the root folder (there is an example [here](https://gitlab.com/ConfrerieDuKassoulait/KassouBot/-/blob/main/.envexample)).

View file

@ -1,10 +1,8 @@
discord.py[voice]==1.7.3 # discord git+https://github.com/iDevision/enhanced-discord.py.git # discord
git+https://github.com/Rapptz/discord-ext-menus.git # discord menus pytz==2021.3 # timezone
pytz==2021.1 # timezone
asyncpraw==7.4.0 # reddit asyncpraw==7.4.0 # reddit
lyricsgenius==3.0.1 # lyrics lyricsgenius==3.0.1 # lyrics
feedparser==6.0.8 # rss feed (news) feedparser==6.0.8 # rss feed (news)
discord-py-slash-command==3.0.1 # slash commands python_dotenv==0.19.1 # using .env file
python_dotenv==0.19.0 # using .env file pomice==1.1.1 # music | to know the version of lavalink used, see the repo
wavelink==0.9.10 # music | to know the version of lavalink used, see the repo discord-together==1.2.1 # for the party games
discord-together==1.1.1 # for the party games

View file

@ -133,7 +133,9 @@ class ConfrerieDuKassoulait(commands.Cog):
await payload.member.add_roles(payload.member.guild.get_role(self.messageDictAndEmojiToRoles[payload.message_id][payload.emoji.id])) await payload.member.add_roles(payload.member.guild.get_role(self.messageDictAndEmojiToRoles[payload.message_id][payload.emoji.id]))
except: except:
await payload.member.add_roles(payload.member.guild.get_role(self.messageDictAndEmojiToRoles[payload.message_id][str(payload.emoji)])) await payload.member.add_roles(payload.member.guild.get_role(self.messageDictAndEmojiToRoles[payload.message_id][str(payload.emoji)]))
except KeyError: except KeyError: # mauvais message ou réaction
return
except AttributeError: # reaction en DM
return return
@commands.Cog.listener() @commands.Cog.listener()
@ -148,3 +150,5 @@ class ConfrerieDuKassoulait(commands.Cog):
await member.remove_roles(guild.get_role(self.messageDictAndEmojiToRoles[payload.message_id][str(payload.emoji)])) await member.remove_roles(guild.get_role(self.messageDictAndEmojiToRoles[payload.message_id][str(payload.emoji)]))
except KeyError: except KeyError:
return return
except AttributeError: # reaction en DM
return

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
from discord.ext import commands from discord.ext import commands, tasks
from discord_slash import cog_ext from discord_slash import cog_ext
from utils.todo import ToDo, embedListeToDo from utils.todo import ToDo, embedListeToDo
from utils.core import getMentionInString, isSlash, mySendHidden from utils.core import getMentionInString, isSlash, mySendHidden
from utils.core import addReaction, mentionToUser from utils.core import addReaction, mentionToUser
from utils.time import nowUTC from utils.time import nowUTC, timeBeforeNextSaturdayAtNineHours
def setup(client): def setup(client):
"""Adding Cog to bot""" """Adding Cog to bot"""
@ -13,8 +13,46 @@ class ToDoDiscord(commands.Cog, name="Todo"):
"""Commandes relatives aux To Do.""" """Commandes relatives aux To Do."""
def __init__(self, client): def __init__(self, client):
self.client = client self.client = client
self._todoLoop.start()
ToDo().creationTable() ToDo().creationTable()
@tasks.loop(minutes = 1) # ce temps est ignoré
async def _todoLoop(self):
"""Méthode qui se répète toute les samedis pour envoyer un récapitulatif des Todos."""
if self._todoLoop.current_loop in (0, 2): # ignore des boucles non voulue (#1 se lance au démarrage et #3 au changement de l'intervalle)
return
elif self._todoLoop.current_loop == 1: # premier vrai lancement
self._todoLoop.change_interval(hours = 168) # prochain lancement dans 1 semaine
todos = []
listIDs = []
for todo in ToDo().listAll():
if todo[0] in listIDs:
pass
else:
todos.append(todo)
listIDs.append(todo[0])
for todo in todos:
user = self.client.get_user(todo[0])
if user == None: # si l'utilisateur n'est pas trouvé
pass # on ignore l'utilisateur
channel = await user.create_dm() # envoie en DM
embed, pageMAX = await embedListeToDo(user, 1)
try:
message = await channel.send("Récapitulatif hebdomadaire de vos To Do's", embed = embed)
except: # Les DM sont fermés
pass # on ignore l'envoie du récap
if pageMAX > 1:
for emoji in ["⬅️", "➡️"]:
await message.add_reaction(emoji)
else:
await message.add_reaction("🔄")
@_todoLoop.before_loop
async def __avant_todoLoop(self):
"""Wait to start the loop until the whole bot is ready"""
await self.client.wait_until_ready()
self._todoLoop.change_interval(seconds = timeBeforeNextSaturdayAtNineHours())
@commands.command(name='todo') @commands.command(name='todo')
async def _todo(self, ctx, *todo): async def _todo(self, ctx, *todo):
"""Met en place un To Do.\n ➡ Syntaxe: {PREFIX}todo <message>""" """Met en place un To Do.\n ➡ Syntaxe: {PREFIX}todo <message>"""
@ -36,7 +74,7 @@ class ToDoDiscord(commands.Cog, name="Todo"):
todoID = ToDo().ajout(messageID, todo, now, ctx.author.id) todoID = ToDo().ajout(messageID, todo, now, ctx.author.id)
if fromSlash != True: if fromSlash != True:
await addReaction(ctx.message, 0) await addReaction(ctx.message, 0)
return await mySendHidden(ctx, fromSlash, f"To Do **`#{todoID[0][0]}`** enrengistré !") return await mySendHidden(ctx, fromSlash, f"To Do **`#{todoID[0][0]}`** enregistré !")
@cog_ext.cog_slash(name="todo", description = "Met en place un To Do.") @cog_ext.cog_slash(name="todo", description = "Met en place un To Do.")
async def __todo(self, ctx, todo): async def __todo(self, ctx, todo):
"""Slash command""" """Slash command"""

@ -1 +1 @@
Subproject commit 570730f3ae83dab0c4a8c61dde1c9094957c6ad4 Subproject commit c39d9220a08c9547b36de85dc9b27e8c89b1c6b2

View file

@ -2,15 +2,13 @@ print("Chargement des extensions & librairie...", end = " ")
import discord import discord
from os import listdir, rename, getcwd from os import listdir, rename, getcwd
from discord_slash import SlashCommand
from discord.ext import commands from discord.ext import commands
from utils.core import load, addReaction from utils.core import load, addReaction
from utils.page import listReaction from utils.page import listReaction
keys = load(["PREFIX", "TOKEN_DISCORD", "DEACTIVATE"]) keys = load(["PREFIX", "TOKEN_DISCORD", "DEACTIVATE"])
customPrefix = keys["PREFIX"] customPrefix = keys["PREFIX"]
client = commands.Bot(command_prefix = customPrefix, case_insensitive = True, intents = discord.Intents.all()) client = commands.Bot(command_prefix = customPrefix, case_insensitive = True, intents = discord.Intents.all(), slash_commands = True)
slash = SlashCommand(client, sync_commands = True)
client.cogs_folder = "cogs" client.cogs_folder = "cogs"
@ -23,9 +21,10 @@ if keys["DEACTIVATE"] != "None":
print(f"No file {file} found, check your \"DEACTIVATE\" variable.") print(f"No file {file} found, check your \"DEACTIVATE\" variable.")
exit(1) exit(1)
for file in listdir(client.cogs_folder): """ for file in listdir(client.cogs_folder):
if file.endswith(".py") and file.startswith("-") == False: if file.endswith(".py") and file.startswith("-") == False:
client.load_extension(f"{client.cogs_folder}.{file[:-3]}") client.load_extension(f"{client.cogs_folder}.{file[:-3]}") """
client.load_extension(f"cogs.music")
print("Terminé !") print("Terminé !")
@client.event @client.event

View file

@ -9,8 +9,12 @@ async def listReaction(client, payload):
""" """
if payload.emoji.name in ["⬅️", "🔄", "➡️"]: if payload.emoji.name in ["⬅️", "🔄", "➡️"]:
if payload.event_type == "REACTION_ADD": if payload.event_type == "REACTION_ADD":
if payload.member.bot == True: # vérifie que c'est pas un bot qui a réagit if payload.member: # check car pas de member en DM
return False, False if payload.member.bot == True: # vérifie que c'est pas un bot qui a réagit
return False, False
else:
if client.get_user(payload.user_id).bot == True: # vérifie que c'est pas un bot qui a réagit
return False, False
channel = client.get_channel(payload.channel_id) channel = client.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id) message = await channel.fetch_message(payload.message_id)
if message.author.id != client.user.id or len(message.embeds) == 0: # vérification message du bot + au moins 1 embed if message.author.id != client.user.id or len(message.embeds) == 0: # vérification message du bot + au moins 1 embed

View file

@ -129,3 +129,16 @@ def ageLayout(tuple):
for i in affichage: for i in affichage:
message = message + f", {tuple[i]} {time[i]}" message = message + f", {tuple[i]} {time[i]}"
return message[2:] return message[2:]
def timeBeforeNextSaturdayAtNineHours() -> int:
"""Envoie le nombre de secondes qu'il y a avant le prochain Samedi à 9h"""
date = datetime.today()
now = date
# prochain 9h
while date.hour != 9:
date = date + timedelta(hours = 1)
# prochain samedi
while date.strftime("%A") != "Saturday":
date = date + timedelta(days = 1)
delta = date - now
return int(delta.total_seconds())

View file

@ -47,6 +47,13 @@ class ToDo(Database):
""" """
return self.affichageResultat(self.requete(requete, userID)) return self.affichageResultat(self.requete(requete, userID))
def listAll(self):
"""Retourne la liste de tout les To Do."""
requete = """
SELECT user_id, id, todo_str, creation_int FROM todo
"""
return self.affichageResultat(self.requete(requete))
def appartenance(self, userID: int, id: int): 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.""" """Vérifie qu'un To Do appartiens à un utilisateur. Renvois False si le To Do n'existe pas."""
requete = """ requete = """