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; } 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 e881202..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(); } @@ -436,6 +442,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 @@ -492,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, });