- Remplace JSON par SQLite (aiosqlite) pour atomicité et intégrité - Nouveau format RIB français avec checksum modulo 97 - Chaque banque a son propre rôle Discord (isolation par serveur) - TVA automatique Particulier -> Entreprise, redirection au Fisc - Institutions gouvernementales avec droit d'audit optionnel - Commandes: /gouv, /banque, /audit, /mes-ribs - Supprime: 16 anciens fichiers (entreprises, FBM, URSAFF, etc.) - Reset complet des données, repart de zéro
151 lines
4.2 KiB
Python
151 lines
4.2 KiB
Python
import json
|
|
import os
|
|
import discord
|
|
from typing import Optional
|
|
|
|
CONFIG_DIR = os.path.join(os.path.dirname(__file__), "..", "data", "guilds")
|
|
|
|
DEFAULT_CONFIG = {
|
|
"roles": {
|
|
"banquier": None,
|
|
"gouvernement": None,
|
|
"citoyen": None,
|
|
"staff": None,
|
|
"team_staff": None,
|
|
"attente_oral": None,
|
|
"candidature_a_faire": None,
|
|
"ems": None,
|
|
"visite_medicale": None,
|
|
"permis": None,
|
|
"auto_ecole": None,
|
|
"session_reminders": None,
|
|
},
|
|
"channels": {
|
|
"welcome": None,
|
|
"candidature": None,
|
|
"candidature_2": None,
|
|
"questions": None,
|
|
"mp_reception": None,
|
|
},
|
|
"categories": {
|
|
"ticket": None,
|
|
},
|
|
}
|
|
|
|
ROLE_LABELS = {
|
|
"banquier": "Banquier",
|
|
"gouvernement": "Gouvernement",
|
|
"citoyen": "Citoyen",
|
|
"staff": "Staff",
|
|
"team_staff": "Team Staff",
|
|
"attente_oral": "Attente Oral",
|
|
"candidature_a_faire": "Candidature A Faire",
|
|
"ems": "EMS",
|
|
"visite_medicale": "Visite Médicale",
|
|
"permis": "Permis",
|
|
"auto_ecole": "Auto-École",
|
|
"session_reminders": "Session Reminders",
|
|
}
|
|
|
|
CHANNEL_LABELS = {
|
|
"welcome": "Bienvenue",
|
|
"candidature": "Candidature",
|
|
"candidature_2": "Candidature 2",
|
|
"questions": "Questions",
|
|
"mp_reception": "Réception MP",
|
|
}
|
|
|
|
CATEGORY_LABELS = {
|
|
"ticket": "Tickets",
|
|
}
|
|
|
|
|
|
def _config_path(guild_id: int) -> str:
|
|
return os.path.join(CONFIG_DIR, f"{guild_id}.json")
|
|
|
|
|
|
def load_guild_config(guild_id: int) -> dict:
|
|
path = _config_path(guild_id)
|
|
if not os.path.exists(path):
|
|
return {"roles": {}, "channels": {}, "categories": {}}
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
return json.load(f)
|
|
except (json.JSONDecodeError, IOError):
|
|
return {"roles": {}, "channels": {}, "categories": {}}
|
|
|
|
|
|
def save_guild_config(guild_id: int, config: dict):
|
|
os.makedirs(CONFIG_DIR, exist_ok=True)
|
|
path = _config_path(guild_id)
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
json.dump(config, f, ensure_ascii=False, indent=4)
|
|
|
|
|
|
def get_role_id(guild_id: int, key: str) -> Optional[int]:
|
|
config = load_guild_config(guild_id)
|
|
val = config.get("roles", {}).get(key)
|
|
return int(val) if val else None
|
|
|
|
|
|
def get_channel_id(guild_id: int, key: str) -> Optional[int]:
|
|
config = load_guild_config(guild_id)
|
|
val = config.get("channels", {}).get(key)
|
|
return int(val) if val else None
|
|
|
|
|
|
def get_category_id(guild_id: int, key: str) -> Optional[int]:
|
|
config = load_guild_config(guild_id)
|
|
val = config.get("categories", {}).get(key)
|
|
return int(val) if val else None
|
|
|
|
|
|
def get_guild_role(guild: discord.Guild, key: str) -> Optional[discord.Role]:
|
|
role_id = get_role_id(guild.id, key)
|
|
if not role_id:
|
|
return None
|
|
return guild.get_role(role_id)
|
|
|
|
|
|
def get_guild_channel(guild: discord.Guild, key: str) -> Optional[discord.abc.Messageable]:
|
|
channel_id = get_channel_id(guild.id, key)
|
|
if not channel_id:
|
|
return None
|
|
return guild.get_channel(channel_id)
|
|
|
|
|
|
def get_guild_category(guild: discord.Guild, key: str) -> Optional[discord.CategoryChannel]:
|
|
cat_id = get_category_id(guild.id, key)
|
|
if not cat_id:
|
|
return None
|
|
return guild.get_channel(cat_id)
|
|
|
|
|
|
def has_role(member: discord.Member, key: str) -> bool:
|
|
role = get_guild_role(member.guild, key)
|
|
if not role:
|
|
return False
|
|
return role in member.roles
|
|
|
|
|
|
def set_config_value(guild_id: int, section: str, key: str, value):
|
|
config = load_guild_config(guild_id)
|
|
if section not in config:
|
|
config[section] = {}
|
|
config[section][key] = value
|
|
save_guild_config(guild_id, config)
|
|
|
|
|
|
def is_configured(guild_id: int) -> dict:
|
|
config = load_guild_config(guild_id)
|
|
missing = {"roles": [], "channels": [], "categories": []}
|
|
for key in DEFAULT_CONFIG["roles"]:
|
|
if not config.get("roles", {}).get(key):
|
|
missing["roles"].append(key)
|
|
for key in DEFAULT_CONFIG["channels"]:
|
|
if not config.get("channels", {}).get(key):
|
|
missing["channels"].append(key)
|
|
for key in DEFAULT_CONFIG["categories"]:
|
|
if not config.get("categories", {}).get(key):
|
|
missing["categories"].append(key)
|
|
return missing
|