2022-06-16 01:03:06 +01:00
from . . forms . quiz import StartQuiz
from . . models import Entry , Test
2022-06-20 11:27:05 +01:00
from . . tools . forms import send_errors_to_client
2022-08-20 10:56:43 +01:00
from . . tools . logs import write
2022-06-16 01:03:06 +01:00
from . . tools . test import redirect_if_started
2022-08-20 10:56:43 +01:00
from flask import Blueprint , jsonify , render_template , request , session
from flask . helpers import abort , flash , redirect , url_for
2022-06-16 01:03:06 +01:00
from datetime import datetime
2022-06-11 02:39:47 +01:00
quiz = Blueprint (
name = ' quiz ' ,
import_name = __name__ ,
template_folder = ' templates ' ,
2022-06-16 10:44:48 +01:00
static_folder = ' static ' ,
static_url_path = ' /quiz/static '
2022-06-11 02:39:47 +01:00
)
@quiz.route ( ' / ' )
@quiz.route ( ' /home/ ' )
2022-06-16 01:03:06 +01:00
@redirect_if_started
2022-06-11 02:39:47 +01:00
def _home ( ) :
2022-06-16 01:03:06 +01:00
return render_template ( ' /quiz/index.html ' )
2022-06-11 02:39:47 +01:00
@quiz.route ( ' /instructions/ ' )
def _instructions ( ) :
2022-06-16 01:03:06 +01:00
return render_template ( ' /quiz/instructions.html ' )
2022-06-11 02:39:47 +01:00
2022-06-16 10:44:48 +01:00
@quiz.route ( ' /start/ ' , methods = [ ' GET ' , ' POST ' ] )
2022-06-11 02:39:47 +01:00
def _start ( ) :
2023-02-03 16:06:06 +00:00
clubs = [
' Dundee Korfball Club ' ,
' Edinburgh City Korfball Club ' ,
' Edinburgh Mavericks Korfball Club ' ,
' Edinburgh University Korfball Club ' ,
' Glasgow Korfball Club ' ,
' Saint Andrews University Korfball Club ' ,
' Strathclyde University Korfball Club '
]
try : entries = Entry . query . all ( )
except Exception as exception :
write ( ' system.log ' , f ' Database error when processing request \' { request . url } \' : { exception } ' )
return abort ( 500 )
for entry in entries : clubs . append ( entry . get_club ( ) )
clubs = list ( set ( clubs ) )
try : clubs . remove ( ' ' )
except : pass
2022-06-16 01:03:06 +01:00
form = StartQuiz ( )
if request . method == ' POST ' :
if form . validate_on_submit ( ) :
entry = Entry ( )
entry . set_first_name ( request . form . get ( ' first_name ' ) )
entry . set_surname ( request . form . get ( ' surname ' ) )
entry . set_club ( request . form . get ( ' club ' ) )
2022-06-16 10:44:48 +01:00
entry . set_email ( request . form . get ( ' email ' ) )
2022-06-16 01:03:06 +01:00
code = request . form . get ( ' test_code ' ) . replace ( ' — ' , ' ' ) . lower ( )
2022-08-20 10:56:43 +01:00
try : test = Test . query . filter_by ( code = code ) . first ( )
2022-08-20 14:47:46 +01:00
except Exception as exception :
2022-08-20 10:56:43 +01:00
write ( ' system.log ' , f ' Database error when processing request \' { request . url } \' : { exception } ' )
return abort ( 500 )
2022-06-16 01:03:06 +01:00
entry . test = test
2023-03-04 18:56:10 +00:00
entry . dataset = test . dataset
2022-06-16 01:03:06 +01:00
entry . user_code = request . form . get ( ' user_code ' )
entry . user_code = None if entry . user_code == ' ' else entry . user_code . lower ( )
if not test : return jsonify ( { ' error ' : ' The exam code you entered is invalid. ' } ) , 400
if entry . user_code and entry . user_code not in test . adjustments : return jsonify ( { ' error ' : f ' The user code you entered is not valid. ' } ) , 400
if test . end_date < datetime . now ( ) : return jsonify ( { ' error ' : f ' The exam code you entered expired on { test [ " expiry_date " ] . strftime ( " %d % b % Y % H: % M " ) } . ' } ) , 400
if test . start_date > datetime . now ( ) : return jsonify ( { ' error ' : f ' The exam has not yet opened. Your exam code will be valid from { test [ " start_date " ] . strftime ( " %d % b % Y % H: % M " ) } . ' } ) , 400
2022-06-16 10:44:48 +01:00
success , message = entry . ready ( )
2022-06-16 01:03:06 +01:00
if success :
session [ ' id ' ] = entry . id
return jsonify ( {
' success ' : ' Received and validated test and/or user code. Redirecting to test client. ' ,
' id ' : entry . id
} ) , 200
return jsonify ( { ' error ' : ' There was an error processing the user test and/or user codes. ' } ) , 400
2022-06-20 11:27:05 +01:00
return send_errors_to_client ( form = form )
2023-02-03 16:06:06 +00:00
return render_template ( ' /quiz/start_quiz.html ' , form = form , clubs = clubs )
2022-06-11 02:39:47 +01:00
@quiz.route ( ' /quiz/ ' )
def _quiz ( ) :
2022-06-16 01:03:06 +01:00
id = session . get ( ' id ' )
2022-08-20 10:56:43 +01:00
try :
if not id or not Entry . query . filter_by ( id = id ) . first ( ) :
flash ( ' Your session was not recognised. Please sign in to the quiz again. ' , ' error ' )
session . pop ( ' id ' , None )
return redirect ( url_for ( ' quiz._start ' ) )
2022-08-20 14:47:46 +01:00
except Exception as exception :
2022-08-20 10:56:43 +01:00
write ( ' system.log ' , f ' Database error when processing request \' { request . url } \' : { exception } ' )
return abort ( 500 )
2022-06-16 01:03:06 +01:00
return render_template ( ' /quiz/client.html ' )
2022-06-11 02:39:47 +01:00
@quiz.route ( ' /result/ ' )
def _result ( ) :
2022-06-16 01:03:06 +01:00
id = session . get ( ' id ' )
2022-08-20 10:56:43 +01:00
try : entry = Entry . query . filter_by ( id = id ) . first ( )
2022-08-20 14:47:46 +01:00
except Exception as exception :
2022-08-20 10:56:43 +01:00
write ( ' system.log ' , f ' Database error when processing request \' { request . url } \' : { exception } ' )
return abort ( 500 )
2022-06-16 10:44:48 +01:00
if not entry : return abort ( 404 )
session . pop ( ' id ' , None )
score = round ( 100 * entry . result [ ' score ' ] / entry . result [ ' max ' ] )
tags_low = { tag : tag_result [ ' max ' ] - tag_result [ ' scored ' ] for tag , tag_result in entry . result [ ' tags ' ] . items ( ) }
2022-06-16 01:03:06 +01:00
sorted_low_tags = sorted ( tags_low . items ( ) , key = lambda x : x [ 1 ] , reverse = True )
tag_output = [ tag [ 0 ] for tag in sorted_low_tags [ 0 : 3 ] if tag [ 1 ] > 3 ]
2022-06-16 10:44:48 +01:00
if not entry . status == ' late ' :
2022-06-16 12:46:03 +01:00
entry . notify_result ( )
2022-06-16 01:03:06 +01:00
return render_template ( ' /quiz/result.html ' , entry = entry , score = score , tag_output = tag_output )