Ruff pass for code cleanup
All checks were successful
Build and publish Docker image / docker (push) Successful in 14m40s

This commit is contained in:
Anselme 2026-10-01 15:43:05 +02:00
parent 5f61a45383
commit f15b12af26
4 changed files with 115 additions and 71 deletions

View File

@ -3,7 +3,7 @@ import sqlite3
import random import random
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Tuple from typing import Any, Dict
DB_FILE = "data/database.db" DB_FILE = "data/database.db"
@ -52,6 +52,7 @@ SET nb_clues = nb_clues + 1
DELETE_RIDDLE_QUERY = "DELETE FROM active_riddles 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)
@ -113,7 +114,13 @@ def get_guild_state(guild_id: str) -> Dict[str, Any]:
def rhyme_configure_cooldown_ratio(guild_id: str, cooldown_ratio: float) -> bool: def rhyme_configure_cooldown_ratio(guild_id: str, cooldown_ratio: float) -> bool:
with get_connection() as conn: with get_connection() as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(CONFIGURE_COOLDOWN_RATIO_QUERY, (cooldown_ratio, guild_id,)) cursor.execute(
CONFIGURE_COOLDOWN_RATIO_QUERY,
(
cooldown_ratio,
guild_id,
),
)
conn.commit() conn.commit()
@ -124,25 +131,36 @@ def rhyme_damage_self_control(guild_id: str) -> None:
conn.commit() conn.commit()
def rhyme_reset_cooldown( def rhyme_reset_cooldown(guild_id: str, ratio: float) -> None:
guild_id: str,
ratio: float
) -> None:
with get_connection() as conn: with get_connection() as conn:
# Calculate new cooldown duration # Calculate new cooldown duration
wait_time = random.randint(900, 10800) if bool(random.getrandbits(1)) else random.randint(0, 900) wait_time = (
random.randint(900, 10800)
if bool(random.getrandbits(1))
else random.randint(0, 900)
)
wait_time = 0 if ratio < 0 else int(wait_time * ratio) wait_time = 0 if ratio < 0 else int(wait_time * ratio)
cooldown_until = datetime.now().replace(second=0, microsecond=0) + timedelta(seconds=wait_time) cooldown_until = datetime.now().replace(second=0, microsecond=0) + timedelta(
seconds=wait_time
)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(RESET_COOLDOWN_QUERY, (cooldown_until.isoformat(), guild_id,)) cursor.execute(
RESET_COOLDOWN_QUERY,
(
cooldown_until.isoformat(),
guild_id,
),
)
conn.commit() conn.commit()
def get_active_riddle(channel_id: str) -> Any: 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),)
)
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@ -167,14 +185,20 @@ def save_active_riddle(
) -> None: ) -> None:
with get_connection() as conn: with get_connection() as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(SAVE_RIDDLE_QUERY, (channel_id, riddle_index, nb_clues, message_id, solver_id)) cursor.execute(
SAVE_RIDDLE_QUERY,
(channel_id, riddle_index, nb_clues, message_id, solver_id),
)
conn.commit() conn.commit()
def increment_clue(channel_id: str) -> None: def increment_clue(channel_id: str) -> None:
with get_connection() as conn: with get_connection() as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(INCREMENT_CLUE_QUERY, (channel_id,),) cursor.execute(
INCREMENT_CLUE_QUERY,
(channel_id,),
)
conn.commit() conn.commit()

View File

@ -166,7 +166,7 @@ def get_current_riddle(channel_id):
"nbClues": riddle_data["nb_clues"], "nbClues": riddle_data["nb_clues"],
"riddle": riddles[riddle_data["riddle_index"]].strip(), "riddle": riddles[riddle_data["riddle_index"]].strip(),
"answer": answers[riddle_data["riddle_index"]], "answer": answers[riddle_data["riddle_index"]],
"data": riddle_data "data": riddle_data,
} }
else: else:
return None return None
@ -174,7 +174,7 @@ def get_current_riddle(channel_id):
async def handle_riddle_solving(message, client: discord.Client) -> bool: async def handle_riddle_solving(message, client: discord.Client) -> bool:
current_riddle = get_current_riddle(message.channel.id) current_riddle = get_current_riddle(message.channel.id)
if(not current_riddle): if not current_riddle:
return False return False
answer = current_riddle["answer"] answer = current_riddle["answer"]
riddle_data = current_riddle["data"] riddle_data = current_riddle["data"]
@ -190,9 +190,7 @@ async def handle_riddle_solving(message, client: discord.Client) -> bool:
solver_id=solver_id, solver_id=solver_id,
) )
await message.reply( await message.reply(SUCCESS.format(user=message.author.mention, answer=answer))
SUCCESS.format(user=message.author.mention, answer=answer)
)
try: try:
original_msg = await message.channel.fetch_message( original_msg = await message.channel.fetch_message(
@ -278,7 +276,7 @@ async def new_riddle(interaction: Interaction, index: int) -> None:
riddle_index=index, riddle_index=index,
nb_clues=-1, nb_clues=-1,
message_id=msg.message_id, message_id=msg.message_id,
solver_id=None solver_id=None,
) )
@ -292,23 +290,20 @@ async def update_riddle_message(channel, current_riddle):
def setup_commands(client: discord.Client, tree) -> None: def setup_commands(client: discord.Client, tree) -> None:
@tree.command( @tree.command(name="fouras", description="Demander une énigme au Père Fouras")
name="fouras",
description="Demander une énigme au Père Fouras"
)
async def fouras( async def fouras(
interaction: discord.Interaction, interaction: discord.Interaction,
): ):
if len(riddles) == 0: if len(riddles) == 0:
await interaction.response.send_message("Désolé, mais j'ai oublié mes énigmes", ephemeral=True) await interaction.response.send_message(
"Désolé, mais j'ai oublié mes énigmes", ephemeral=True
)
else: else:
index = random.randint(0, len(riddles) - 1) index = random.randint(0, len(riddles) - 1)
await new_riddle(interaction, index) await new_riddle(interaction, index)
@tree.command( @tree.command(
name="requete", name="requete", description="Demander une énigme spécifique au Père Fouras"
description="Demander une énigme spécifique au Père Fouras"
) )
@app_commands.describe(index="Numéro de l'énigme") @app_commands.describe(index="Numéro de l'énigme")
async def requete( async def requete(
@ -317,21 +312,24 @@ def setup_commands(client: discord.Client, tree) -> None:
): ):
index = index - 1 index = index - 1
if not (0 <= index < len(riddles)): if not (0 <= index < len(riddles)):
await interaction.response.send_message(INVALID_ID.format(len=len(riddles)+1), ephemeral=True) await interaction.response.send_message(
INVALID_ID.format(len=len(riddles) + 1), ephemeral=True
)
return return
await new_riddle(interaction, index) await new_riddle(interaction, index)
@tree.command( @tree.command(
name="repete", name="repete",
description="Demander au Père Fouras de répéter l'énigme en cours" description="Demander au Père Fouras de répéter l'énigme en cours",
) )
async def repete( async def repete(
interaction: discord.Interaction, interaction: discord.Interaction,
): ):
current_riddle = get_current_riddle(interaction.channel.id) current_riddle = get_current_riddle(interaction.channel.id)
if(not current_riddle): if not current_riddle:
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"]
msg = await interaction.response.send_message( msg = await interaction.response.send_message(
@ -345,17 +343,17 @@ def setup_commands(client: discord.Client, tree) -> None:
solver_id=riddle_data["solver_id"], solver_id=riddle_data["solver_id"],
) )
@tree.command( @tree.command(
name="indice", name="indice", description="Demander un indice pour l'énigme en cours"
description="Demander un indice pour l'énigme en cours"
) )
async def indice( async def indice(
interaction: discord.Interaction, interaction: discord.Interaction,
): ):
current_riddle = get_current_riddle(interaction.channel.id) current_riddle = get_current_riddle(interaction.channel.id)
if(not current_riddle): if not current_riddle:
await interaction.response.send_message("Aucune énigme en cours", ephemeral=True) await interaction.response.send_message(
"Aucune énigme en cours", ephemeral=True
)
return return
answer = current_riddle["answer"] answer = current_riddle["answer"]
riddle_data = current_riddle["data"] riddle_data = current_riddle["data"]
@ -366,7 +364,7 @@ def setup_commands(client: discord.Client, tree) -> None:
await interaction.response.send_message( await interaction.response.send_message(
"Perdu ! La réponse était : `{0}`".format(answer) "Perdu ! La réponse était : `{0}`".format(answer)
) )
if(not await update_riddle_message(interaction.channel, current_riddle)): if not await update_riddle_message(interaction.channel, current_riddle):
return return
await finish_riddle(interaction.channel, client) await finish_riddle(interaction.channel, client)
else: else:
@ -377,6 +375,8 @@ def setup_commands(client: discord.Client, tree) -> None:
message_id=riddle_data["message_id"], message_id=riddle_data["message_id"],
solver_id=riddle_data["solver_id"], solver_id=riddle_data["solver_id"],
) )
if(not await update_riddle_message(interaction.channel, current_riddle)): if not await update_riddle_message(interaction.channel, current_riddle):
return return
await interaction.response.send_message("Nouvel indice : `{0}`".format(clue_string(answer, nb_clues))) await interaction.response.send_message(
"Nouvel indice : `{0}`".format(clue_string(answer, nb_clues))
)

View File

@ -76,7 +76,12 @@ async def handle_rhyme_logic(message, client) -> bool:
message_content = message.content.lower() message_content = message.content.lower()
last_word = get_last_word(message_content) last_word = get_last_word(message_content)
if not message.author.bot and message.author.id != client.user.id and message.guild and last_word: if (
not message.author.bot
and message.author.id != client.user.id
and message.guild
and last_word
):
rhyme = find_rhyme(last_word) rhyme = find_rhyme(last_word)
guild_id = str(message.guild.id) guild_id = str(message.guild.id)
@ -110,23 +115,27 @@ async def handle_message(message, client: discord.Client) -> bool:
return await handle_rhyme_logic(message, client) return await handle_rhyme_logic(message, client)
def setup_rhymes_commands(client: discord.Client, tree: discord.app_commands.CommandTree) -> None: def setup_rhymes_commands(
client: discord.Client, tree: discord.app_commands.CommandTree
) -> None:
@tree.command( @tree.command(
name="config", name="config",
description="Permet de configurer à quel point le Père Fouras est relou" description="Permet de configurer à quel point le Père Fouras est relou",
) )
@app_commands.default_permissions(manage_guild=True) @app_commands.default_permissions(manage_guild=True)
@app_commands.checks.has_permissions(manage_guild=True) @app_commands.checks.has_permissions(manage_guild=True)
@app_commands.describe(ratio="ratio de cooldown (0 = )") @app_commands.describe(ratio="ratio de cooldown (0 = )")
async def config( async def config(interaction: discord.Interaction, ratio: float):
interaction: discord.Interaction,
ratio: float
):
guild_id: str = str(interaction.guild_id) guild_id: str = str(interaction.guild_id)
guild_state = database.get_guild_state(guild_id) guild_state = database.get_guild_state(guild_id)
database.rhyme_configure_cooldown_ratio(guild_id, ratio) database.rhyme_configure_cooldown_ratio(guild_id, ratio)
msg = f"Le ratio de cooldown passe de {guild_state['cooldown_ratio']:.2f} à {ratio:.2f} pour le serveur {interaction.guild.name}" msg = f"Le ratio de cooldown passe de {guild_state['cooldown_ratio']:.2f} à {ratio:.2f} pour le serveur {interaction.guild.name}"
if ratio < 0: if ratio < 0:
await interaction.response.send_message(f"{msg}\nLes \"poil au\" sont désormais désactivés.", ephemeral=True) await interaction.response.send_message(
f'{msg}\nLes "poil au" sont désormais désactivés.', ephemeral=True
)
else: else:
await interaction.response.send_message(f"{msg}\nLes \"poil au\" ont désormais un cooldown entre 0 et {int(180*ratio)} minutes.", ephemeral=True) await interaction.response.send_message(
f'{msg}\nLes "poil au" ont désormais un cooldown entre 0 et {int(180 * ratio)} minutes.',
ephemeral=True,
)

View File

@ -1,47 +1,58 @@
```python
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import json import json
riddles = [] riddles = []
def scrape_year_data(scrap_year): def scrape_year_data(scrap_year):
base_url = 'https://www.fan-fortboyard.fr/pages/fanzone/enigmes-du-pere-fouras/' base_url = "https://www.fan-fortboyard.fr/pages/fanzone/enigmes-du-pere-fouras/"
if(scrap_year > 2019): if scrap_year > 2019:
url = f'{base_url}enigmes-{scrap_year}.html' # Replace with the actual URL pattern url = f"{base_url}enigmes-{scrap_year}.html" # Replace with the actual URL pattern
else: else:
url = f'{base_url}{scrap_year}.html' # Replace with the actual URL pattern url = f"{base_url}{scrap_year}.html" # Replace with the actual URL pattern
response = requests.get(url) response = requests.get(url)
if response.status_code == 200: if response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser') soup = BeautifulSoup(response.text, "html.parser")
paragraphs = soup.find_all('p') paragraphs = soup.find_all("p")
for paragraph in paragraphs: for paragraph in paragraphs:
span = paragraph.find('span') span = paragraph.find("span")
if span and span.find('strong'): if span and span.find("strong"):
strong_tag = span.find('strong') strong_tag = span.find("strong")
if strong_tag and strong_tag.text.strip().isdigit(): if strong_tag and strong_tag.text.strip().isdigit():
riddle_count = strong_tag.text.strip() riddle_count = strong_tag.text.strip()
answer_span = paragraph.find_all('span', style=True) answer_span = paragraph.find_all("span", style=True)
if answer_span: if answer_span:
answer_text = answer_span[-1].get_text(strip=True) answer_text = answer_span[-1].get_text(strip=True)
riddle_count = strong_tag.text.strip() riddle_count = strong_tag.text.strip()
riddle_text = paragraph.decode_contents() riddle_text = paragraph.decode_contents()
riddle_text = riddle_text.replace('<br/>', '\n').replace('<br>', '\n') riddle_text = riddle_text.replace("<br/>", "\n").replace(
riddle_text = BeautifulSoup(riddle_text, 'html.parser').get_text(strip=True) "<br>", "\n"
riddle_text = riddle_text.split(')', 1)[-1].strip() )
riddle_text = BeautifulSoup(
riddle_text, "html.parser"
).get_text(strip=True)
riddle_text = riddle_text.split(")", 1)[-1].strip()
if "RÉPONSE" in riddle_text: if "RÉPONSE" in riddle_text:
riddle_text = riddle_text.split("RÉPONSE", 1)[0].strip() riddle_text = riddle_text.split("RÉPONSE", 1)[0].strip()
riddles.append({'riddle': riddle_text, 'answer': answer_text, 'count': riddle_count, 'year': scrap_year}) riddles.append(
{
"riddle": riddle_text,
"answer": answer_text,
"count": riddle_count,
"year": scrap_year,
}
)
else: else:
print(f'No answer found : {scrap_year}-{riddle_count}') print(f"No answer found : {scrap_year}-{riddle_count}")
else: else:
print(f'Failed to retrieve data for year {year}: {response.status_code}') print(f"Failed to retrieve data for year {year}: {response.status_code}")
for year in range(2007, 2023): for year in range(2007, 2023):
scrape_year_data(year) scrape_year_data(year)
with open('riddles.json', 'w', encoding='utf-8') as json_file: with open("riddles.json", "w", encoding="utf-8") as json_file:
json.dump(riddles, json_file, indent=4, ensure_ascii=False) json.dump(riddles, json_file, indent=4, ensure_ascii=False)
```