Compare commits
12 commits
Author | SHA1 | Date | |
---|---|---|---|
0581be7f6d | |||
1f29ea0d1a | |||
c3e11519c4 | |||
ce7ad42bb9 | |||
7d30eae1f2 | |||
8c35af16ff | |||
ef1816be20 | |||
abd62d7c6d | |||
dac6ed6112 | |||
1b7b4d0507 | |||
be47cc43b0 | |||
f9c02e6c95 |
10 changed files with 296 additions and 1005 deletions
|
@ -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)).
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
1191
src/cogs/music.py
1191
src/cogs/music.py
File diff suppressed because it is too large
Load diff
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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 = """
|
||||||
|
|
Reference in a new issue