Added question generating API
This commit is contained in:
		@@ -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
 | 
			
		||||
    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
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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():
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user