code cleanup, removed useless comments

This commit is contained in:
Anselme 2026-08-06 16:20:08 +02:00
parent 4e966eb821
commit 51496646f4
5 changed files with 34 additions and 93 deletions

View File

@ -28,6 +28,7 @@ https://discord.com/api/oauth2/authorize?client_id=1110208055171367014&permissio
python -m venv "venv" python -m venv "venv"
source venv/bin/activate source venv/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
python main.py
``` ```
## Setup discord ## Setup discord

View File

@ -7,7 +7,6 @@ from typing import Any, Dict, Tuple
DB_FILE = "data/database.db" DB_FILE = "data/database.db"
# guild-state queries
CREATE_GUILD_STATE_QUERY = """ CREATE_GUILD_STATE_QUERY = """
INSERT INTO guild_state (guild_id, cooldown_until, cooldown_ratio, self_control, last_updated) INSERT INTO guild_state (guild_id, cooldown_until, cooldown_ratio, self_control, last_updated)
VALUES (?, datetime('now'), 1.0, 1.0, datetime('now')) VALUES (?, datetime('now'), 1.0, 1.0, datetime('now'))
@ -39,6 +38,20 @@ SET cooldown_until = ?,
WHERE guild_id = ? WHERE guild_id = ?
""" """
SAVE_RIDDLE_QUERY = """
INSERT OR REPLACE INTO active_riddles
(channel_id, riddle_index, nb_clues, message_id, solver_id, updated_at)
VALUES (?, ?, ?, ?, ?, datetime('now'))
"""
INCREMENT_CLUE_QUERY = """
UPDATE active_riddles
SET nb_clues = nb_clues + 1
WHERE channel_id = ?
"""
DELETE_RIDDLE_QUERY = "DELETE FROM active_riddles WHERE channel_id = ?"
def ensure_db() -> None: def ensure_db() -> None:
"""Initialize SQLite database and create tables if needed.""" """Initialize SQLite database and create tables if needed."""
Path(DB_FILE).parent.mkdir(parents=True, exist_ok=True) Path(DB_FILE).parent.mkdir(parents=True, exist_ok=True)
@ -69,7 +82,6 @@ def ensure_db() -> None:
def get_connection() -> sqlite3.Connection: def get_connection() -> sqlite3.Connection:
"""Return SQLite connection with row factory for named column access."""
conn = sqlite3.connect(DB_FILE) conn = sqlite3.connect(DB_FILE)
conn.row_factory = sqlite3.Row conn.row_factory = sqlite3.Row
return conn return conn
@ -127,7 +139,7 @@ def rhyme_reset_cooldown(
conn.commit() conn.commit()
def get_active_riddle(channel_id: str): def get_active_riddle(channel_id: str) -> Any:
with get_connection() as conn: with get_connection() as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM active_riddles WHERE channel_id = ?", (str(channel_id),)) cursor.execute("SELECT * FROM active_riddles WHERE channel_id = ?", (str(channel_id),))
@ -151,47 +163,23 @@ def save_active_riddle(
riddle_index: int, riddle_index: int,
nb_clues: int, nb_clues: int,
message_id: int, message_id: int,
solver_id: str = None, solver_id: str = "",
): ) -> None:
with get_connection() as conn: with get_connection() as conn:
cursor = conn.cursor() cursor = conn.cursor()
# Si solver_id existe, on considère que c'est résolu et on garde l'entrée pour historique cursor.execute(SAVE_RIDDLE_QUERY, (channel_id, riddle_index, nb_clues, message_id, solver_id))
# Sinon on met à jour l'énigme en cours
cursor.execute(
"""
INSERT OR REPLACE INTO active_riddles
(channel_id, riddle_index, nb_clues, message_id, solver_id, updated_at)
VALUES (?, ?, ?, ?, ?, datetime('now'))
""",
(str(channel_id), riddle_index, nb_clues, message_id, solver_id)
)
conn.commit() conn.commit()
def remove_active_riddle(channel_id: str) -> bool: def increment_clue(channel_id: str) -> None:
"""Supprimer une énigme active du suivi."""
with get_connection() as conn: with get_connection() as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("DELETE FROM active_riddles WHERE channel_id = ?", (str(channel_id),)) cursor.execute(INCREMENT_CLUE_QUERY, (channel_id,),)
conn.commit() conn.commit()
return cursor.rowcount > 0
def get_all_active_riddles(): def remove_active_riddle(channel_id: str) -> None:
"""Récupérer toutes les énigmes actives (pour debug)."""
with get_connection() as conn: with get_connection() as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM active_riddles") cursor.execute(DELETE_RIDDLE_QUERY, (str(channel_id),))
return [ conn.commit()
{
"channel_id": row["channel_id"],
"riddle_index": row["riddle_index"],
"nb_clues": row["nb_clues"],
"message_id": row["message_id"],
"solver_id": row["solver_id"],
"created_at": row["created_at"],
"updated_at": row["updated_at"],
}
for row in cursor.fetchall()
]

View File

@ -63,7 +63,6 @@ def load_riddles() -> list:
def new_riddle_state(index: int) -> Dict[str, Any]: def new_riddle_state(index: int) -> Dict[str, Any]:
"""Créer un nouvel état d'énigme sans sauvegarde DB."""
return { return {
"index": index, "index": index,
"nbClues": -1, "nbClues": -1,
@ -73,16 +72,10 @@ def new_riddle_state(index: int) -> Dict[str, Any]:
async def finish_riddle(channel, client: discord.Client) -> None: async def finish_riddle(channel, client: discord.Client) -> None:
"""Supprimer l'énigme active de la DB et supprimer le suivi en mémoire.""" database.remove_active_riddle(str(channel.id))
removed = database.remove_active_riddle(str(channel.id))
# Optionnel : si vous gardez un cache en mémoire pour performance, supprimez-le ici
# if hasattr(client, '_cache_ongoing_riddles'):
# client._cache_ongoing_riddles.pop(channel.id, None)
def clue_string(answer: str, nb_clues: int) -> str: def clue_string(answer: str, nb_clues: int) -> str:
"""Generate clue string with revealed letters."""
final_string = "_" final_string = "_"
for _ in range(len(answer) - 1): for _ in range(len(answer) - 1):
final_string += " _" final_string += " _"
@ -109,7 +102,6 @@ def clue_string(answer: str, nb_clues: int) -> str:
def format_riddle_message( def format_riddle_message(
current_riddle: Dict[str, Any], solved: bool = False, solver_mention: str = "" current_riddle: Dict[str, Any], solved: bool = False, solver_mention: str = ""
) -> str: ) -> str:
"""Format riddle message for display."""
nb_clues = current_riddle.get("nbClues", -1) nb_clues = current_riddle.get("nbClues", -1)
answer = current_riddle.get("answer", "") answer = current_riddle.get("answer", "")
@ -151,9 +143,6 @@ async def get_channel_name(channel, client: discord.Client) -> str:
async def handle_debug_commands(message, client: discord.Client) -> bool: async def handle_debug_commands(message, client: discord.Client) -> bool:
"""Handle debug commands (debug, save, load, broadcast). Returns True if handled."""
message_content = message.content.lower()
broadcast_match = re.match(r"^broadcast\s+(\d+) (.*)", message.content) broadcast_match = re.match(r"^broadcast\s+(\d+) (.*)", message.content)
if broadcast_match and message.author.id == MAINTAINER_ID: if broadcast_match and message.author.id == MAINTAINER_ID:
index = int(broadcast_match.group(1)) index = int(broadcast_match.group(1))
@ -177,7 +166,6 @@ def get_current_riddle(channel_id):
if not riddle_data: if not riddle_data:
return None return None
# Reconstruire l'état de l'énigme
if 0 <= riddle_data["riddle_index"] < len(riddles): if 0 <= riddle_data["riddle_index"] < len(riddles):
return { return {
"index": riddle_data["riddle_index"], "index": riddle_data["riddle_index"],
@ -197,11 +185,9 @@ async def handle_riddle_solving(message, client: discord.Client) -> bool:
answer = current_riddle["answer"] answer = current_riddle["answer"]
riddle_data = current_riddle["data"] riddle_data = current_riddle["data"]
# Check if message contains the answer
if unidecode(answer.lower()) in unidecode(message.content.lower()): if unidecode(answer.lower()) in unidecode(message.content.lower()):
solver_id = str(message.author.id) solver_id = str(message.author.id)
# Mise à jour DB : marque comme résolue avec le solver
database.save_active_riddle( database.save_active_riddle(
channel_id=str(message.channel.id), channel_id=str(message.channel.id),
riddle_index=riddle_data["riddle_index"], riddle_index=riddle_data["riddle_index"],
@ -214,7 +200,6 @@ async def handle_riddle_solving(message, client: discord.Client) -> bool:
SUCCESS.format(user=message.author.mention, answer=answer) SUCCESS.format(user=message.author.mention, answer=answer)
) )
# Récupération du message original pour édition
try: try:
original_msg = await message.channel.fetch_message( original_msg = await message.channel.fetch_message(
riddle_data["message_id"] riddle_data["message_id"]
@ -227,7 +212,6 @@ async def handle_riddle_solving(message, client: discord.Client) -> bool:
except discord.errors.NotFound: except discord.errors.NotFound:
pass pass
# Suppression du suivi actif
await finish_riddle(message.channel, client) await finish_riddle(message.channel, client)
return True return True
@ -235,27 +219,24 @@ async def handle_riddle_solving(message, client: discord.Client) -> bool:
async def handle_bug_report(message, client: discord.Client) -> bool: async def handle_bug_report(message, client: discord.Client) -> bool:
"""Handle bug report command. Returns True if bug report was sent."""
if not message.content.lower().startswith("bug"): if not message.content.lower().startswith("bug"):
return False return False
author_user = await client.fetch_user(MAINTAINER_ID) author_user = await client.fetch_user(MAINTAINER_ID)
channel_name = await get_channel_name(message.channel, client) channel_name = await get_channel_name(message.channel, client)
# Load message history
messages = [ messages = [
{ {
"id": msg.id, "id": msg.id,
"content": msg.content, "content": msg.content,
"date": msg.created_at.strftime("%d/%m %H:%M:%S"), "date": msg.created_at.strftime("%d/%m %H:%M:%S"),
} }
async for msg in message.channel.history(limit=10) async for msg in message.channel.history(limit=6)
] ]
messages_json = json.dumps(messages, ensure_ascii=False) messages_json = json.dumps(messages, ensure_ascii=False)
# Récupération de l'état DB au lieu de la variable globale active_riddle = database.get_active_riddle(message.channel.id)
active_riddles = database.get_all_active_riddles() state_json = json.dumps(active_riddle, ensure_ascii=False, indent=2)
state_json = json.dumps(active_riddles, ensure_ascii=False, indent=2)
await author_user.send( await author_user.send(
BUG_REPORT.format( BUG_REPORT.format(
@ -265,7 +246,7 @@ async def handle_bug_report(message, client: discord.Client) -> bool:
channel_id=message.channel.id, channel_id=message.channel.id,
message=message.content, message=message.content,
history=messages_json, history=messages_json,
# state=state_json, state=state_json,
) )
) )
await message.channel.send( await message.channel.send(
@ -275,18 +256,14 @@ async def handle_bug_report(message, client: discord.Client) -> bool:
async def handle_message(message, client: discord.Client) -> bool: async def handle_message(message, client: discord.Client) -> bool:
"""Main entry point for message handling."""
database.ensure_db() database.ensure_db()
# Handle debug/admin commands first
if await handle_debug_commands(message, client): if await handle_debug_commands(message, client):
return True return True
# Handle bug reports
if await handle_bug_report(message, client): if await handle_bug_report(message, client):
return True return True
# Handle riddle solving
if await handle_riddle_solving(message, client): if await handle_riddle_solving(message, client):
return True return True
@ -362,13 +339,14 @@ def setup_commands(client: discord.Client, tree) -> None:
await interaction.response.send_message("Aucune énigme en cours", ephemeral=True) await interaction.response.send_message("Aucune énigme en cours", ephemeral=True)
return return
riddle_data = current_riddle["data"] riddle_data = current_riddle["data"]
await interaction.response.send_message("Ok, je vais répéter l'énigme en cours", ephemeral=True) msg = await interaction.response.send_message(
msg = await interaction.channel.send(format_riddle_message(current_riddle)) format_riddle_message(current_riddle)
)
database.save_active_riddle( database.save_active_riddle(
channel_id=str(interaction.channel.id), channel_id=str(interaction.channel.id),
riddle_index=riddle_data["riddle_index"], riddle_index=riddle_data["riddle_index"],
nb_clues=current_riddle["nbClues"], nb_clues=current_riddle["nbClues"],
message_id=msg.id, message_id=msg.message_id,
solver_id=riddle_data["solver_id"], solver_id=riddle_data["solver_id"],
) )
@ -408,7 +386,6 @@ def setup_commands(client: discord.Client, tree) -> None:
return return
await finish_riddle(interaction.channel, client) await finish_riddle(interaction.channel, client)
else: else:
# Update nb clues in DB
database.save_active_riddle( database.save_active_riddle(
channel_id=str(interaction.channel.id), channel_id=str(interaction.channel.id),
riddle_index=riddle_data["riddle_index"], riddle_index=riddle_data["riddle_index"],

15
main.py
View File

@ -1,14 +1,11 @@
# main.py
import os import os
import discord import discord
from discord import app_commands from discord import app_commands
from dotenv import load_dotenv from dotenv import load_dotenv
# Load environment variables
load_dotenv() load_dotenv()
# Discord client setup
intents = discord.Intents.default() intents = discord.Intents.default()
intents.members = True intents.members = True
intents.presences = True intents.presences = True
@ -23,26 +20,19 @@ tree = app_commands.CommandTree(client)
@client.event @client.event
async def on_ready(): async def on_ready():
global client, tree global client, tree
"""Initialize bot state and sync commands."""
# Import initialization functions
from fouras import load_riddles, setup_commands from fouras import load_riddles, setup_commands
from rhymes import ensure_log_file, load_rhymes, setup_rhymes_commands from rhymes import ensure_log_file, load_rhymes, setup_rhymes_commands
# Ensure directories exist
ensure_log_file() ensure_log_file()
# Load riddles and answers
load_riddles() load_riddles()
# register fouras commands
setup_commands(client, tree) setup_commands(client, tree)
setup_rhymes_commands(client, tree) setup_rhymes_commands(client, tree)
# Load rhymes
success, msg = load_rhymes() success, msg = load_rhymes()
print(msg) print(msg)
# Sync commands
async for guild in client.fetch_guilds(): async for guild in client.fetch_guilds():
tree.copy_global_to(guild=guild) tree.copy_global_to(guild=guild)
await tree.sync(guild=guild) await tree.sync(guild=guild)
@ -53,23 +43,18 @@ async def on_ready():
@client.event @client.event
async def on_message(message): async def on_message(message):
global client global client
"""Handle incoming messages."""
# Ignore bot's own messages
if message.author == client.user: if message.author == client.user:
return return
# Handle fouras module
from fouras import handle_message as handle_fouras from fouras import handle_message as handle_fouras
await handle_fouras(message, client) await handle_fouras(message, client)
# Handle rhymes module
from rhymes import handle_message as handle_rhymes from rhymes import handle_message as handle_rhymes
await handle_rhymes(message, client) await handle_rhymes(message, client)
# Run the client
if __name__ == "__main__": if __name__ == "__main__":
token = os.getenv("DISCORD_TOKEN") token = os.getenv("DISCORD_TOKEN")
if not token: if not token:

View File

@ -16,7 +16,6 @@ loaded_rhymes = {}
def ensure_log_file() -> None: def ensure_log_file() -> None:
"""Create CSV log file if it doesn't exist."""
Path(RHYME_LOG_FILE).parent.mkdir(parents=True, exist_ok=True) Path(RHYME_LOG_FILE).parent.mkdir(parents=True, exist_ok=True)
if not Path(RHYME_LOG_FILE).exists(): if not Path(RHYME_LOG_FILE).exists():
@ -26,7 +25,6 @@ def ensure_log_file() -> None:
def load_rhymes() -> Tuple[bool, str]: def load_rhymes() -> Tuple[bool, str]:
global loaded_rhymes global loaded_rhymes
"""Load rhymes from JSON file. Returns (success, message)."""
try: try:
with open(RHYMES_FILE, "r", encoding="utf-8") as f: with open(RHYMES_FILE, "r", encoding="utf-8") as f:
loaded_rhymes = json.load(f) loaded_rhymes = json.load(f)
@ -38,7 +36,6 @@ def load_rhymes() -> Tuple[bool, str]:
def log_rhyme(last_word: str, rhyme_triggered: str) -> None: def log_rhyme(last_word: str, rhyme_triggered: str) -> None:
"""Log rhyme trigger to CSV file."""
timestamp = datetime.now().isoformat() timestamp = datetime.now().isoformat()
with open(RHYME_LOG_FILE, "a", encoding="utf-8") as f: with open(RHYME_LOG_FILE, "a", encoding="utf-8") as f:
@ -47,7 +44,6 @@ def log_rhyme(last_word: str, rhyme_triggered: str) -> None:
def get_last_word(text: str) -> str: def get_last_word(text: str) -> str:
"""Extract last alphabetic word from text."""
truncated = text truncated = text
while True: while True:
if len(truncated) < 2 or truncated[-1].isnumeric(): if len(truncated) < 2 or truncated[-1].isnumeric():
@ -61,7 +57,7 @@ def get_last_word(text: str) -> str:
def find_rhyme(word: str) -> str: def find_rhyme(word: str) -> str:
global loaded_rhymes global loaded_rhymes
"""Find matching rhyme for given word."""
for rhyme in loaded_rhymes: for rhyme in loaded_rhymes:
if word in rhyme["blacklist"]: if word in rhyme["blacklist"]:
return "" return ""
@ -77,7 +73,6 @@ async def get_guild_name(guildId, client) -> str:
async def handle_rhyme_logic(message, client) -> bool: async def handle_rhyme_logic(message, client) -> bool:
"""Main rhyme detection logic. Returns True if rhyme was triggered."""
message_content = message.content.lower() message_content = message.content.lower()
last_word = get_last_word(message_content) last_word = get_last_word(message_content)
@ -90,14 +85,12 @@ async def handle_rhyme_logic(message, client) -> bool:
cooldown_ratio = guild_state["cooldown_ratio"] cooldown_ratio = guild_state["cooldown_ratio"]
if cooldown_ratio >= 0: if cooldown_ratio >= 0:
# Check cooldown
cooldown_dt = datetime.fromisoformat(guild_state["cooldown_until"]) cooldown_dt = datetime.fromisoformat(guild_state["cooldown_until"])
now_dt = datetime.now() now_dt = datetime.now()
if now_dt >= cooldown_dt: if now_dt >= cooldown_dt:
self_control = guild_state["self_control"] self_control = guild_state["self_control"]
# Probability check
if random.random() < self_control: if random.random() < self_control:
database.rhyme_damage_self_control(guild_id) database.rhyme_damage_self_control(guild_id)
return False return False
@ -111,12 +104,9 @@ async def handle_rhyme_logic(message, client) -> bool:
async def handle_message(message, client) -> bool: async def handle_message(message, client) -> bool:
"""Main entry point for message handling."""
# Initialize database and log file on first run
database.ensure_db() database.ensure_db()
ensure_log_file() ensure_log_file()
# Process rhyme logic
return await handle_rhyme_logic(message, client) return await handle_rhyme_logic(message, client)