2022-06-22 01:57:45 +01:00
|
|
|
from ..models import Dataset, Entry, User
|
|
|
|
from ..tools.data import validate_json
|
2022-08-20 10:56:43 +01:00
|
|
|
from ..tools.logs import write
|
2022-06-14 22:55:11 +01:00
|
|
|
from ..tools.test import evaluate_answers, generate_questions
|
|
|
|
|
2022-08-20 10:56:43 +01:00
|
|
|
from flask import Blueprint, jsonify, request
|
|
|
|
from flask.helpers import abort, flash, url_for
|
2022-06-22 01:57:45 +01:00
|
|
|
from flask_login import login_required
|
2022-08-20 10:56:43 +01:00
|
|
|
from sqlalchemy.exc import SQLAlchemyError
|
2022-06-14 22:55:11 +01:00
|
|
|
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from json import loads
|
2022-06-11 02:39:47 +01:00
|
|
|
|
|
|
|
api = Blueprint(
|
|
|
|
name='api',
|
|
|
|
import_name=__name__
|
|
|
|
)
|
|
|
|
|
|
|
|
@api.route('/questions/', methods=['POST'])
|
|
|
|
def _fetch_questions():
|
2022-06-14 22:55:11 +01:00
|
|
|
id = request.get_json()['id']
|
2022-08-20 10:56:43 +01:00
|
|
|
try: entry = Entry.query.filter_by(id=id).first()
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
write('system.log', f'Database error when processing request \'{request.url}\': {exception}')
|
|
|
|
return abort(500)
|
2022-06-14 22:55:11 +01:00
|
|
|
if not entry: return jsonify({'error': 'Invalid entry ID.'}), 400
|
2022-06-15 23:54:44 +01:00
|
|
|
test = entry.test
|
|
|
|
user_code = entry.user_code
|
|
|
|
time_limit = test.time_limit
|
2022-06-14 22:55:11 +01:00
|
|
|
time_adjustment = 0
|
|
|
|
if time_limit:
|
|
|
|
_time_limit = int(time_limit)
|
|
|
|
if user_code:
|
2022-06-16 10:44:48 +01:00
|
|
|
time_adjustment = test.adjustments[user_code]
|
2022-06-14 22:55:11 +01:00
|
|
|
_time_limit += time_adjustment
|
|
|
|
end_delta = timedelta(minutes=_time_limit)
|
2022-06-22 01:57:45 +01:00
|
|
|
end_time = datetime.now() + end_delta
|
2022-06-14 22:55:11 +01:00
|
|
|
else:
|
|
|
|
end_time = None
|
|
|
|
entry.start()
|
2022-06-15 23:54:44 +01:00
|
|
|
dataset = test.dataset
|
2022-06-14 22:55:11 +01:00
|
|
|
success, message = dataset.check_file()
|
|
|
|
if not success: return jsonify({'error': message}), 500
|
|
|
|
data_path = dataset.get_file()
|
|
|
|
with open(data_path, 'r') as data_file:
|
|
|
|
data = loads(data_file.read())
|
|
|
|
questions = generate_questions(data)
|
|
|
|
return jsonify({
|
|
|
|
'time_limit': end_time,
|
|
|
|
'questions': questions,
|
2022-06-16 10:44:48 +01:00
|
|
|
'start_time': entry.start_time,
|
2022-06-14 22:55:11 +01:00
|
|
|
'time_adjustment': time_adjustment
|
|
|
|
}), 200
|
2022-06-11 02:39:47 +01:00
|
|
|
|
|
|
|
@api.route('/submit/', methods=['POST'])
|
|
|
|
def _submit_quiz():
|
2022-06-14 22:55:11 +01:00
|
|
|
id = request.get_json()['id']
|
|
|
|
answers = request.get_json()['answers']
|
2022-08-20 10:56:43 +01:00
|
|
|
try: entry = Entry.query.filter_by(id=id).first()
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
write('system.log', f'Database error when processing request \'{request.url}\': {exception}')
|
|
|
|
return abort(500)
|
2022-06-16 01:03:06 +01:00
|
|
|
if not entry: return jsonify({'error': 'Unrecognised Entry.'}), 400
|
|
|
|
test = entry.test
|
2022-06-15 23:54:44 +01:00
|
|
|
dataset = test.dataset
|
2022-06-14 22:55:11 +01:00
|
|
|
success, message = dataset.check_file()
|
|
|
|
if not success: return jsonify({'error': message}), 500
|
|
|
|
data_path = dataset.get_file()
|
|
|
|
with open(data_path, 'r') as data_file:
|
|
|
|
data = loads(data_file.read())
|
|
|
|
result = evaluate_answers(answers=answers, key=data)
|
|
|
|
entry.complete(answers=answers, result=result)
|
|
|
|
return jsonify({
|
|
|
|
'success': 'Your submission has been processed. Redirecting you to receive your results.',
|
|
|
|
'id': id
|
|
|
|
}), 200
|
2022-06-22 01:57:45 +01:00
|
|
|
|
|
|
|
@api.route('/editor/', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def _editor(id:str=None):
|
|
|
|
request_data = request.get_json()
|
|
|
|
id = request_data['id']
|
2022-08-20 10:56:43 +01:00
|
|
|
try:
|
|
|
|
dataset = Dataset.query.filter_by(id=id).first()
|
|
|
|
user = User.query.filter_by(id=creator).first()
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
write('system.log', f'Database error when processing request \'{request.url}\': {exception}')
|
|
|
|
return abort(500)
|
2022-06-22 01:57:45 +01:00
|
|
|
if not dataset: return jsonify({'error': 'Invalid request. Dataset not found.'}), 404
|
|
|
|
data_path = dataset.get_file()
|
|
|
|
if request_data['action'] == 'fetch':
|
|
|
|
with open(data_path, 'r') as data_file:
|
|
|
|
data = loads(data_file.read())
|
|
|
|
return jsonify({'success': 'Successfully downloaded dataset', 'data': data}), 200
|
|
|
|
default = request_data['default']
|
|
|
|
creator = request_data['creator']
|
|
|
|
name = request_data['name']
|
|
|
|
data = request_data['data']
|
|
|
|
if not validate_json(data): return jsonify({'error': 'The data you submitted was invalid.'}), 400
|
|
|
|
dataset.set_name(name)
|
|
|
|
dataset.creator = user
|
|
|
|
success, message = dataset.update(data=data, default=default)
|
|
|
|
if not success: return jsonify({'error': message}), 400
|
|
|
|
return jsonify({'success': message}), 200
|
|
|
|
|
|
|
|
@api.route('/editor/new/', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def _editor_new():
|
|
|
|
new_dataset = Dataset()
|
|
|
|
new_dataset.set_name('New Dataset')
|
|
|
|
success, message = new_dataset.create(data=[], default=False)
|
|
|
|
if not success: return jsonify({'error':message}), 400
|
|
|
|
flash(message, 'success')
|
|
|
|
return jsonify({'success': message, 'redirect_to': url_for('editor._editor_console', id=new_dataset.id)}), 200
|