Compare commits
5 Commits
feature/re
...
feature/in
| Author | SHA1 | Date | |
|---|---|---|---|
| faba475d67 | |||
| 5c8c45518c | |||
| 8cbb77be3c | |||
| 59a501c0a6 | |||
| 6692c43102 |
11
.dockerignore
Normal file
11
.dockerignore
Normal file
@@ -0,0 +1,11 @@
|
||||
venv/
|
||||
.venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.git/
|
||||
tests/
|
||||
*.log
|
||||
.env
|
||||
config/
|
||||
/.vscode/
|
||||
*.log
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -165,3 +165,5 @@ data/
|
||||
*.disabled
|
||||
|
||||
config/
|
||||
|
||||
tests/
|
||||
35
Dockerfile
35
Dockerfile
@@ -1,19 +1,36 @@
|
||||
FROM python:3.13.14-alpine
|
||||
|
||||
RUN apk add --no-cache \
|
||||
build-base \
|
||||
libffi-dev \
|
||||
musl-dev \
|
||||
openssl-dev \
|
||||
python3-dev \
|
||||
geckodriver \
|
||||
firefox-esr
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt && \
|
||||
apk add --no-cache firefox geckodriver
|
||||
|
||||
COPY . .
|
||||
|
||||
ENV TOKEN=""
|
||||
ENV URL=""
|
||||
ENV CONFIG_PATH="/config"
|
||||
ENV COGS=""
|
||||
ENV GECKODRIVER_PATH="/usr/bin/geckodriver"
|
||||
|
||||
RUN mkdir ${CONFIG_PATH}
|
||||
RUN adduser -D bot && \
|
||||
mkdir /logs && \
|
||||
chown -R bot:bot /logs && \
|
||||
chmod 755 /logs && \
|
||||
mkdir -p ${CONFIG_PATH} && \
|
||||
chown -R bot:bot ${CONFIG_PATH} && \
|
||||
chmod 755 ${CONFIG_PATH}
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
RUN chown -R bot:bot /app && \
|
||||
chmod -R 755 /app && \
|
||||
chmod +x /app/main.py
|
||||
|
||||
USER bot
|
||||
|
||||
ENTRYPOINT ["python", "main.py"]
|
||||
17
compose.yaml
17
compose.yaml
@@ -6,15 +6,30 @@ networks:
|
||||
|
||||
services:
|
||||
botmafieux:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: nebulo9/botmafieux:latest
|
||||
container_name: botmafieux
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- internal
|
||||
- outbound
|
||||
env_file: ./.env
|
||||
env_file:
|
||||
- ./.env
|
||||
volumes:
|
||||
- ./config:/config
|
||||
healthcheck:
|
||||
test: ["CMD", "pgrep", "-f", "main.py"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
|
||||
6778
config/hltv.html
6778
config/hltv.html
File diff suppressed because one or more lines are too long
@@ -1,27 +0,0 @@
|
||||
Ta gueule.
|
||||
Qui a demandé ?
|
||||
Mais tais-toi!
|
||||
zZzZzZzZ......
|
||||
Tout ça ?
|
||||
On peut se passer du message je pense.
|
||||
C'est chiant le message là.
|
||||
Mdr on s'en fout.
|
||||
Pas lu.
|
||||
Trop long j'ai décroché.
|
||||
Il faut quitter le serveur, vous gênez l'espace s'il vous plaît.
|
||||
Gênant...
|
||||
Si je devais noter la pertinence du message ce serait genre 1/10.
|
||||
Tu es ridicule, arrête d'écrire.
|
||||
Ça a intéréssé quelqu'un ?
|
||||
Franchement c'était nécessaire d'écrire ça ?
|
||||
Honestly the most useless thing I read today.
|
||||
Dommage que les hommes soient cons…
|
||||
Ta mère mérite la prison pour avoir mis au monde un HOMME.
|
||||
T'as pas beaucoup de neurones.
|
||||
Arrêtons de normaliser les hommes svp.
|
||||
🚮🚮
|
||||
Ton message me donne envie de vomir.
|
||||
J'ai pas ri perso.
|
||||
Tiens tiens encore une raison de détester les hommes !
|
||||
Y'a moyen ton père c'est Macron.
|
||||
Tu préfères devenir un être humain sympa ou rester un homme ?
|
||||
@@ -1 +0,0 @@
|
||||
[{"mentor_id": 264189554582355969, "guild_id": 897157935006900254, "next_roll": "2026-07-22T00:00:00"}]
|
||||
@@ -1,22 +0,0 @@
|
||||
target;weight;take
|
||||
any;1.0;Tu as besoin d'un café ?
|
||||
any;1.0;Je peux te faire un café si tu veux ?
|
||||
any;1.0;Tu as besoin d'un thé ?
|
||||
any;1.0;Je peux te faire un thé si tu veux ?
|
||||
any;1.0;Tu as besoin d'un matcha latte?
|
||||
any;1.0;Je peux te faire un matcha latte si tu veux ?
|
||||
any;1.0;Tu peux m'aider sur un truc ?
|
||||
any;1.0;Désolé, j'ai pas compris.
|
||||
any;1.0;Attends, tu peux réexpliquer ?
|
||||
any;1.0;J'ai fait une bêtise je crois...
|
||||
nebulo;2.0;J'ai un bug dans mon code tu peux regarder ?
|
||||
bluebro;2.0;J'ai un bug dans mon code tu peux regarder ?
|
||||
viebah;2.0;J'ai un bug dans mon code tu peux regarder ?
|
||||
merdix;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||
goupzy;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||
viebah;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||
goupzy;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||
nino274;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||
cemesah;2.0;J'ai fait une erreur, il faut réimprimer les cartes...
|
||||
cemesah;2.0;J'ai pas sauvegardé et InDesign a planté...
|
||||
cemesah;2.0;Tu veux du bouillon ?
|
||||
|
@@ -1,10 +1,13 @@
|
||||
aiohappyeyeballs==2.6.2
|
||||
aiohappyeyeballs==2.7.1
|
||||
aiohttp==3.14.1
|
||||
aiosignal==1.4.0
|
||||
asarPy==1.0.1
|
||||
async-timeout==5.0.1
|
||||
attrs==26.1.0
|
||||
audioop-lts==0.2.2
|
||||
beautifulsoup4==4.15.0
|
||||
certifi==2026.5.20
|
||||
cffi==2.1.0
|
||||
charset-normalizer==3.4.7
|
||||
frozenlist==1.8.0
|
||||
h11==0.16.0
|
||||
@@ -15,6 +18,8 @@ outcome==1.3.0.post0
|
||||
propcache==0.5.2
|
||||
psycopg2-binary==2.9.12
|
||||
py-cord==2.8.0
|
||||
pycparser==3.0
|
||||
PyNaCl==1.6.2
|
||||
PySocks==1.7.1
|
||||
python-dotenv==1.2.2
|
||||
requests==2.34.2
|
||||
@@ -24,8 +29,9 @@ sortedcontainers==2.4.0
|
||||
soupsieve==2.8.4
|
||||
trio==0.33.0
|
||||
trio-websocket==0.12.2
|
||||
typing_extensions==4.15.0
|
||||
typing_extensions==4.16.0
|
||||
urllib3==2.7.0
|
||||
wavelink==3.5.2
|
||||
websocket-client==1.9.0
|
||||
wsproto==1.3.2
|
||||
yarl==1.24.2
|
||||
|
||||
23
setup/bot.py
23
setup/bot.py
@@ -1,7 +1,5 @@
|
||||
import discord
|
||||
from discord.ext import bridge
|
||||
# from cogs.birthday import BirthdayCog
|
||||
# from cogs.productivity import ProductivityCog
|
||||
from discord.ext import commands
|
||||
from cogs.cs import CSCog
|
||||
from cogs.insult import InsultsCog
|
||||
from cogs.roulette import RouletteCog
|
||||
@@ -15,8 +13,9 @@ bot_intents.members = True
|
||||
bot_intents.presences = True
|
||||
bot_intents.guilds = True
|
||||
bot_intents.reactions = True
|
||||
bot_intents.voice_states = True
|
||||
|
||||
bot = bridge.Bot(command_prefix='$', intents=bot_intents)
|
||||
bot = commands.Bot(command_prefix='$', intents=bot_intents)
|
||||
|
||||
COG_REGISTRY = {
|
||||
'cs': CSCog,
|
||||
@@ -29,6 +28,22 @@ COG_REGISTRY = {
|
||||
from discord import option as discord_option
|
||||
|
||||
|
||||
@bot.slash_command(name="reload", description="Reload a feature (cog) by name, or 'all')")
|
||||
@discord_option(name="feature", description="Feature to reload (e.g. cs, insult, roles, roulette, all)", input_type=str, required=True)
|
||||
async def reload(ctx: discord.ApplicationContext, feature: str):
|
||||
# Only allow administrators
|
||||
if not ctx.author or not getattr(ctx.author, 'guild_permissions', None) or not ctx.author.guild_permissions.administrator:
|
||||
await ctx.respond("You must be a server administrator to use this command.", ephemeral=True)
|
||||
return
|
||||
|
||||
await ctx.defer()
|
||||
reload_feature(feature)
|
||||
await ctx.followup.send(f"Reload requested for feature: {feature}", ephemeral=True)
|
||||
|
||||
# Register a global admin slash command directly on the bot to avoid circular imports.
|
||||
from discord import option as discord_option
|
||||
|
||||
|
||||
@bot.slash_command(name="reload", description="Reload a feature (cog) by name, or 'all')")
|
||||
@discord_option(name="feature", description="Feature to reload (e.g. cs, insult, roles, roulette, all)", input_type=str, required=True)
|
||||
async def reload(ctx: discord.ApplicationContext, feature: str):
|
||||
|
||||
@@ -7,19 +7,11 @@ class Config:
|
||||
|
||||
TOKEN = str(os.getenv("TOKEN", ""))
|
||||
CONFIG_PATH = str(os.getenv("CONFIG_PATH"))
|
||||
COGS = os.getenv("COGS", "")
|
||||
|
||||
GUILDS_IDS:list[int] = []
|
||||
|
||||
GUILD_CONFIGS:dict[int,dict] = {}
|
||||
|
||||
@classmethod
|
||||
def get_cogs(cls):
|
||||
raw_value = cls.COGS.strip()
|
||||
if not raw_value:
|
||||
return None
|
||||
return [item.strip().lower() for item in raw_value.split(",") if item.strip()]
|
||||
|
||||
@classmethod
|
||||
def load_guilds_configs(cls):
|
||||
with os.scandir(cls.CONFIG_PATH) as d:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
import sys
|
||||
|
||||
# Determine log level from environment variable `LOG_LEVEL` (e.g. DEBUG, INFO)
|
||||
raw_level = os.getenv("LOG_LEVEL", "INFO").upper()
|
||||
@@ -15,7 +17,26 @@ else:
|
||||
logging.basicConfig(level=level, format='[%(levelname)s] %(asctime)s: %(name)s: %(message)s')
|
||||
LOGGER = logging.getLogger('botmafieux')
|
||||
LOGGER.setLevel(level)
|
||||
# File handler (append)
|
||||
handler = logging.FileHandler(filename='botmafieux.log', encoding='utf-8', mode='a')
|
||||
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
|
||||
LOGGER.addHandler(handler)
|
||||
|
||||
# Decide log file path: prefer LOG_FILE, then CONFIG_PATH/botmafieux.log, then /tmp
|
||||
preferred = os.getenv('LOG_FILE')
|
||||
if not preferred:
|
||||
cfg_path = "/logs"
|
||||
if cfg_path:
|
||||
preferred = os.path.join(cfg_path, 'botmafieux.log')
|
||||
else:
|
||||
preferred = os.path.join(tempfile.gettempdir(), 'botmafieux.log')
|
||||
|
||||
formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s')
|
||||
|
||||
try:
|
||||
handler = logging.FileHandler(filename=preferred, encoding='utf-8', mode='a')
|
||||
handler.setFormatter(formatter)
|
||||
LOGGER.addHandler(handler)
|
||||
except (PermissionError, OSError) as e:
|
||||
# Fall back to console logging if file cannot be opened
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
stream_handler.setFormatter(formatter)
|
||||
LOGGER.addHandler(stream_handler)
|
||||
# Print a warning directly to stderr in case logging isn't yet configured elsewhere
|
||||
print(f"[WARN] Could not open log file '{preferred}' for writing: {e}. Falling back to stdout.", file=sys.stderr)
|
||||
Reference in New Issue
Block a user