This commit is contained in:
Ross
2022-06-29 22:01:45 +01:00
parent 09d9c42a59
commit 9699d20192
7 changed files with 58 additions and 8 deletions
+1
View File
@@ -72,6 +72,7 @@ urlpatterns = [
),
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),
+6 -5
View File
@@ -324,7 +324,7 @@ class ExamBase(models.Model):
return msg
def email_user_results(self, user, resend=False, additional_emails=list):
def email_user_results(self, user, resend=False, additional_emails=None):
#if self.results_email_sent and not resend:
# return False, "Already sent."
@@ -332,7 +332,7 @@ class ExamBase(models.Model):
msg = self.generate_user_report(user)
if not user.email:
return False, "User has no email"
return [False, "User has no email"]
emails = [user.email]
@@ -342,7 +342,7 @@ class ExamBase(models.Model):
emails.append(supervisor_email)
if additional_emails:
if additional_emails is not None:
emails.extend(additional_emails)
try:
@@ -355,11 +355,11 @@ class ExamBase(models.Model):
# html_message=html_msg,
)
except SMTPException as e:
return False, e
return [False, e]
#self.results_email_sent = True
#self.save()
return True, ""
return [True, ""]
class NoteType(models.Model):
@@ -608,6 +608,7 @@ class CidUserExam(models.Model):
manual_submission = models.BooleanField(default=False)
# TODO switch to json field?
results_emailed_status = models.CharField(max_length=255, blank=True)
@@ -91,6 +91,7 @@
<summary>Email results</summary>
User results emailed: {{exam.exam_results_emailed|default:"Never"}}<br/>
<button id="email-results-button" title="Email results to users and their supervisors">Email user results</button>
<button id="email-unsent-results-button" title="Email results to users and their supervisors">Email unsent user results</button>
<button id="email-results-check-button" title="Check the status of emailed results">Check email status</button>
<p>Note: currently only works with registered users</p>
</details>
@@ -116,6 +117,23 @@
}
evt.preventDefault();
})
$("#email-unsent-results-button").click((evt) => {
if (confirm("This will email results, please make sure scores have been refreshed before continuing")) {
let additional_email = prompt("Please enter an additional email to send to (user and supervisor will automatically be used if available) if required");
let url = "{% url exam.app_name|add:':exam_report_email_unsent' exam_id=exam.pk %}";
if ( additional_email != null ) {
url = url + "?additional_email="+encodeURI(additional_email)
}
window.location = url;
}
evt.preventDefault();
})
$("#email-results-check-button").click((evt) => {
window.location = "{% url exam.app_name|add:':exam_report_email_status' exam_id=exam.pk %}";
+29 -3
View File
@@ -560,6 +560,20 @@ class ExamViews(View, LoginRequiredMixin):
},
)
@method_decorator(login_required)
def exam_user(self, request, exam_id, user_id):
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
if request.user not in exam.author.all():
if not self.check_user_access(request.user, exam_id):
raise PermissionDenied
user = User.objects.get(pk=user_id)
user_exam = exam.get_or_create_cid_user_exam(user_user=user)
return JsonResponse(model_to_dict(user_exam))
@method_decorator(login_required)
def exam_report_email_status(self, request, exam_id):
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
@@ -578,9 +592,12 @@ class ExamViews(View, LoginRequiredMixin):
return JsonResponse(status)
@method_decorator(login_required)
def exam_report_email_unsent(self, request, exam_id):
return self.exam_report_email(request, exam_id, unsent_only=True)
@method_decorator(login_required)
def exam_report_email(self, request, exam_id):
def exam_report_email(self, request, exam_id, unsent_only=False):
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
if request.user not in exam.author.all():
@@ -606,13 +623,22 @@ class ExamViews(View, LoginRequiredMixin):
email_results = {}
for u in users:
user = User.objects.get(pk=u)
user_exam = exam.get_or_create_cid_user_exam(user_user=user)
if unsent_only and user_exam.results_emailed_status:
continue
#print(user, user_exam.results_emailed_status)
#if json.loads(user_exam.results_emailed_status)[0] == True:
# continue
if additional_email:
email_results[user.username] = exam.email_user_results(user, additional_emails=[additional_email])
else:
email_results[user.username] = exam.email_user_results(user)
email_results[user.username].append(f" {time}")
user_exam.results_emailed_status = json.dumps(email_results[user.username])
user_exam = exam.get_or_create_cid_user_exam(user_user=user)
user_exam.results_emailed_status = json.dumps(email_results[user.username]) + f" {time}"
user_exam.save()
exam.exam_results_emailed = time
+1
View File
@@ -27,6 +27,7 @@ urlpatterns = [
),
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),
+2
View File
@@ -72,7 +72,9 @@ urlpatterns = [
name="exam_question_detail",
),
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
path("exam/<int:exam_id>/user/<int:user_id>", views.GenericExamViews.exam_user, name="exam_user"),
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),
+1
View File
@@ -27,6 +27,7 @@ urlpatterns = [
),
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),