From ac1ad771f07f58374fee04a3ba0c3145c7a4bbbf Mon Sep 17 00:00:00 2001 From: viveksantayana Date: Sun, 28 Nov 2021 18:17:50 +0000 Subject: [PATCH] Added question generating API --- ref-test/common/data_tools.py | 37 ++++++++++++++++++++++++++++- ref-test/quiz/static/js/script.js | 3 ++- ref-test/quiz/views.py | 39 +++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/ref-test/common/data_tools.py b/ref-test/common/data_tools.py index 716ad75..d21819b 100644 --- a/ref-test/common/data_tools.py +++ b/ref-test/common/data_tools.py @@ -2,7 +2,10 @@ import os import pathlib from json import dump, loads from datetime import datetime + +from flask.json import jsonify from main import app +from random import shuffle from werkzeug.utils import secure_filename @@ -58,4 +61,36 @@ def store_data_file(file, default:bool=None): if default: with open(os.path.join(app.config['DATA_FILE_DIRECTORY'], '.default.txt'), 'w') as _file: _file.write(filename) - return filename \ No newline at end of file + return filename + +def randomise_list(list:list): + _list = list.copy() + shuffle(_list) + return(_list) + +def generate_questions(dataset:dict): + questions_list = dataset['questions'] + output = [] + for block in randomise_list(questions_list): + if block['type'] == 'question': + question = { + 'q_type': 'question', + 'q_no': block['q_no'], + 'question_header': '', + 'text': block['text'], + 'options': randomise_list(block['options']) + } + output.append(question) + if block['type'] == 'block': + for key, _question in enumerate(randomise_list(block['questions'])): + question = { + 'q_type': 'block', + 'q_no': _question['q_no'], + 'question_header': block['question_header'] if 'question_header' in block else '', + 'block_length': len(block['questions']), + 'block_q_no': key, + 'text': _question['text'], + 'options': randomise_list(_question['options']) + } + output.append(question) + return output \ No newline at end of file diff --git a/ref-test/quiz/static/js/script.js b/ref-test/quiz/static/js/script.js index 279761c..0a142a4 100644 --- a/ref-test/quiz/static/js/script.js +++ b/ref-test/quiz/static/js/script.js @@ -26,7 +26,8 @@ $('form[name=form-quiz-start]').submit(function(event) { data: data, dataType: 'json', success: function(response) { - window.location.href = "/admin/login/"; + var _id = response._id + window.location.href = `/api/questions/${_id}`; }, error: function(response) { if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) { diff --git a/ref-test/quiz/views.py b/ref-test/quiz/views.py index d08476e..8dedba7 100644 --- a/ref-test/quiz/views.py +++ b/ref-test/quiz/views.py @@ -1,9 +1,13 @@ -from flask import Blueprint, render_template, request, redirect, jsonify +from flask import Blueprint, render_template, request, redirect, jsonify, session, abort +from flask.helpers import url_for from datetime import datetime from uuid import uuid4 +import os +from json import loads -from main import db +from main import app, db from common.security import encrypt +from common.data_tools import generate_questions views = Blueprint( 'quiz_views', @@ -42,17 +46,44 @@ def start(): 'name': encrypt(name), 'email': encrypt(email), 'club': encrypt(club), - 'test-code': test_code, + 'test_code': test_code, 'user_code': user_code, 'start_time': datetime.utcnow(), 'status': 'started' } if db.entries.insert(entry): - return jsonify({ 'success': f'Exam started at started {entry["start_time"].strftime("%H:%M:%S")}.' }) + session['_id'] = entry['_id'] # Change this to return _id via JSON so client can access. Client will not be able to decrypt session cookie. + return jsonify({ + 'success': 'Success! An exam entry was started.', + '_id': entry['_id'] + }), 200 else: errors = [*form.errors] return jsonify({ 'error': errors}), 400 +@views.route('/api/questions/<_id>') +def fetch_questions(_id): + entry = db.entries.find_one({'_id': _id}) + if not entry: + return abort(404) + test_code = entry['test_code'] + # user_code = entry['user_code'] Implement functionality for adjustments + + test = db.tests.find_one({'test_code' : test_code}) + dataset = test['dataset'] + + dataset_path = os.path.join(app.config['DATA_FILE_DIRECTORY'], dataset) + with open(dataset_path, 'r') as data_file: + data = loads(data_file.read()) + + questions = generate_questions(data) + time_limit = test['time_limit'] + return jsonify({ + 'time_limit': time_limit, + 'questions': questions + }) + + @views.route('/privacy/') def privacy():