DOCS/outputs/mnaha/seed/step2_sections.py
Thomas Fransolet d14f151517 Livrables de presentation, seed de demo MNAHA et wireframes
- outputs/platform, outputs/prospect : scripts de construction des decks
  commerciaux + captures sources et .pptx generes.
- outputs/mnaha : seed complet de l'instance de demo luxembourgeoise
  (scripts par etape, contenus, images generees), le deck en version
  marque blanche et en version brandee, le PDF de presentation.
- outputs/Wireframes : maquettes app mobile, app web et manager.
- interview clients : notes de l'entretien Fourneau St Michel.

state.json et les __pycache__ sont ignores : le premier porte les cles
d'API de l'instance seedee, les scripts le regenerent.
2026-09-11 15:47:57 +02:00

145 lines
5.6 KiB
Python

# -*- coding: utf-8 -*-
"""Étape 2 — articles, sommaire et quiz.
Une section se crée vide (POST /api/Section, qui ne connaît que le type), puis se
remplit par un PUT typé. C'est le chemin que suit manager-app.
"""
import json
from pathlib import Path
from api import Api, LANGS, tr
from content import ARTICLES, MENUS, QUIZZES
STATE = Path(__file__).resolve().parent / "state.json"
ARTICLE, MENU, QUIZ = 6, 4, 5
def empty_translations():
return [{"language": lang, "value": ""} for lang in LANGS]
def create_section(api, state, config_key, section_type, label):
"""Crée la section si son label n'existe pas déjà dans cette configuration."""
config_id = state["configs"][config_key]
existing = api.get(f"/api/Section/configuration/{config_id}") or []
found = next((s for s in existing if s["label"] == label), None)
if found:
return found, False
created = api.post("/api/Section", {
"configurationId": config_id,
"instanceId": state["instanceId"],
"label": label,
"type": section_type,
"isSubSection": False,
})
return created, True
def seed_articles(api, state):
for config_key, articles in ARTICLES.items():
for order, art in enumerate(articles):
section, created = create_section(api, state, config_key, ARTICLE,
art["label"])
lat, lon = art["coords"]
api.put("/api/Section", {
**section,
"type": ARTICLE,
"order": order,
"title": tr(**art["title"]),
"description": tr(**art["description"]),
"content": tr(**art["content"]),
"isContentTop": False,
"isReadAudioAuto": False,
"audioIds": empty_translations(),
"contents": [],
"isBeacon": True,
"beaconId": art["beacon"],
"latitude": lat,
"longitude": lon,
"meterZoneGPS": 12,
})
print(f" {'+' if created else '=':1} article {config_key} / {art['label']}")
def seed_menus(api, state):
for config_key, menu in MENUS.items():
section, created = create_section(api, state, config_key, MENU, menu["label"])
api.put("/api/Section", {
**section,
"type": MENU,
"order": 10,
"title": tr(**menu["title"]),
"description": tr(**menu["description"]),
"sections": [],
})
print(f" {'+' if created else '='} sommaire {config_key} / {menu['label']}")
def seed_quizzes(api, state):
for config_key, quiz in QUIZZES.items():
section, created = create_section(api, state, config_key, QUIZ, quiz["label"])
api.put("/api/Section", {
**section,
"type": QUIZ,
"order": 11,
"title": tr(**quiz["title"]),
"description": tr(FR="Trois questions, une minute.",
DE="Drei Fragen, eine Minute.",
EN="Three questions, one minute.",
NL="Drie vragen, één minuut."),
"questions": [],
"bad_level": tr(FR="Il reste des salles à explorer.",
DE="Es gibt noch Säle zu entdecken.",
EN="There are still rooms to explore.",
NL="Er zijn nog zalen te ontdekken."),
"medium_level": tr(FR="Bon début — continuez la visite.",
DE="Guter Anfang — setzen Sie den Rundgang fort.",
EN="Good start — carry on with the visit.",
NL="Goed begin — zet het bezoek voort."),
"good_level": tr(FR="Belle attention aux détails.",
DE="Schöne Aufmerksamkeit für Details.",
EN="Fine attention to detail.",
NL="Mooie aandacht voor details."),
"great_level": tr(FR="Sans faute. Vous avez tout lu !",
DE="Fehlerfrei. Sie haben alles gelesen!",
EN="Flawless. You read everything!",
NL="Foutloos. U hebt alles gelezen!"),
})
already = api.get(f"/api/SectionQuiz/{section['id']}/questions") or []
if already:
print(f" = quiz {config_key} ({len(already)} questions déjà là)")
continue
for order, question in enumerate(quiz["questions"]):
api.post(f"/api/SectionQuiz/{section['id']}/questions", {
"sectionQuizId": section["id"],
"order": order,
"label": [{"language": lang, "value": question["q"].get(lang,
question["q"]["FR"])}
for lang in LANGS],
"responses": [
{"order": i,
"isGood": good,
"label": [{"language": lang, "value": text.get(lang, text["FR"])}
for lang in LANGS]}
for i, (text, good) in enumerate(question["answers"])
],
})
print(f" + quiz {config_key} ({len(quiz['questions'])} questions)")
def main():
api = Api()
state = json.loads(STATE.read_text(encoding="utf-8"))
seed_articles(api, state)
seed_menus(api, state)
seed_quizzes(api, state)
print("\nétape 2 terminée")
if __name__ == "__main__":
main()