SPB Git forge

spb/uqo-imm1033

Public
5commits 1branches 0releases
30.2 MBsize
maindefault branch
2 h agolast push
JavaScript 68% CSS 32%
7.7 KB

# _Site_web — Notes de cours interactives IMM1003 et IMM1033 (v2)

Générateur de sites statiques à partir des sources LaTeX des manuels (<cours>/<code>_Notes_de_cours/sources/) et du rapport Rapport_Immobilier_Quebec/. Deux sites publics servis par le cluster MacLustr via mld + ngrok :

Site Domaine App mld Port
IMM1003 — Éléments d’évaluation immobilière https://www.uqo-imm1003.app uqo-imm1003 8160
IMM1033 — Méthodes du coût https://www.uqo-imm1033.app uqo-imm1033 8161

# Ce que contient chaque site

  • Séances 1 à 14 : notes intégrales (boîtes pédagogiques, notes marginales Tufte, KaTeX, TikZ→SVG), stepper de sections, sommaire avec sections lues, objectifs cochables, mode révision, explorateurs interactifs insérés dans les séances (9 par cours, courses.py → widgets), surlignage + notes personnelles (export Markdown), lecture audio (synthèse vocale), quiz intégré.
  • Réviser : aide-mémoire, glossaire (infobulles dans le texte), toutes les définitions, fiches recto-verso, carte du cours (SVG radial, objectifs par séance), banque d’exercices.
  • S’exercer : quiz + examen blanc, entraînement (problèmes à données aléatoires, data/entrainement-<code>.js), jeux (association, vrai/faux, remise en ordre — courses.py → sequences), calculateurs (data/outils-<code>.js), tableau de bord de progression (export/import JSON).
  • Ressources : diapositives, téléchargements, rapport « Le marché de l’habitation au Québec » (21 sections, 67 figures SVG, 28 tableaux, métriques clés, explorateurs HPI ACI et FRED avec données data/hpi.json, data/fred.json), bibliographie fusionnée, recherche plein texte.
  • Séances vidéo (/videos/, /videos/<nn>/) : enregistrements Zoom avec chapitres cliquables, ligne du temps, transcription synchronisée et cherchable (clic = aller dans la vidéo), sous-titres WebVTT, storyboard des changements d’écran, résumé + « à retenir » + questions posées, clavardage, téléchargements (MP4, M4A, VTT, SRT, TXT), reprise de lecture, vitesse, mode audio seulement, lien horodaté ?t=. Bouton « Enregistrement de la séance » sur la page de séance correspondante ; chapitres indexés dans la recherche.
  • Identité UQO : logo officiel (barre, héros, pied de page), favicons/icônes tactiles générés (build/brand.py), image de partage Open Graph 1200×630 par cours (/assets/og.png), thème clair par défaut + thème sombre.

Non publiés : solutionnaires, questionnaires d’examen, grilles de correction.

# Arborescence

text
_Site_web/
├── build/
│   ├── build.py          ← orchestrateur : python3 build/build.py [imm1003] [imm1033]
│   ├── latex2html.py     ← convertisseur LaTeX → HTML (dialecte uqo-notes.sty + article du rapport)
│   ├── videos.py         ← séances vidéo : nettoyage whisper, cues VTT/SRT, paragraphes, chapitres, storyboard (ffmpeg + Pillow), cache/video-frames/
│   ├── rapport.py        ← rapport : découpage en sections, tableaux \input, valeurs clés, figures PDF→SVG, extraction HPI (xlsx) et FRED (json)
│   ├── tikz.py           ← tikzpicture → SVG (pdflatex standalone + pdftocairo), cache/tikz/
│   ├── render_math.mjs   ← KaTeX en lot (node)
│   ├── bib.py            ← references.bib → auteur-année
│   ├── brand.py          ← logo UQO, favicons, apple-touch-icon, image OG (Pillow + Fira Sans de TeX Live)
│   ├── templates.py      ← gabarits HTML (accueil, séance, carte, rapport, jeux, entraînement, progression…)
│   ├── courses.py        ← métadonnées : parties et couleurs, calendrier, évaluations, TP publiés, widgets, séquences
│   └── test_convert.py   ← test de conversion complet
├── assets/css/site.css   ← feuille de style v2 (Fraunces / Source Serif 4 / Fira Sans, couleur par partie, mobile)
├── assets/js/app.js      ← application cliente : recherche, quiz, fiches, widgets SVG, entraînement, jeux, progression, notes, TTS, explorateurs HPI/FRED
├── assets/brand/         ← logo UQO source (Wikimedia + sources LaTeX)
├── data/                 ← quiz-<code>.json, outils-<code>.js, entrainement-<code>.js
├── videos/<code>/<nn>/   ← séance vidéo : video.mp4 + audio.m4a (gitignorés), transcript.json (whisper), meta.json (chapitres, résumé…), chat.txt, scenes.txt
├── server/server.mjs     ← serveur statique Node zéro dépendance
├── cache/                ← tikz/ et rapport-fig/ (SVG rendus)
├── dist/<code>/          ← sites générés (ignorés par git)
└── stage/uqo-<code>/     ← dossiers d'app pour `mld stage`

# Construire et déployer

bash
cd _Site_web && npm install            # KaTeX (une fois)
python3 build/build.py                 # ≈ 1 s par cours avec les caches
node server/server.mjs 8160 dist/imm1003   # test local
for c in imm1003 imm1033; do
  rm -rf stage/uqo-$c/dist && cp -R dist/$c stage/uqo-$c/dist
  ~/Desktop/cluster-skill/mld stage stage/uqo-$c uqo-$c && ~/Desktop/cluster-skill/mld deploy uqo-$c
done

Prérequis : Python ≥ 3.12 (+ Pillow, openpyxl), Node ≥ 20, TeX Live (pdflatex, FiraSans, fontawesome5, pgfplots), poppler (pdftocairo, pdfinfo), ffmpeg/ffprobe (séances vidéo), venv ~/.venvs/whisper (mlx-whisper) pour transcrire. Manifestes mld : M1M32:~/dispatch/apps/uqo-imm1003.json, uqo-imm1033.json. Emplacement courant : mld status.

# Ajouter une séance vidéo (enregistrement Zoom)

bash
V=videos/imm1003/02 && mkdir -p $V      # ou videos/imm1033/<nn> ; même recette pour les deux cours
ffmpeg -i ~/Desktop/seanceN/video*.mp4 -c copy -movflags +faststart $V/video.mp4   # remux pour la lecture progressive
cp ~/Desktop/seanceN/audio*.m4a $V/audio.m4a ; cp ~/Desktop/seanceN/chat.txt $V/     # chat optionnel
~/.venvs/whisper/bin/mlx_whisper $V/audio.m4a --model mlx-community/whisper-large-v3-turbo --language fr \
  --output-dir /tmp/tr --output-name s --output-format json --word-timestamps True --condition-on-previous-text False
cp /tmp/tr/s.json $V/transcript.json
ffmpeg -i $V/video.mp4 -vf "scale=432:-2,select='gt(scene,0.12)',showinfo" -vsync vfr -f null - 2>&1 \
  | grep -o "pts_time:[0-9.]*" | sed 's/pts_time://' > $V/scenes.txt                   # changements de diapositive
# puis rédiger $V/meta.json (date_text, start_t, chapters[{t,title,desc,link,kind}], summary, keypoints, questions, related)
python3 build/build.py imm1003        # puis : cp -R dist/<code> stage/uqo-<code>/dist ; cp server/server.mjs stage/uqo-<code>/ ; python3 stage/make_app_repos.py ;
                                      # commit/push stage/uqo-<code> (médias gitignorés) ; mld stage stage/uqo-<code> uqo-<code> ; mld deploy uqo-<code> --node <nœud courant>

Le build lie (hard link) le MP4 dans dist/<code>/videos/<nn>/, génère captions.vtt, chapters.vtt, transcript.{json,srt,txt}, poster.webp, sb/*.webp et la page. Les médias ne sont pas versionnés (ni dans UQO_COURS ni dans stage/uqo-<code>) : ils voyagent par mld stage (rsync). Le serveur sert les plages HTTP (Range) pour la lecture progressive.

# Ajouter du contenu interactif

  • Widget dans une séance : ajouter ("s-<ch>-<sec>", "<nom>") dans courses.py → widgets et enregistrer <nom> via Widgets.register(...) dans app.js (le widget est inséré à la fin de la première sous-section).
  • Problème d’entraînement : ajouter un objet {id, title, ch, url, gen(R)} dans data/entrainement-<code>.js.
  • Séquence (jeu de remise en ordre) : ajouter un triplet dans courses.py → sequences.
  • Question de quiz : data/quiz-<code>.json (q, c [choix], a index, e explication, url).