Added automated email notification of results.

This commit is contained in:
Vivek Santayana 2021-12-01 00:46:21 +00:00
parent 3d5939ed9c
commit c57461f118

View File

@ -4,10 +4,11 @@ from datetime import datetime, timedelta
from uuid import uuid4 from uuid import uuid4
import os import os
from json import loads from json import loads
from flask_mail import Message
from pymongo.collection import ReturnDocument from pymongo.collection import ReturnDocument
from main import app, db from main import app, db, mail
from common.security import encrypt from common.security import encrypt
from common.data_tools import generate_questions, evaluate_answers from common.data_tools import generate_questions, evaluate_answers
from common.security.database import decrypt_find_one from common.security.database import decrypt_find_one
@ -28,6 +29,13 @@ def home():
return redirect(url_for('quiz_views.start_quiz')) return redirect(url_for('quiz_views.start_quiz'))
return render_template('/quiz/index.html') return render_template('/quiz/index.html')
@views.route('/instructions/')
def instructions():
_id = session.get('_id')
if _id and db.entries.find_one({'_id': _id}):
return redirect(url_for('quiz_views.start_quiz'))
return render_template('/quiz/instructions.html')
@views.route('/start/', methods = ['GET', 'POST']) @views.route('/start/', methods = ['GET', 'POST'])
def start(): def start():
from .forms import StartQuiz from .forms import StartQuiz
@ -78,7 +86,7 @@ def fetch_questions():
_id = request.get_json()['_id'] _id = request.get_json()['_id']
entry = db.entries.find_one({'_id': _id}) entry = db.entries.find_one({'_id': _id})
if not entry: if not entry:
return abort(404) return jsonify({'error': 'The data that the client sent to the server is invalid. This is possibly because you have already submitted your exam and have tried to access the page again.'}), 400
test_code = entry['test_code'] test_code = entry['test_code']
# user_code = entry['user_code'] TODO Implement functionality for adjustments # user_code = entry['user_code'] TODO Implement functionality for adjustments
@ -153,9 +161,59 @@ def result():
return abort(404) return abort(404)
score = round(100*entry['results']['score']/entry['results']['max']) score = round(100*entry['results']['score']/entry['results']['max'])
tags_low = { tag: tag_result['max'] - tag_result['scored'] for tag, tag_result in entry['results']['tags'].items() } tags_low = { tag: tag_result['max'] - tag_result['scored'] for tag, tag_result in entry['results']['tags'].items() }
sorted_low = sorted(tags_low.items(), key=lambda x: x[1], reverse=True) sorted_low_tags = sorted(tags_low.items(), key=lambda x: x[1], reverse=True)
show_low_tags = sorted_low[0:3] tag_output = [ tag[0] for tag in sorted_low_tags[0:3] if tag[1] > 3]
return render_template('/quiz/result.html', entry=entry, score=score, show_low_tags=show_low_tags) if entry['results']['grade'] == 'pass':
flavour_text_plain = """Well done on successfully completing the refereeing theory exam. We really appreciate members of our community taking the time to get qualified to referee.
"""
elif entry['results']['grade'] == 'merit':
flavour_text_plain = """Congratulations on achieving a merit in the refereeing exam. We are delighted that members of our community work so hard with refereeing.
"""
elif entry['results']['grade'] == 'fail':
flavour_text_plain = """Unfortunately, you were not successful in passing the theory exam in this attempt. We hope that this does not dissuade you, and that you try again in the future.
"""
email = Message(
subject="SKA Refereeing Theory Exam Results",
recipients=[entry['email']],
body=f"""SKA Refereeing Theory Exam\n\n
Candidate Results\n\n
Dear {entry['name']['first_name']},\n\n
This email is to confirm that you have took the SKA Refereeing Theory Exam. Your test has been evaluated and your results have been generated.\n\n
{entry['name']['surname']}, {entry['name']['first_name']}\n\n
Email Address: {entry['email']}\n
{f"Club: {entry['club']}" if entry['club'] else ''}\n
Date of Test: {entry['submission_time'].strftime('%d %b %Y')}\n
Score: {score}%\n
Grade: {entry['results']['grade']}\n\n
{flavour_text_plain}\n\n
Based on your answers, we would also suggest you brush up on the following topics as you continue refereeing:\n\n
{','.join(tag_output)}\n\n
Thank you for taking the time to get qualified as a referee.\n\n
Best wishes,\n
SKA Refereeing
""",
html=f"""<h1>SKA Refereeing Theory Exam</h1>
<h2>Candidate Results</h2>
<p>Dear {entry['name']['first_name']},</p>
<p>This email is to confirm that you have took the SKA Refereeing Theory Exam. Your test has been evaluated and your results have been generated.</p>
<h3>{entry['name']['surname']}, {entry['name']['first_name']}</h3>
<p><strong>Email Address</strong>: {entry['email']}</p>
{f"<p><strong>Club</strong>: {entry['club']}</p>" if entry['club'] else ''}
<p><strong>Date of Test</strong>: {entry['submission_time'].strftime('%d %b %Y')}</p>
<h1>{score}%</h1>
<h2>{entry['results']['grade']}</h2>
<p>{flavour_text_plain}</p>
<p>Based on your answers, we would also suggest you revise the following topics as you continue refereeing:</p>
<ul>
<li>{'</li><li>'.join(tag_output)}</li>
</ul>
<p>Thank you for taking the time to get qualified as a referee.</p>
<p>Best wishes,<br />
SKA Refereeing</p>
""",
)
mail.send(email)
return render_template('/quiz/result.html', entry=entry, score=score, tag_output=tag_output)
@views.route('/privacy/') @views.route('/privacy/')
def privacy(): def privacy():