From 9b4d70a6ec97a29707c4c0e51cf33e8b93e9d285 Mon Sep 17 00:00:00 2001 From: Rahul Arya Date: Wed, 10 Mar 2021 03:23:54 -0800 Subject: [PATCH 1/2] Add IDs to each question/group --- examtool/examtool/api/convert.py | 2 +- examtool/examtool/api/scramble.py | 10 +++++++++- examtool_web_common/js/ElementEntropy.js | 11 +++++++++++ examtool_web_common/js/Exam.js | 4 +++- examtool_web_common/js/Question.js | 2 ++ 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 examtool_web_common/js/ElementEntropy.js diff --git a/examtool/examtool/api/convert.py b/examtool/examtool/api/convert.py index fec6b86d..6a423c92 100644 --- a/examtool/examtool/api/convert.py +++ b/examtool/examtool/api/convert.py @@ -9,7 +9,7 @@ from examtool.api.utils import list_to_dict, IDFactory -VERSION = 2 # increment when backward-incompatible changes are made +VERSION = 3 # increment when backward-incompatible changes are made def html_convert(x): diff --git a/examtool/examtool/api/scramble.py b/examtool/examtool/api/scramble.py index 937352cb..bc778c25 100644 --- a/examtool/examtool/api/scramble.py +++ b/examtool/examtool/api/scramble.py @@ -46,7 +46,7 @@ def scramble_group_children(): ) get_elements(group)[:] = elements - if version > 1: + if version >= 2: scramble_group_children() if is_compressible_group(group): @@ -62,6 +62,8 @@ def scramble_group_children(): out.append(element) return out + add_entropy(group) + return [group] def scramble_question(question, substitutions, config): @@ -100,6 +102,8 @@ def scramble_question(question, substitutions, config): else: question.pop("solution", None) + add_entropy(question) + return question def substitute(target: dict, list_substitutions, attrs, *, store=True): @@ -137,6 +141,10 @@ def scramble_keep_fixed(objects): for i, object in zip(movable_object_pos, movable_object_values): objects[i] = object + def add_entropy(element): + if version >= 3: + element["entropy"] = hex(random.randrange(2 ** 30)) + global_substitutions = select_substitutions(exam) exam["config"]["scramble_groups"] = exam["config"].get( "scramble_groups", [-1] diff --git a/examtool_web_common/js/ElementEntropy.js b/examtool_web_common/js/ElementEntropy.js new file mode 100644 index 00000000..7500140d --- /dev/null +++ b/examtool_web_common/js/ElementEntropy.js @@ -0,0 +1,11 @@ +import React from "react"; + +export default function ElementEntropy({ entropy }) { + return ( + entropy != null && ( + + [version {entropy}] + + ) + ); +} diff --git a/examtool_web_common/js/Exam.js b/examtool_web_common/js/Exam.js index 378f6c30..5bf75d29 100644 --- a/examtool_web_common/js/Exam.js +++ b/examtool_web_common/js/Exam.js @@ -1,9 +1,10 @@ /* eslint-disable react/no-array-index-key */ import React, { useContext, useEffect } from "react"; import { typeset } from "MathJax"; -import { Col, Jumbotron, Row } from "react-bootstrap"; +import { Col, Form, Jumbotron, Row } from "react-bootstrap"; import Anchor from "./Anchor"; import { inAdminMode } from "./auth"; +import ElementEntropy from "./ElementEntropy"; import ExamContext from "./ExamContext"; import Points from "./Points"; import Question from "./Question"; @@ -94,6 +95,7 @@ export function Group({ group, number, small }) { {/* eslint-disable-next-line react/no-danger */}
+ {group.elements.map((element, i) => element.type === "group" ? ( + {contents} Date: Sat, 13 Mar 2021 01:51:12 -0800 Subject: [PATCH 2/2] Minor fixes --- exam-server/main.py | 3 +++ examtool_web_common/js/Exam.js | 2 +- examtool_web_common/js/Timer.js | 18 ++++++++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/exam-server/main.py b/exam-server/main.py index ca997d27..eafd6ae9 100644 --- a/exam-server/main.py +++ b/exam-server/main.py @@ -38,6 +38,9 @@ def update_cache(): with open("static/index.html") as f: main_html = f.read() + if getenv("ENV") == "dev": + main_html = main_html.replace("production.min", "development") + with open("static/main.js") as f: main_js = f.read() diff --git a/examtool_web_common/js/Exam.js b/examtool_web_common/js/Exam.js index 5bf75d29..0c428549 100644 --- a/examtool_web_common/js/Exam.js +++ b/examtool_web_common/js/Exam.js @@ -1,7 +1,7 @@ /* eslint-disable react/no-array-index-key */ import React, { useContext, useEffect } from "react"; import { typeset } from "MathJax"; -import { Col, Form, Jumbotron, Row } from "react-bootstrap"; +import { Col, Jumbotron, Row } from "react-bootstrap"; import Anchor from "./Anchor"; import { inAdminMode } from "./auth"; import ElementEntropy from "./ElementEntropy"; diff --git a/examtool_web_common/js/Timer.js b/examtool_web_common/js/Timer.js index 17a48b4a..ab9f2096 100644 --- a/examtool_web_common/js/Timer.js +++ b/examtool_web_common/js/Timer.js @@ -7,7 +7,7 @@ export default function Timer({ target, onLock, onEnd }) { const [hover, setHover] = useState(false); const [timeString, setTimeString] = useState(""); - const updateTimeString = () => { + const updateTimeString = (initial) => { const time = Math.round(new Date().getTime() / 1000); const remaining = Math.max(target - time, 0); @@ -21,20 +21,22 @@ export default function Timer({ target, onLock, onEnd }) { .padStart(2, "0")}:${seconds.toString().padStart(2, "0")}` ); - if (target - time < 0 && target - time >= -60) { - onLock(); - setTimeString(`${60 + target - time}s`); - } + if (!initial) { + if (target - time < 0 && target - time >= -60) { + onLock(); + setTimeString(`${60 + target - time}s`); + } - if (target - time < -60) { - onEnd(); + if (target - time < -60) { + onEnd(); + } } }; useInterval(updateTimeString, 1000); if (!timeString) { - updateTimeString(); + updateTimeString(true); } return (