2021-11-30 03:11:28 +00:00
|
|
|
from flask import Blueprint, render_template, request, redirect, jsonify, session, abort, flash
|
2021-11-28 18:17:50 +00:00
|
|
|
from flask.helpers import url_for
|
2021-11-25 23:12:20 +00:00
|
|
|
from datetime import datetime
|
|
|
|
from uuid import uuid4
|
2021-11-28 18:17:50 +00:00
|
|
|
import os
|
|
|
|
from json import loads
|
2021-11-25 23:12:20 +00:00
|
|
|
|
2021-11-28 18:17:50 +00:00
|
|
|
from main import app, db
|
2021-11-28 02:30:46 +00:00
|
|
|
from common.security import encrypt
|
2021-11-28 18:17:50 +00:00
|
|
|
from common.data_tools import generate_questions
|
2021-11-23 13:00:03 +00:00
|
|
|
|
|
|
|
views = Blueprint(
|
|
|
|
'quiz_views',
|
|
|
|
__name__,
|
2021-11-24 17:17:56 +00:00
|
|
|
static_url_path='',
|
2021-11-23 13:00:03 +00:00
|
|
|
template_folder='templates',
|
|
|
|
static_folder='static'
|
|
|
|
)
|
|
|
|
|
|
|
|
@views.route('/')
|
|
|
|
@views.route('/home/')
|
|
|
|
def home():
|
2021-11-24 17:17:56 +00:00
|
|
|
return render_template('/quiz/index.html')
|
|
|
|
|
|
|
|
@views.route('/start/', methods = ['GET', 'POST'])
|
|
|
|
def start():
|
|
|
|
from .forms import StartQuiz
|
|
|
|
form = StartQuiz()
|
2021-11-25 23:12:20 +00:00
|
|
|
if request.method == 'GET':
|
|
|
|
return render_template('/quiz/start-quiz.html', form=form)
|
|
|
|
if request.method == 'POST':
|
|
|
|
if form.validate_on_submit():
|
|
|
|
name = {
|
|
|
|
'first_name': request.form.get('first_name'),
|
|
|
|
'surname': request.form.get('surname')
|
|
|
|
}
|
|
|
|
email = request.form.get('email')
|
|
|
|
club = request.form.get('club')
|
|
|
|
test_code = request.form.get('test_code').replace('—', '')
|
|
|
|
user_code = request.form.get('user_code')
|
|
|
|
user_code = None if user_code == '' else user_code
|
|
|
|
if not db.tests.find_one({'test_code': test_code}):
|
|
|
|
return jsonify({'error': 'The exam code you entered is invalid.'}), 400
|
2021-11-28 17:28:14 +00:00
|
|
|
entry = {
|
2021-11-25 23:12:20 +00:00
|
|
|
'_id': uuid4().hex,
|
|
|
|
'name': encrypt(name),
|
|
|
|
'email': encrypt(email),
|
|
|
|
'club': encrypt(club),
|
2021-11-28 18:17:50 +00:00
|
|
|
'test_code': test_code,
|
2021-11-25 23:12:20 +00:00
|
|
|
'user_code': user_code,
|
2021-11-30 03:11:28 +00:00
|
|
|
# 'start_time': datetime.utcnow(), TODO move start time to after configuration.
|
|
|
|
# 'status': 'started'
|
2021-11-25 23:12:20 +00:00
|
|
|
}
|
2021-11-28 17:28:14 +00:00
|
|
|
if db.entries.insert(entry):
|
2021-11-30 03:11:28 +00:00
|
|
|
session['_id'] = entry['_id'] # TODO Change this to return _id via JSON so client can access. Client will not be able to decrypt session cookie.
|
2021-11-28 18:17:50 +00:00
|
|
|
return jsonify({
|
2021-11-30 03:11:28 +00:00
|
|
|
'success': 'Received and validated test and/or user code. Redirecting to test client.',
|
2021-11-28 18:17:50 +00:00
|
|
|
'_id': entry['_id']
|
|
|
|
}), 200
|
2021-11-25 23:12:20 +00:00
|
|
|
else:
|
|
|
|
errors = [*form.errors]
|
|
|
|
return jsonify({ 'error': errors}), 400
|
|
|
|
|
2021-11-30 03:11:28 +00:00
|
|
|
@views.route('/api/questions/', methods=['POST'])
|
|
|
|
def fetch_questions():
|
|
|
|
_id = request.get_json()['_id']
|
2021-11-28 18:17:50 +00:00
|
|
|
entry = db.entries.find_one({'_id': _id})
|
|
|
|
if not entry:
|
|
|
|
return abort(404)
|
|
|
|
test_code = entry['test_code']
|
2021-11-30 03:11:28 +00:00
|
|
|
# user_code = entry['user_code'] TODO Implement functionality for adjustments
|
2021-11-28 18:17:50 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
})
|
|
|
|
|
2021-11-30 03:11:28 +00:00
|
|
|
@views.route('/test/')
|
|
|
|
def start_quiz():
|
|
|
|
_id = session.get('_id')
|
|
|
|
if not _id or not db.entries.find_one({'_id': _id}):
|
|
|
|
flash('Your log in was not recognised. Please sign in to the quiz again.', 'error')
|
|
|
|
return redirect(url_for('quiz_views.start'))
|
|
|
|
return render_template('quiz/client.html')
|
2021-11-28 18:17:50 +00:00
|
|
|
|
2021-11-23 13:00:03 +00:00
|
|
|
|
|
|
|
@views.route('/privacy/')
|
|
|
|
def privacy():
|
2021-11-25 23:12:20 +00:00
|
|
|
return render_template('/quiz/privacy.html')
|