"""Génère imsmanifest.xml pour le paquet Web/SCORM (voir build_scorm_package.py) — SCORM 1.2 par défaut (support le plus large chez les clients visés, Moodle et la plupart des LMS d'entreprise acceptent les deux, l'inverse est faux) ou 2004 3rd/4th edition au choix du créateur du jeu (voir db/games/get_scorm_version.py) : seule la 2004 sépare cmi.completion_status/cmi.success_status, utile quand un "échoué" doit rester "completed" (l'apprenant est allé au bout) plutôt que retomber en "incomplete" comme l'impose le champ unique de la 1.2.""" import os from xml.sax.saxutils import escape _MANIFEST_TEMPLATE_1_2 = """ ADL SCORM 1.2 {title} {title} {file_entries} """ _MANIFEST_TEMPLATE_2004 = """ ADL SCORM 2004 4th Edition {title} {title} {file_entries} """ _MANIFEST_TEMPLATES = {"1.2": _MANIFEST_TEMPLATE_1_2, "2004": _MANIFEST_TEMPLATE_2004} def build_manifest_xml(slug, game_name, package_files, version="1.2"): """`package_files` : chemins relatifs (depuis la racine du paquet, tel qu'écrits dans le zip) de TOUS les fichiers autres que index.html — un LMS strict (SCORM Cloud) rejette un manifeste qui omet un fichier réellement présent dans le paquet. `version` : '1.2' (défaut) ou '2004' — voir db/games/get_scorm_version.py.""" file_entries = "\n".join( ' '.format(escape(rel.replace(os.sep, "/"))) for rel in package_files ) template = _MANIFEST_TEMPLATES.get(version, _MANIFEST_TEMPLATE_1_2) return template.format( identifier=escape(slug), title=escape(game_name), file_entries=file_entries, )