Final beta for tonight
This commit is contained in:
BIN
.bot.py.swp
Normal file
BIN
.bot.py.swp
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
arbre.png
BIN
arbre.png
Binary file not shown.
|
Before Width: | Height: | Size: 493 KiB After Width: | Height: | Size: 614 KiB |
BIN
avatars/1334641803059793940.png
Normal file
BIN
avatars/1334641803059793940.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
avatars/565561317189091328.png
Normal file
BIN
avatars/565561317189091328.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 274 KiB |
BIN
avatars/582633859967877133.png
Normal file
BIN
avatars/582633859967877133.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
20
bot.py
20
bot.py
@@ -74,14 +74,20 @@ async def enregistrer(interaction: discord.Interaction):
|
||||
async def adopter(interaction: discord.Interaction, enfant: discord.Member):
|
||||
parent = interaction.user
|
||||
|
||||
# Debug
|
||||
parent_gen = family.get_generation(str(parent.id))
|
||||
enfant_gen = family.get_generation(str(enfant.id))
|
||||
print(f"Adoption: {parent.display_name} (gen {parent_gen}) → {enfant.display_name} (gen {enfant_gen})")
|
||||
|
||||
# Validations
|
||||
if parent.id == enfant.id:
|
||||
await interaction.response.send_message("❌ Auto-adoption impossible !", ephemeral=True)
|
||||
return
|
||||
|
||||
if family.get_generation(str(enfant.id)) < family.get_generation(str(parent.id)):
|
||||
# Nouvelle condition plus permissive
|
||||
if enfant_gen > parent_gen:
|
||||
await interaction.response.send_message(
|
||||
"❌ Structure familiale invalide !",
|
||||
"❌ Impossible d'adopter quelqu'un de plus ancien que vous !",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
@@ -131,6 +137,16 @@ async def adopter(interaction: discord.Interaction, enfant: discord.Member):
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
@bot.tree.command(name="racine", description="Définir un membre comme racine")
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def racine(interaction: discord.Interaction, membre: discord.Member, est_racine: bool):
|
||||
success = family.set_as_root(str(membre.id), est_racine)
|
||||
await interaction.response.send_message(
|
||||
f"✅ {membre.mention} est maintenant {'une racine' if est_racine else 'plus une racine'} !"
|
||||
if success else "❌ Erreur",
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
@bot.tree.command(name="couple", description="Officialiser une relation")
|
||||
async def couple(interaction: discord.Interaction, partenaire: discord.Member):
|
||||
membre = interaction.user
|
||||
|
||||
22
family.json
22
family.json
@@ -29,7 +29,8 @@
|
||||
"id": "901473267104223232",
|
||||
"name": "Partenaire"
|
||||
}
|
||||
]
|
||||
],
|
||||
"avatar": "https://cdn.discordapp.com/avatars/436978132105560064/1d711ba4fea8d707903df35ea859a86c.png?size=1024"
|
||||
},
|
||||
"567371662165803009": {
|
||||
"name": "Je suis g\u00e9niale.ment on fire",
|
||||
@@ -120,6 +121,21 @@
|
||||
"name": "NYM N'EST PAS UN CODE BARRE"
|
||||
}
|
||||
]
|
||||
},
|
||||
"565561317189091328": {
|
||||
"name": "BardimeduSAFF Hamilton ofthemind",
|
||||
"avatar": "https://cdn.discordapp.com/avatars/565561317189091328/c77280ab4a455cd482f73a2ef38d72f8.png?size=1024",
|
||||
"parents": []
|
||||
},
|
||||
"582633859967877133": {
|
||||
"name": "L'incarn\u00e9 zzz",
|
||||
"avatar": "https://cdn.discordapp.com/avatars/582633859967877133/89c60709a5e4c47ee16001844f0d51ad.png?size=1024",
|
||||
"parents": []
|
||||
},
|
||||
"1334641803059793940": {
|
||||
"name": "Epic The Ticketal",
|
||||
"avatar": "https://cdn.discordapp.com/avatars/1334641803059793940/e36465f33fa4c2cd35a9de212e6832fc.png?size=1024",
|
||||
"parents": []
|
||||
}
|
||||
},
|
||||
"couples": [
|
||||
@@ -130,6 +146,10 @@
|
||||
[
|
||||
"506016482300395520",
|
||||
"769178722838118400"
|
||||
],
|
||||
[
|
||||
"565561317189091328",
|
||||
"582633859967877133"
|
||||
]
|
||||
]
|
||||
}
|
||||
56
family.py
56
family.py
@@ -13,7 +13,8 @@ class FamilyManager:
|
||||
with open(self.file_path, "w") as f:
|
||||
json.dump({
|
||||
"members": {},
|
||||
"couples": []
|
||||
"couples": [],
|
||||
"roots": []
|
||||
}, f, indent=2)
|
||||
|
||||
def _load(self) -> Dict:
|
||||
@@ -26,6 +27,23 @@ class FamilyManager:
|
||||
with open(self.file_path, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
def set_as_root(self, member_id: str, is_root: bool = True) -> bool:
|
||||
"""Définit un membre comme racine ou non"""
|
||||
data = self._load()
|
||||
if str(member_id) not in data["members"]:
|
||||
return False
|
||||
|
||||
if "roots" not in data:
|
||||
data["roots"] = []
|
||||
|
||||
if is_root and str(member_id) not in data["roots"]:
|
||||
data["roots"].append(str(member_id))
|
||||
elif not is_root and str(member_id) in data["roots"]:
|
||||
data["roots"].remove(str(member_id))
|
||||
|
||||
self._save(data)
|
||||
return True
|
||||
|
||||
def add_member(self, member_id: str, member_name: str, avatar_url: str = None):
|
||||
"""
|
||||
Ajoute ou met à jour un membre
|
||||
@@ -49,11 +67,12 @@ class FamilyManager:
|
||||
|
||||
self._save(data)
|
||||
|
||||
def add_child(self, parent_id: str, child_id: str):
|
||||
def add_child(self, parent_id: str, child_id: str) -> bool:
|
||||
"""
|
||||
Ajoute un lien parent-enfant
|
||||
:param parent_id: ID du parent
|
||||
:param child_id: ID de l'enfant
|
||||
:return: True si succès, False si échec
|
||||
"""
|
||||
data = self._load()
|
||||
|
||||
@@ -69,7 +88,7 @@ class FamilyManager:
|
||||
})
|
||||
|
||||
# Ajoute le partenaire comme parent secondaire si existe
|
||||
partner_id = self.get_partner(parent_id)
|
||||
partner_id = self.get_partner(str(parent_id))
|
||||
if partner_id:
|
||||
partner_name = data["members"].get(partner_id, {}).get("name", "Partenaire")
|
||||
data["members"][str(child_id)]["parents"].append({
|
||||
@@ -143,20 +162,33 @@ class FamilyManager:
|
||||
def get_generation(self, member_id: str) -> int:
|
||||
"""
|
||||
Calcule la génération d'un membre
|
||||
:return: 0 pour la racine, 1 pour ses enfants, etc.
|
||||
:return: 0 pour les racines, 1 pour leurs enfants, etc.
|
||||
"""
|
||||
data = self._load()
|
||||
generation = 0
|
||||
current_id = str(member_id)
|
||||
|
||||
while current_id in data["members"] and data["members"][current_id].get("parents"):
|
||||
current_id = data["members"][current_id]["parents"][0]["id"]
|
||||
generation += 1
|
||||
if generation > 10: # Sécurité contre les boucles infinies
|
||||
break
|
||||
return generation
|
||||
# Si c'est une racine explicite
|
||||
if str(member_id) in data.get("roots", []):
|
||||
return 0
|
||||
|
||||
parents = data["members"].get(str(member_id), {}).get("parents", [])
|
||||
|
||||
# Si pas de parents => nouvelle racine (gen 0)
|
||||
if not parents:
|
||||
return 0
|
||||
|
||||
# Calcul basé sur les parents
|
||||
return 1 + min(
|
||||
self.get_generation(p["id"])
|
||||
for p in parents
|
||||
if p["id"] in data["members"]
|
||||
)
|
||||
|
||||
def get_all_members(self) -> List[str]:
|
||||
"""Liste tous les IDs des membres enregistrés"""
|
||||
data = self._load()
|
||||
return list(data["members"].keys())
|
||||
|
||||
def get_roots(self) -> List[str]:
|
||||
"""Liste toutes les racines"""
|
||||
data = self._load()
|
||||
return data.get("roots", [])
|
||||
|
||||
9
tree.py
9
tree.py
@@ -37,7 +37,14 @@ def create_avatar_with_name(user_id, name, avatar_path, output_path):
|
||||
print(f"Erreur création avatar+texte {user_id}: {e}")
|
||||
return False
|
||||
|
||||
def generate_tree(input_file, output_file, root_id):
|
||||
def generate_tree(input_file, output_file, root_id=None): # root_id devient optionnel
|
||||
with open(input_file) as f:
|
||||
data = json.load(f)
|
||||
|
||||
roots = data.get("roots", [root_id] if root_id else [])
|
||||
if not roots:
|
||||
roots = [mid for mid, m in data["members"].items() if not m.get("parents")]
|
||||
|
||||
with open(input_file) as f:
|
||||
data = json.load(f)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user