from .constants import QUEST_STATUS_CHOICES _MAX_LINES_PER_COLUMN = 200 _MAX_SPEAKER_LENGTH = 60 def sanitize_quest_dialogues(raw_dialogues): """Une réplique = {speaker: '', text: '...'} — le nom vient du champ "ℹ️ Informations" d'un objet de scène kind= "personnage" (voir screens/rendering/personnage_names.py), ou "Joueur" (toujours proposé, voir static/js/quests/quest-editor.js) : texte libre côté serveur (jamais un enum fixe — n'importe quel nom donné à un personnage doit être accepté), juste borné en longueur. Une colonne par statut de quête (voir QUEST_STATUS_CHOICES), même esprit que resolve_collision_rules.sanitize_collision_rules : rejette tout élément invalide plutôt que de lever, ne garde jamais un texte ou un nom vide.""" result = {status: [] for status in QUEST_STATUS_CHOICES} if not isinstance(raw_dialogues, dict): return result for status in QUEST_STATUS_CHOICES: raw_lines = raw_dialogues.get(status) if not isinstance(raw_lines, list): continue cleaned = [] for raw_line in raw_lines[:_MAX_LINES_PER_COLUMN]: if not isinstance(raw_line, dict): continue speaker = raw_line.get("speaker") text = raw_line.get("text") if not isinstance(speaker, str) or not speaker.strip(): continue if not isinstance(text, str) or not text.strip(): continue cleaned.append({"speaker": speaker.strip()[:_MAX_SPEAKER_LENGTH], "text": text.strip()}) result[status] = cleaned return result