add types, refactor code
This commit is contained in:
parent
589e062ad2
commit
114701c230
6 changed files with 103 additions and 98 deletions
31
src/client.py
Normal file
31
src/client.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
from twitchio import Message
|
||||||
|
from twitchio.ext import commands
|
||||||
|
from utils.commands import CommandesDB
|
||||||
|
from utils.core import load
|
||||||
|
|
||||||
|
|
||||||
|
class Client(commands.Bot):
|
||||||
|
def __init__(self):
|
||||||
|
self.keys = load(["ACCESS_TOKEN", "PREFIX", "CHANNEL"])
|
||||||
|
super().__init__(
|
||||||
|
token=self.keys["ACCESS_TOKEN"],
|
||||||
|
prefix=self.keys["PREFIX"],
|
||||||
|
initial_channels=self.keys["CHANNEL"],
|
||||||
|
)
|
||||||
|
|
||||||
|
async def event_ready(self) -> None:
|
||||||
|
CommandesDB().creationTable()
|
||||||
|
print(f"Logged in as {self.nick}")
|
||||||
|
|
||||||
|
async def event_message(self, message: Message) -> None:
|
||||||
|
if message.echo: # messages with echo set to True are messages sent by the bot
|
||||||
|
return
|
||||||
|
|
||||||
|
# Let the bot know we want to handle and invoke our commands
|
||||||
|
await self.handle_commands(message)
|
||||||
|
|
||||||
|
async def event_command_error(self, _, error) -> None:
|
||||||
|
if isinstance(error, commands.errors.CommandNotFound):
|
||||||
|
# Ignore unknown commands (useful because custom commands aren't known)
|
||||||
|
return
|
||||||
|
raise error
|
36
src/main.py
36
src/main.py
|
@ -1,43 +1,13 @@
|
||||||
from os import listdir
|
from os import listdir
|
||||||
|
|
||||||
from twitchio.ext import commands
|
from client import Client
|
||||||
from utils.commands import CommandesDB
|
|
||||||
from utils.core import load
|
|
||||||
|
|
||||||
|
|
||||||
class Client(commands.Bot):
|
|
||||||
def __init__(self):
|
|
||||||
self.keys = load(["ACCESS_TOKEN", "PREFIX", "CHANNEL"])
|
|
||||||
super().__init__(
|
|
||||||
token=self.keys["ACCESS_TOKEN"],
|
|
||||||
prefix=self.keys["PREFIX"],
|
|
||||||
initial_channels=self.keys["CHANNEL"],
|
|
||||||
)
|
|
||||||
|
|
||||||
async def event_ready(self):
|
|
||||||
CommandesDB().creationTable()
|
|
||||||
print(f"Logged in as {self.nick}")
|
|
||||||
|
|
||||||
async def event_message(self, message):
|
|
||||||
if message.echo: # Messages with echo set to True are messages sent by the bot
|
|
||||||
return
|
|
||||||
|
|
||||||
await self.handle_commands(
|
|
||||||
message
|
|
||||||
) # Let the bot know we want to handle and invoke our commands
|
|
||||||
|
|
||||||
async def event_command_error(self, _, error):
|
|
||||||
if isinstance(
|
|
||||||
error, commands.errors.CommandNotFound
|
|
||||||
): # Ignore unknown commands (useful because custom commands aren’t known)
|
|
||||||
return
|
|
||||||
raise error
|
|
||||||
|
|
||||||
|
|
||||||
client = Client()
|
client = Client()
|
||||||
|
|
||||||
|
# Load modules
|
||||||
for file in listdir("modules"):
|
for file in listdir("modules"):
|
||||||
if file.endswith(".py") and file.startswith("-") is False:
|
if file.endswith(".py") and file.startswith("-") is False:
|
||||||
client.load_module(f"modules.{file[:-3]}")
|
client.load_module(f"modules.{file[:-3]}")
|
||||||
|
|
||||||
|
print("Starting..", end=" ", flush=True)
|
||||||
client.run()
|
client.run()
|
||||||
|
|
|
@ -8,7 +8,8 @@ from utils.commands import CommandesDB, existeCommande, existeTouteCommande
|
||||||
from utils.core import listCommands, load
|
from utils.core import listCommands, load
|
||||||
|
|
||||||
|
|
||||||
def prepare(client: Bot):
|
def prepare(client: Bot) -> None:
|
||||||
|
"""Add the module to the client"""
|
||||||
client.add_cog(Commandes(client))
|
client.add_cog(Commandes(client))
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,9 +19,9 @@ class Commandes(Cog):
|
||||||
def __init__(self, client: Bot):
|
def __init__(self, client: Bot):
|
||||||
self.client = client
|
self.client = client
|
||||||
self.prefix = load(["PREFIX"])["PREFIX"]
|
self.prefix = load(["PREFIX"])["PREFIX"]
|
||||||
self.notModo = "tu n'es pas modérateur"
|
self.not_a_mod = "tu n'es pas modérateur"
|
||||||
self.notExistingCommand = "cette commande n'existe pas"
|
self.unknown_command = "cette commande n'existe pas"
|
||||||
self.alreadyExistingCommand = (
|
self.existing_command = (
|
||||||
f"cette commande existe déjà, {self.prefix}edit <name> <msg> pour l'éditer"
|
f"cette commande existe déjà, {self.prefix}edit <name> <msg> pour l'éditer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,89 +36,89 @@ class Commandes(Cog):
|
||||||
"""
|
"""
|
||||||
if name is None or message is None:
|
if name is None or message is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
author = cast(Chatter, ctx.author)
|
author = cast(Chatter, ctx.author)
|
||||||
if author.is_mod:
|
if author.is_mod:
|
||||||
if existeTouteCommande(self.client, name)[0] is False:
|
if existeTouteCommande(self.client, name) is False:
|
||||||
CommandesDB().ajoutCommande(name, message)
|
CommandesDB().ajoutCommande(name, message)
|
||||||
await ctx.send(f"@{ctx.author.name}, commande {name} ajoutée !")
|
await ctx.send(f"@{ctx.author.name}, commande {name} ajoutée !")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"@{ctx.author.name}, {self.alreadyExistingCommand}.")
|
await ctx.send(f"@{ctx.author.name}, {self.existing_command}.")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"@{ctx.author.name}, {self.notModo}.")
|
await ctx.send(f"@{ctx.author.name}, {self.not_a_mod}.")
|
||||||
|
|
||||||
@new(name="remove", aliases=["delete", "suppr", "supprimer"], no_global_checks=True)
|
@new(name="remove", aliases=["delete", "suppr", "supprimer"], no_global_checks=True)
|
||||||
async def _remove(self, ctx: Context, commandName: str | None = None) -> None:
|
async def _remove(self, ctx: Context, name: str | None = None) -> None:
|
||||||
"""
|
"""
|
||||||
Supprime une commande de la base de donnée du bot
|
Supprime une commande de la base de donnée du bot
|
||||||
|
|
||||||
`remove name`
|
`remove name`
|
||||||
"""
|
"""
|
||||||
if commandName is None:
|
if name is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
author = cast(Chatter, ctx.author)
|
author = cast(Chatter, ctx.author)
|
||||||
if author.is_mod:
|
if author.is_mod:
|
||||||
if existeCommande(commandName)[0]:
|
if existeCommande(name)[0]:
|
||||||
CommandesDB().suppressionCommande(commandName)
|
CommandesDB().suppressionCommande(name)
|
||||||
await ctx.send(
|
await ctx.send(f"@{ctx.author.name}, commande {name} supprimée !")
|
||||||
f"@{ctx.author.name}, commande {commandName} supprimée !"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"@{ctx.author.name}, {self.notExistingCommand}.")
|
await ctx.send(f"@{ctx.author.name}, {self.unknown_command}.")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"@{ctx.author.name}, {self.notModo}.")
|
await ctx.send(f"@{ctx.author.name}, {self.not_a_mod}.")
|
||||||
|
|
||||||
@new(name="list", aliases=["liste", "commands", "commandes", "help", "aide"])
|
@new(name="list", aliases=["liste", "commands", "commandes", "help", "aide"])
|
||||||
async def _list(self, ctx: Context) -> None:
|
async def _list(self, ctx: Context) -> None:
|
||||||
"""Affiche la liste des commandes de la base de donnée du bot"""
|
"""Affiche la liste des commandes de la base de donnée du bot"""
|
||||||
commandes = CommandesDB().listeCommande()
|
commandes: list[str] = [item[0] for item in CommandesDB().listeCommande()]
|
||||||
|
|
||||||
author = cast(Chatter, ctx.author)
|
author = cast(Chatter, ctx.author)
|
||||||
for command in listCommands(self.client):
|
for command in listCommands(self.client):
|
||||||
name = command.name
|
name = command.name
|
||||||
if command.no_global_checks:
|
if command.no_global_checks and author.is_mod:
|
||||||
if author.is_mod:
|
continue
|
||||||
continue
|
|
||||||
if command.aliases:
|
if command.aliases:
|
||||||
name += " (alias: "
|
name += " (alias: "
|
||||||
for aliase in command.aliases:
|
for aliase in command.aliases:
|
||||||
name += f"{self.prefix}{aliase}, "
|
name += f"{self.prefix}{aliase}, "
|
||||||
name = f"{name[:-2]})"
|
name = f"{name[:-2]})"
|
||||||
commandes.append((name,))
|
commandes.append(name)
|
||||||
|
|
||||||
if len(commandes) > 0:
|
if len(commandes) > 0:
|
||||||
message = f"@{ctx.author.name}, liste des commandes -> "
|
await ctx.send(
|
||||||
for commande in commandes:
|
f"@{ctx.author.name}, liste des commandes -> "
|
||||||
message += f"{self.prefix}{commande[0]}, "
|
+ self.prefix
|
||||||
await ctx.send(message[:-2])
|
+ f", {self.prefix}".join(commandes)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"@{ctx.author.name}, aucune commande enrengistrée dans la base de donnée."
|
f"@{ctx.author.name}, aucune commande enregistrée dans la base de donnée."
|
||||||
)
|
)
|
||||||
|
|
||||||
@new(name="edit", no_global_checks=True)
|
@new(name="edit", no_global_checks=True)
|
||||||
async def _edit(
|
async def _edit(
|
||||||
self,
|
self,
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
commandName: str | None = None,
|
name: str | None = None,
|
||||||
commandMessage: str | None = None,
|
message: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Modifie une commande de la base de donnée du bot
|
Modifie une commande de la base de donnée du bot
|
||||||
|
|
||||||
add name new_message
|
add name new_message
|
||||||
"""
|
"""
|
||||||
if commandName is None or commandMessage is None:
|
if name is None or message is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
author = cast(Chatter, ctx.author)
|
author = cast(Chatter, ctx.author)
|
||||||
if author.is_mod:
|
if author.is_mod:
|
||||||
if existeCommande(commandName)[0]:
|
if existeCommande(name)[0]:
|
||||||
CommandesDB().suppressionCommande(commandName)
|
CommandesDB().suppressionCommande(name)
|
||||||
CommandesDB().ajoutCommande(commandName, commandMessage)
|
CommandesDB().ajoutCommande(name, message)
|
||||||
await ctx.send(f"@{ctx.author.name}, commande {commandName} modifiée !")
|
await ctx.send(f"@{ctx.author.name}, commande {name} modifiée !")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"@{ctx.author.name}, {self.notExistingCommand}.")
|
await ctx.send(f"@{ctx.author.name}, {self.unknown_command}.")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"@{ctx.author.name}, {self.notModo}.")
|
await ctx.send(f"@{ctx.author.name}, {self.not_a_mod}.")
|
||||||
|
|
||||||
@Cog.event("event_message") # type: ignore
|
@Cog.event("event_message") # type: ignore
|
||||||
async def _event_message(self, message: Message) -> None:
|
async def _event_message(self, message: Message) -> None:
|
||||||
|
@ -125,9 +126,8 @@ class Commandes(Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
if message.content.startswith(self.prefix):
|
if message.content.startswith(self.prefix):
|
||||||
command = existeCommande(
|
# Récupère le nom de la commande
|
||||||
message.content[1:].split(" ")[0]
|
command = existeCommande(message.content[1:].split(" ")[0])
|
||||||
) # récupère le nom de la commande
|
if command[0]: # vérification si elle existe
|
||||||
if command[0]: # vérification si existe
|
# Envois le contenu de la commande
|
||||||
# envois le contenu de la commande
|
|
||||||
await message.channel.send(f"@{message.author.name}, {command[1]}")
|
await message.channel.send(f"@{message.author.name}, {command[1]}")
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from twitchio.ext.commands import Bot
|
||||||
from utils.core import listCommands
|
from utils.core import listCommands
|
||||||
from utils.db import Database
|
from utils.db import Database
|
||||||
|
|
||||||
|
@ -6,7 +7,7 @@ class CommandesDB(Database):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(r"db/bot.sqlite3")
|
super().__init__(r"db/bot.sqlite3")
|
||||||
|
|
||||||
def creationTable(self):
|
def creationTable(self) -> None:
|
||||||
"""Créer la table qui stocker les commandes."""
|
"""Créer la table qui stocker les commandes."""
|
||||||
requete = """
|
requete = """
|
||||||
CREATE TABLE IF NOT EXISTS commandes (
|
CREATE TABLE IF NOT EXISTS commandes (
|
||||||
|
@ -16,7 +17,7 @@ class CommandesDB(Database):
|
||||||
"""
|
"""
|
||||||
self.requete(requete)
|
self.requete(requete)
|
||||||
|
|
||||||
def ajoutCommande(self, name: str, message: str):
|
def ajoutCommande(self, name: str, message: str) -> None:
|
||||||
"""Ajoute une commande."""
|
"""Ajoute une commande."""
|
||||||
requete = """
|
requete = """
|
||||||
INSERT INTO commandes (
|
INSERT INTO commandes (
|
||||||
|
@ -28,7 +29,7 @@ class CommandesDB(Database):
|
||||||
"""
|
"""
|
||||||
self.requete(requete, [name, message])
|
self.requete(requete, [name, message])
|
||||||
|
|
||||||
def suppressionCommande(self, name: str):
|
def suppressionCommande(self, name: str) -> None:
|
||||||
"""Supprime une commande."""
|
"""Supprime une commande."""
|
||||||
requete = """
|
requete = """
|
||||||
DELETE FROM commandes
|
DELETE FROM commandes
|
||||||
|
@ -36,12 +37,12 @@ class CommandesDB(Database):
|
||||||
"""
|
"""
|
||||||
self.requete(requete, name)
|
self.requete(requete, name)
|
||||||
|
|
||||||
def listeCommande(self):
|
def listeCommande(self) -> list[tuple]:
|
||||||
"""Retourne la liste des commandes."""
|
"""Retourne la liste des commandes."""
|
||||||
return self.affichageResultat(self.requete("SELECT * FROM commandes;"))
|
return self.getResults(self.requete("SELECT * FROM commandes;"))
|
||||||
|
|
||||||
|
|
||||||
def existeCommande(command: str):
|
def existeCommande(command: str) -> tuple[bool, str | None]:
|
||||||
"""Vérifie qu'une commande existe dans la base de donnée."""
|
"""Vérifie qu'une commande existe dans la base de donnée."""
|
||||||
commandes = CommandesDB().listeCommande()
|
commandes = CommandesDB().listeCommande()
|
||||||
for commande in commandes:
|
for commande in commandes:
|
||||||
|
@ -50,7 +51,7 @@ def existeCommande(command: str):
|
||||||
return (False, None)
|
return (False, None)
|
||||||
|
|
||||||
|
|
||||||
def existeTouteCommande(client, commande: str):
|
def existeTouteCommande(client: Bot, commande: str) -> bool:
|
||||||
"""Vérifie qu'une commande existe dans la base de donnée et dans le bot en lui-même."""
|
"""Vérifie qu'une commande existe dans la base de donnée et dans le bot en lui-même."""
|
||||||
commandes = []
|
commandes = []
|
||||||
for command in CommandesDB().listeCommande():
|
for command in CommandesDB().listeCommande():
|
||||||
|
@ -60,6 +61,4 @@ def existeTouteCommande(client, commande: str):
|
||||||
if command.aliases:
|
if command.aliases:
|
||||||
for comm in command.aliases:
|
for comm in command.aliases:
|
||||||
commandes.append(comm)
|
commandes.append(comm)
|
||||||
if commande in commandes:
|
return commande in commandes
|
||||||
return (True,)
|
|
||||||
return (False,)
|
|
||||||
|
|
|
@ -2,9 +2,10 @@ from os import environ
|
||||||
from sys import exit
|
from sys import exit
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
from twitchio.ext.commands import Bot, Command
|
||||||
|
|
||||||
|
|
||||||
def load(variables):
|
def load(variables: list[str]) -> dict:
|
||||||
"""Load env variables"""
|
"""Load env variables"""
|
||||||
keys = {}
|
keys = {}
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
@ -22,7 +23,7 @@ def load(variables):
|
||||||
return keys
|
return keys
|
||||||
|
|
||||||
|
|
||||||
def listCommands(client):
|
def listCommands(client: Bot) -> list[Command]:
|
||||||
cogs = client.cogs.values()
|
cogs = client.cogs.values()
|
||||||
commands = []
|
commands = []
|
||||||
for cog in cogs:
|
for cog in cogs:
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
import sqlite3
|
from sqlite3 import Connection, Cursor, Error, connect
|
||||||
|
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
def __init__(self, urlDatabase: str):
|
_cursor = tuple[Cursor, int | None] | None
|
||||||
connexion = self.createConnection(urlDatabase)
|
|
||||||
|
def __init__(self, url: str):
|
||||||
|
connexion = self.createConnection(url)
|
||||||
if connexion is None:
|
if connexion is None:
|
||||||
raise Exception("Can't connect to database")
|
raise Exception("Can't connect to database")
|
||||||
self.connexion = connexion
|
self.connexion = connexion
|
||||||
|
|
||||||
def createConnection(self, path):
|
def createConnection(self, path: str) -> Connection | None:
|
||||||
"""Connexion à une base de donnée SQLite"""
|
"""Connexion à une base de donnée SQLite"""
|
||||||
if not self.isFileExists(path):
|
if not self._fileExists(path):
|
||||||
open(path, "x")
|
open(path, "x")
|
||||||
connnexion = None
|
connnexion = None
|
||||||
try:
|
try:
|
||||||
connnexion = sqlite3.connect(path)
|
connnexion = connect(path)
|
||||||
except sqlite3.Error as e:
|
except Error as e:
|
||||||
print(e)
|
print(e)
|
||||||
return connnexion
|
return connnexion
|
||||||
|
|
||||||
def isFileExists(self, path):
|
def _fileExists(self, path: str) -> bool:
|
||||||
"""Vérifie qu'un fichier existe"""
|
"""Vérifie qu'un fichier existe"""
|
||||||
try:
|
try:
|
||||||
open(path, "r")
|
open(path, "r")
|
||||||
|
@ -28,8 +30,10 @@ class Database:
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def requete(self, requete, valeurs=None):
|
def requete(
|
||||||
"""Envois une requête vers la base de données"""
|
self, requete: str, valeurs: str | list | tuple | None = None
|
||||||
|
) -> _cursor:
|
||||||
|
"""Envoie une requête vers la base de données"""
|
||||||
try:
|
try:
|
||||||
curseur = self.connexion.cursor()
|
curseur = self.connexion.cursor()
|
||||||
if valeurs:
|
if valeurs:
|
||||||
|
@ -40,10 +44,10 @@ class Database:
|
||||||
curseur.execute(requete)
|
curseur.execute(requete)
|
||||||
self.connexion.commit()
|
self.connexion.commit()
|
||||||
return (curseur, curseur.lastrowid)
|
return (curseur, curseur.lastrowid)
|
||||||
except sqlite3.Error as e:
|
except Error as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
def affichageResultat(self, curseur):
|
def getResults(self, curseur: _cursor) -> list[tuple]:
|
||||||
"""Affiche le résultat d'une requête"""
|
"""Affiche le résultat d'une requête"""
|
||||||
tableau = []
|
tableau = []
|
||||||
if curseur is None:
|
if curseur is None:
|
||||||
|
|
Loading…
Reference in a new issue