Compare commits
No commits in common. "f15b12af2665a0de484a4181ee66754e0abcedbf" and "d955a7a80115978513a45f39bfe0a660e9ad63f2" have entirely different histories.
f15b12af26
...
d955a7a801
@ -1,33 +0,0 @@
|
|||||||
name: Build and publish Docker image
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
docker:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Derive registry host and image name
|
|
||||||
id: registry
|
|
||||||
run: |
|
|
||||||
host="$(printf '%s' "${{ gitea.server_url }}" | sed -E 's#^[a-zA-Z][a-zA-Z0-9+.-]*://##; s#/.*$##')"
|
|
||||||
image="$(printf '%s' "${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]')"
|
|
||||||
echo "host=${host}" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "image=${image}" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Log in to Gitea Container Registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: ${{ steps.registry.outputs.host }}
|
|
||||||
username: ${{ gitea.repository_owner }}
|
|
||||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and push image
|
|
||||||
run: |
|
|
||||||
docker build -t "${{ steps.registry.outputs.host }}/${{ steps.registry.outputs.image }}:latest" .
|
|
||||||
docker push "${{ steps.registry.outputs.host }}/${{ steps.registry.outputs.image }}:latest"
|
|
||||||
31
Dockerfile
31
Dockerfile
@ -4,22 +4,29 @@ FROM python:3.9-slim
|
|||||||
# Set the working directory
|
# Set the working directory
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install Python dependencies
|
# Install git and clean up
|
||||||
COPY requirements.txt .
|
RUN apt-get update -q && \
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
apt-get install -y git && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Copy application code
|
# Create data directory with proper permissions
|
||||||
COPY main.py fouras.py rhymes.py database.py ./
|
|
||||||
COPY resources/ ./resources/
|
|
||||||
|
|
||||||
# Create data directory for persistent state
|
|
||||||
RUN mkdir -p /app/data && chmod 755 /app/data
|
RUN mkdir -p /app/data && chmod 755 /app/data
|
||||||
|
|
||||||
# Ensure Python output is not buffered (useful for logs)
|
# Set safe directory
|
||||||
ENV PYTHONUNBUFFERED=1
|
RUN git config --global --add safe.directory '*'
|
||||||
|
|
||||||
|
# Clone the repository
|
||||||
|
RUN git init /app && git remote add origin https://git.epicsparrow.com/Anselme/perefouras.git && git fetch --depth 1 origin master && git reset --hard FETCH_HEAD
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# give exec permissions to main
|
||||||
|
RUN chmod +x main.py
|
||||||
|
|
||||||
# Set data directory as volume mount point
|
# Set data directory as volume mount point
|
||||||
VOLUME /app/data
|
VOLUME /app/data
|
||||||
|
|
||||||
# Run the bot
|
# Command to update the repo and run the script
|
||||||
CMD ["python", "main.py"]
|
CMD ["sh", "-c", "cd /app && git fetch --depth 1 origin master && git reset --hard FETCH_HEAD && python main.py"]
|
||||||
52
database.py
52
database.py
@ -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
|
from typing import Any, Dict, Tuple
|
||||||
|
|
||||||
DB_FILE = "data/database.db"
|
DB_FILE = "data/database.db"
|
||||||
|
|
||||||
@ -52,7 +52,6 @@ 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)
|
||||||
@ -91,14 +90,14 @@ def get_connection() -> sqlite3.Connection:
|
|||||||
def get_guild_state(guild_id: str) -> Dict[str, Any]:
|
def get_guild_state(guild_id: str) -> Dict[str, Any]:
|
||||||
with get_connection() as conn:
|
with get_connection() as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(GET_GUILD_STATE_QUERY, (guild_id,))
|
cursor.execute(GET_GUILD_STATE_QUERY,(guild_id,))
|
||||||
row = cursor.fetchone()
|
row = cursor.fetchone()
|
||||||
|
|
||||||
if not row:
|
if not row:
|
||||||
cursor.execute(CREATE_GUILD_STATE_QUERY, (guild_id,))
|
cursor.execute(CREATE_GUILD_STATE_QUERY, (guild_id,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
cursor.execute(GET_GUILD_STATE_QUERY, (guild_id,))
|
cursor.execute(GET_GUILD_STATE_QUERY,(guild_id,))
|
||||||
row = cursor.fetchone()
|
row = cursor.fetchone()
|
||||||
|
|
||||||
if row:
|
if row:
|
||||||
@ -114,13 +113,7 @@ 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(
|
cursor.execute(CONFIGURE_COOLDOWN_RATIO_QUERY, (cooldown_ratio, guild_id,))
|
||||||
CONFIGURE_COOLDOWN_RATIO_QUERY,
|
|
||||||
(
|
|
||||||
cooldown_ratio,
|
|
||||||
guild_id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
@ -131,36 +124,25 @@ def rhyme_damage_self_control(guild_id: str) -> None:
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
def rhyme_reset_cooldown(guild_id: str, ratio: float) -> None:
|
def rhyme_reset_cooldown(
|
||||||
|
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 = (
|
wait_time = random.randint(900, 10800) if bool(random.getrandbits(1)) else random.randint(0, 900)
|
||||||
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(
|
cooldown_until = datetime.now().replace(second=0, microsecond=0) + timedelta(seconds=wait_time)
|
||||||
seconds=wait_time
|
|
||||||
)
|
|
||||||
|
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute(RESET_COOLDOWN_QUERY, (cooldown_until.isoformat(), guild_id,))
|
||||||
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(
|
cursor.execute("SELECT * FROM active_riddles WHERE channel_id = ?", (str(channel_id),))
|
||||||
"SELECT * FROM active_riddles WHERE channel_id = ?", (str(channel_id),)
|
|
||||||
)
|
|
||||||
row = cursor.fetchone()
|
row = cursor.fetchone()
|
||||||
|
|
||||||
if row:
|
if row:
|
||||||
@ -185,20 +167,14 @@ def save_active_riddle(
|
|||||||
) -> None:
|
) -> None:
|
||||||
with get_connection() as conn:
|
with get_connection() as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute(SAVE_RIDDLE_QUERY, (channel_id, riddle_index, nb_clues, message_id, solver_id))
|
||||||
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(
|
cursor.execute(INCREMENT_CLUE_QUERY, (channel_id,),)
|
||||||
INCREMENT_CLUE_QUERY,
|
|
||||||
(channel_id,),
|
|
||||||
)
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
services:
|
services:
|
||||||
perefouras:
|
perefouras:
|
||||||
image: git.epicsparrow.com/anselme/perefouras:latest
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
environment:
|
environment:
|
||||||
- DISCORD_TOKEN=${FOURAS_DISCORD_TOKEN}
|
- DISCORD_TOKEN=${FOURAS_DISCORD_TOKEN}
|
||||||
- MAINTAINER_ID=${FOURAS_MAINTAINER_ID:-151626081458192384}
|
- MAINTAINER_ID=${FOURAS_MAINTAINER_ID:-151626081458192384}
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- ${FOURAS_DATA_DIR}:/app/data
|
- ${FOURAS_DATA_DIR}:/app/data
|
||||||
54
fouras.py
54
fouras.py
@ -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,7 +190,9 @@ async def handle_riddle_solving(message, client: discord.Client) -> bool:
|
|||||||
solver_id=solver_id,
|
solver_id=solver_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
await message.reply(SUCCESS.format(user=message.author.mention, answer=answer))
|
await message.reply(
|
||||||
|
SUCCESS.format(user=message.author.mention, answer=answer)
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
original_msg = await message.channel.fetch_message(
|
original_msg = await message.channel.fetch_message(
|
||||||
@ -276,7 +278,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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -290,20 +292,23 @@ 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(name="fouras", description="Demander une énigme au Père Fouras")
|
@tree.command(
|
||||||
|
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(
|
await interaction.response.send_message("Désolé, mais j'ai oublié mes énigmes", ephemeral=True)
|
||||||
"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", description="Demander une énigme spécifique au Père Fouras"
|
name="requete",
|
||||||
|
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(
|
||||||
@ -312,24 +317,21 @@ 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(
|
await interaction.response.send_message(INVALID_ID.format(len=len(riddles)+1), ephemeral=True)
|
||||||
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(
|
await interaction.response.send_message("Aucune énigme en cours", ephemeral=True)
|
||||||
"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(
|
||||||
@ -343,17 +345,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", description="Demander un indice pour l'énigme en cours"
|
name="indice",
|
||||||
|
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(
|
await interaction.response.send_message("Aucune énigme en cours", ephemeral=True)
|
||||||
"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"]
|
||||||
@ -364,7 +366,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:
|
||||||
@ -375,8 +377,6 @@ 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(
|
await interaction.response.send_message("Nouvel indice : `{0}`".format(clue_string(answer, nb_clues)))
|
||||||
"Nouvel indice : `{0}`".format(clue_string(answer, nb_clues))
|
|
||||||
)
|
|
||||||
|
|||||||
27
rhymes.py
27
rhymes.py
@ -76,12 +76,7 @@ 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 (
|
if not message.author.bot and message.author.id != client.user.id and message.guild and last_word:
|
||||||
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)
|
||||||
|
|
||||||
@ -115,27 +110,23 @@ 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(
|
def setup_rhymes_commands(client: discord.Client, tree: discord.app_commands.CommandTree) -> None:
|
||||||
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(interaction: discord.Interaction, ratio: float):
|
async def config(
|
||||||
|
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(
|
await interaction.response.send_message(f"{msg}\nLes \"poil au\" sont désormais désactivés.", ephemeral=True)
|
||||||
f'{msg}\nLes "poil au" sont désormais désactivés.', ephemeral=True
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(f"{msg}\nLes \"poil au\" ont désormais un cooldown entre 0 et {int(180*ratio)} minutes.", ephemeral=True)
|
||||||
f'{msg}\nLes "poil au" ont désormais un cooldown entre 0 et {int(180 * ratio)} minutes.',
|
|
||||||
ephemeral=True,
|
|
||||||
)
|
|
||||||
|
|||||||
@ -1,58 +1,47 @@
|
|||||||
|
```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(
|
riddle_text = riddle_text.replace('<br/>', '\n').replace('<br>', '\n')
|
||||||
"<br>", "\n"
|
riddle_text = BeautifulSoup(riddle_text, 'html.parser').get_text(strip=True)
|
||||||
)
|
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(
|
riddles.append({'riddle': riddle_text, 'answer': answer_text, 'count': riddle_count, 'year': scrap_year})
|
||||||
{
|
|
||||||
"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)
|
||||||
|
```
|
||||||
Loading…
x
Reference in New Issue
Block a user