Phase 1.2 de la feuille de route produit — un paquet SCORM tourne seul dans le LMS du client, sans serveur Forge Engine disponible. Ajoute static/js/play/offline/ (miroir JS de screens/rendering/ et data_actions/, sous window.FORGE_OFFLINE) pour que variables, score, données d'objet, répéteurs et conditions de visibilité fonctionnent entièrement en mémoire côté navigateur ; branche actions.js et bindings.js dessus au lieu d'un fetch() serveur. Ajoute publish/build_scorm_package.py (paquet statique + imsmanifest.xml SCORM 1.2 + wrapper API SCORM) et le bouton "Exporter (Web/SCORM)". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
49 lines
1.9 KiB
Python
49 lines
1.9 KiB
Python
"""Génère imsmanifest.xml (SCORM 1.2) pour le paquet Web/SCORM (voir
|
|
build_scorm_package.py). SCORM 1.2 plutôt que 2004 : support le plus
|
|
large chez les clients visés (Moodle, la plupart des LMS d'entreprise
|
|
acceptent les deux, l'inverse est faux)."""
|
|
import os
|
|
from xml.sax.saxutils import escape
|
|
|
|
_MANIFEST_TEMPLATE = """<?xml version="1.0" standalone="no" ?>
|
|
<manifest identifier="FORGE_{identifier}" version="1"
|
|
xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
|
|
xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd
|
|
http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd">
|
|
<metadata>
|
|
<schema>ADL SCORM</schema>
|
|
<schemaversion>1.2</schemaversion>
|
|
</metadata>
|
|
<organizations default="FORGE_ORG_{identifier}">
|
|
<organization identifier="FORGE_ORG_{identifier}">
|
|
<title>{title}</title>
|
|
<item identifier="FORGE_ITEM_{identifier}" identifierref="FORGE_RES_{identifier}">
|
|
<title>{title}</title>
|
|
</item>
|
|
</organization>
|
|
</organizations>
|
|
<resources>
|
|
<resource identifier="FORGE_RES_{identifier}" type="webcontent" adlcp:scormtype="sco" href="index.html">
|
|
<file href="index.html"/>
|
|
{file_entries}
|
|
</resource>
|
|
</resources>
|
|
</manifest>
|
|
"""
|
|
|
|
|
|
def build_manifest_xml(slug, game_name, package_files):
|
|
"""`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."""
|
|
file_entries = "\n".join(
|
|
' <file href="{}"/>'.format(escape(rel.replace(os.sep, "/")))
|
|
for rel in package_files
|
|
)
|
|
return _MANIFEST_TEMPLATE.format(
|
|
identifier=escape(slug), title=escape(game_name), file_entries=file_entries,
|
|
)
|