From 6bf9f77b0881af71bbffc1acb2fe4b22b0519f1b Mon Sep 17 00:00:00 2001 From: rcmiller Date: Thu, 23 Feb 2023 19:53:17 -0500 Subject: [PATCH 1/3] support for exercise-all-answers-correct Surrounding an exercise or set of exercise choices with `
...
` turns off answer checking and just uses the handx form fields for data collection --- web/handout/handout-render.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/web/handout/handout-render.js b/web/handout/handout-render.js index e881202..dec12f0 100644 --- a/web/handout/handout-render.js +++ b/web/handout/handout-render.js @@ -436,6 +436,15 @@ function convertExercise(container, category, node) { choice.attr('data-ex-expected', encodeURIComponent(answerSpec)); } }); + + // override answer-checking if we are inside a mark-all-answers-correct element + if ($(this).parents('.exercise-all-answers-correct').length > 0) { + $('.exercise-choice', this).each(function() { + var choice = $(this); + choice.removeAttr('data-ex-expected'); + choice.attr('data-ex-regex', encodeURIComponent('/.*/')); + }); + } }); // header From 1c4d9dd1d47ba459254e4b6737641f24fbcca163 Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Sat, 27 May 2023 11:40:20 -0400 Subject: [PATCH 2/3] Topics & Terms is now populated only with handouts published on the homepage: replaced HANDOUT_TOC_KINDS with HANDOUT_TOC_ROOTS, and added data-handx-index to mark links to handouts that should be included in the TOC by recursive traversal from the roots --- server/course-setup.php | 2 +- server/structure.php | 29 +++++++++++++++++++---------- web/handout/handout-render.js | 7 +++++++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/server/course-setup.php b/server/course-setup.php index 64faf1d..e098c11 100644 --- a/server/course-setup.php +++ b/server/course-setup.php @@ -10,7 +10,7 @@ const OMNIVORE = 'https://omnivore.example.com'; const COURSE = '6.HANDX'; const SEMESTER = 'ia00'; -$HANDOUT_TOC_KINDS = array('classes'); +$HANDOUT_TOC_ROOTS = array('home-index'); // for remote delivery: path and secret // $WWW_FS = '/mit/6.HANDX/www/' . SEMESTER; // $WWW_SECRET = 'abcd1234'; diff --git a/server/structure.php b/server/structure.php index 99be46f..f6368b3 100644 --- a/server/structure.php +++ b/server/structure.php @@ -8,15 +8,21 @@ header("Access-Control-Allow-Origin: $origin"); } -function parse($json) { - $configjson = file_get_contents($json.'.json'); - $config = json_decode($configjson); - return $config; +function load_handout($handout_id) { + return json_decode(file_get_contents('data/'.$handout_id.'.json')); } -function incl($config) { - global $HANDOUT_TOC_KINDS; - return in_array($config->kind, $HANDOUT_TOC_KINDS) && ! property_exists($config, 'noindex'); +function collect_handouts($handout_ids) { + $handouts = array_map(load_handout, array_values($handout_ids)); + $array_of_array_of_handouts = array_map(function($config) { + return collect_handouts($config->handoutsToIndex); + }, $handouts); + foreach ($array_of_array_of_handouts as $array_of_handouts) { + foreach ($array_of_handouts as $config) { + array_push($handouts, $config); + } + } + return $handouts; } function entry($config) { @@ -27,7 +33,10 @@ function entry($config) { } header('Content-Type: application/json'); -$configs = array_map(function($name) { return substr($name, 0, -5); }, glob('data/*.json')); -natsort($configs); -print json_encode(array_map(entry, array_values(array_filter(array_map(parse, array_values($configs)), incl)))); + +$configs = collect_handouts($HANDOUT_TOC_ROOTS); +$configs = array_values(array_filter($configs, function($config) { return ! property_exists($config, 'noindex'); +})); +//natsort($configs); // rely on the in-order traversal of handoutsToIndex +print json_encode(array_map(entry, $configs)); ?> diff --git a/web/handout/handout-render.js b/web/handout/handout-render.js index dec12f0..cfc4578 100644 --- a/web/handout/handout-render.js +++ b/web/handout/handout-render.js @@ -189,6 +189,12 @@ function renderPage() { id: this.id, }; }).toArray(); + window.handoutsToIndex = $('[data-handx-index] a').map(function() { + const href = $(this).attr('href'); + const m = href.match(/([\w-]+\/[\w-]+)\/handout\//); + if (! m) return undefined; + return m[1].replace(/[^\w-]/g, '-'); + }).toArray(); if (window.HANDOUT_DID_RENDER) { window.HANDOUT_DID_RENDER(); } if (window.onHandoutDidRender) { window.onHandoutDidRender(); } @@ -501,6 +507,7 @@ function handoutDeliveryCallback() { handout, part: part || null, structure: window.handoutStructure, + handoutsToIndex: window.handoutsToIndex, exercises: window.handoutExercises, noindex: document.querySelector('script[data-handx-noindex]') ? true : undefined, }); From 09ed8674e623b1e641da4a2854c0d8e32d3dc7d4 Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Thu, 29 Dec 2022 12:50:25 -0500 Subject: [PATCH 3/3] fixed bug in lambda delivery script when a handout/ folder is deleted from the git repo --- lambda/src/index.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lambda/src/index.ts b/lambda/src/index.ts index 236647b..7f85864 100644 --- a/lambda/src/index.ts +++ b/lambda/src/index.ts @@ -1,6 +1,6 @@ import { spawnSync } from 'child_process'; import { createHmac }from 'crypto'; -import { readFileSync, writeFileSync } from 'fs'; +import { readFileSync, writeFileSync, existsSync } from 'fs'; import { request } from 'https'; import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; @@ -162,6 +162,10 @@ function findUpdated(before: string, after: string, cwd: string): Set { } function findDirs(cwd: string): string[] { + if ( ! existsSync(cwd) ) { + console.log(cwd, 'does not exist in git clone, skipping'); + return []; + } const { stdout, error } = spawnSync('/var/task/bin/find', [ '-L', '.', '-mindepth', '1', '-type', 'd' ], { cwd, encoding: 'utf8' }); if (error) { throw error; } @@ -169,6 +173,10 @@ function findDirs(cwd: string): string[] { } function findFiles(cwd: string): string[] { + if ( ! existsSync(cwd) ) { + console.log(cwd, 'does not exist in git clone, skipping'); + return []; + } const { stdout, error } = spawnSync('/var/task/bin/find', [ '-L', '.', '-type', 'f' ], { cwd, encoding: 'utf8' }); if (error) { throw error; }