.
This commit is contained in:
+152
-33
@@ -1,4 +1,4 @@
|
||||
from collections import defaultdict
|
||||
from collections import defaultdict, Counter
|
||||
import statistics
|
||||
import threading
|
||||
from dal import autocomplete
|
||||
@@ -294,7 +294,9 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
# exam_group = group_map[self.app_name]
|
||||
|
||||
class ExamFilter(FilterSet):
|
||||
sort_order = OrderingFilter(fields=(("name", "name"), ("exam_mode", "exam_mode")))
|
||||
sort_order = OrderingFilter(
|
||||
fields=(("name", "name"), ("exam_mode", "exam_mode"))
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = exam
|
||||
@@ -529,16 +531,15 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
def exam_list(self, request, all=False):
|
||||
|
||||
if not self.check_user_access(request.user):
|
||||
#raise PermissionDenied
|
||||
exam_list = self.Exam.objects.filter(author__id=request.user.id).order_by("name")
|
||||
# raise PermissionDenied
|
||||
exam_list = self.Exam.objects.filter(author__id=request.user.id).order_by(
|
||||
"name"
|
||||
)
|
||||
else:
|
||||
exam_list = self.Exam.objects.all().order_by("name")
|
||||
|
||||
if not all:
|
||||
exams = exam_list.filter(exam_mode=True, archive=False).order_by(
|
||||
"name"
|
||||
)
|
||||
|
||||
exams = exam_list.filter(exam_mode=True, archive=False).order_by("name")
|
||||
|
||||
marking = False
|
||||
|
||||
@@ -556,6 +557,90 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
},
|
||||
)
|
||||
|
||||
@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)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, exam_id):
|
||||
raise PermissionDenied
|
||||
|
||||
users = [i[2:] for i in exam.user_scores if i.startswith("u/")]
|
||||
|
||||
status = {}
|
||||
for u in users:
|
||||
user = User.objects.get(pk=u)
|
||||
user_exam = exam.get_or_create_cid_user_exam(user_user=user)
|
||||
status[user.username] = user_exam.results_emailed_status
|
||||
|
||||
return JsonResponse(status)
|
||||
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_report_email(self, request, exam_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
|
||||
|
||||
|
||||
# We only need to send emails to those who have scores
|
||||
# (who should be in exam.user_scores)
|
||||
users = [i[2:] for i in exam.user_scores if i.startswith("u/")]
|
||||
|
||||
time = timezone.now()
|
||||
|
||||
email_results = {}
|
||||
for u in users:
|
||||
user = User.objects.get(pk=u)
|
||||
email_results[user.username] = exam.email_user_results(user)
|
||||
|
||||
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
|
||||
exam.save()
|
||||
|
||||
return JsonResponse(email_results)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_user_report_email(self, request, exam_id, user_id):
|
||||
# print(Exam.objects.all())
|
||||
# exams = Exam.objects.all()
|
||||
# print("test", Exam.objects.all().get(id=pk))
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
|
||||
u = get_object_or_404(User, pk=user_id)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, exam_id):
|
||||
raise PermissionDenied
|
||||
|
||||
res = exam.email_user_results(u)
|
||||
|
||||
return HttpResponse(res)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_user_report(self, request, exam_id, user_id):
|
||||
# print(Exam.objects.all())
|
||||
# exams = Exam.objects.all()
|
||||
# print("test", Exam.objects.all().get(id=pk))
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
|
||||
u = get_object_or_404(User, pk=user_id)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, exam_id):
|
||||
raise PermissionDenied
|
||||
|
||||
res = exam.generate_user_report(u)
|
||||
print(res)
|
||||
|
||||
return HttpResponse(res)
|
||||
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_overview(self, request, pk):
|
||||
# print(Exam.objects.all())
|
||||
@@ -563,6 +648,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
# print("test", Exam.objects.all().get(id=pk))
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=pk)
|
||||
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, pk):
|
||||
raise PermissionDenied
|
||||
@@ -1396,6 +1482,10 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
by_question = defaultdict(dict)
|
||||
unmarked = set()
|
||||
|
||||
if self.app_name in ("rapids"):
|
||||
user_answers_callstates = defaultdict(list)
|
||||
user_answers_callstates_counted = {}
|
||||
|
||||
if self.app_name in ("physics", "sbas"):
|
||||
questions = exam.exam_questions.all()
|
||||
else:
|
||||
@@ -1408,15 +1498,18 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
cids = set()
|
||||
|
||||
cids_user_id_map = {}
|
||||
|
||||
# Loop through all candidates
|
||||
for cid_user_answer in cid_user_answers:
|
||||
# Convoluted (probably...)
|
||||
if cid_user_answer.user is None:
|
||||
cid = cid_user_answer.cid
|
||||
# cid_passcodes[cid] = cid_user_answer.passcode
|
||||
cids.add(cid)
|
||||
cids.add("c/"+cid)
|
||||
else:
|
||||
cid = f"u/{cid_user_answer.user.username}"
|
||||
cid = f"u/{cid_user_answer.user.pk}"
|
||||
cids_user_id_map[cid] = cid_user_answer.user.username
|
||||
cids.add(cid)
|
||||
|
||||
s = cid_user_answer
|
||||
@@ -1439,9 +1532,15 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
unmarked.add(index)
|
||||
user_answers[cid].append(ans)
|
||||
user_answers_marks[cid].append(answer_score)
|
||||
# user_answers_and_marks[cid].append((ans, answer_score))
|
||||
|
||||
if self.app_name in ("rapids", "anatomy", "sbas"):
|
||||
if self.app_name == "rapids":
|
||||
callstate = s.get_answer_callstate()
|
||||
print(cid, callstate)
|
||||
by_question[q][cid] = (ans, answer_score, callstate)
|
||||
user_answers_callstates[cid].append(callstate)
|
||||
print(user_answers_callstates)
|
||||
print("CID:::",cid, user_answers_callstates[cid])
|
||||
elif self.app_name in ("rapids", "anatomy", "sbas"):
|
||||
by_question[q][cid] = (ans, answer_score)
|
||||
else:
|
||||
zipped_ans_scores = zip(ans, answer_score)
|
||||
@@ -1513,33 +1612,53 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
exam.stats_graph = fig_html
|
||||
|
||||
exam.user_scores = user_scores
|
||||
user_data = {}
|
||||
for u in cids:
|
||||
#uid = cids_user_id_map[u]
|
||||
user_data[u] = {
|
||||
"score": user_scores[u],
|
||||
"normalised_score": user_scores_normalised[u],
|
||||
}
|
||||
|
||||
if self.app_name == "rapids":
|
||||
counted_callstates = dict(Counter(user_answers_callstates[u]))
|
||||
user_data[u]["callstates"] = str(counted_callstates)
|
||||
user_answers_callstates_counted[u] = counted_callstates
|
||||
|
||||
print(user_data)
|
||||
|
||||
exam.user_scores = user_data
|
||||
|
||||
exam.save()
|
||||
|
||||
template_variables = {
|
||||
"cids": sorted(cids),
|
||||
# "cid_passcodes": cid_passcodes,
|
||||
"exam": exam,
|
||||
"unmarked": unmarked,
|
||||
"questions": questions,
|
||||
"by_question": by_question,
|
||||
# "user_answers": dict(user_answers),
|
||||
# "user_answers_marks": dict(user_answers_marks),
|
||||
"user_scores": user_scores,
|
||||
"user_scores_normalised": user_scores_normalised,
|
||||
# "user_scores_list": user_scores_list,
|
||||
# "user_names": user_names,
|
||||
# "user_answers_and_marks": user_answers_and_marks,
|
||||
"max_score": max_score,
|
||||
"mean": mean,
|
||||
"median": median,
|
||||
"mode": mode,
|
||||
"plot": fig_html,
|
||||
}
|
||||
|
||||
if self.app_name == "rapids":
|
||||
template_variables["user_answers_callstates"] = user_answers_callstates_counted
|
||||
|
||||
return render(
|
||||
request,
|
||||
f"{self.app_name}/exam_scores_new.html",
|
||||
{
|
||||
"cids": sorted(cids),
|
||||
# "cid_passcodes": cid_passcodes,
|
||||
"exam": exam,
|
||||
"unmarked": unmarked,
|
||||
"questions": questions,
|
||||
"by_question": by_question,
|
||||
# "user_answers": dict(user_answers),
|
||||
# "user_answers_marks": dict(user_answers_marks),
|
||||
"user_scores": user_scores,
|
||||
"user_scores_normalised": user_scores_normalised,
|
||||
# "user_scores_list": user_scores_list,
|
||||
# "user_names": user_names,
|
||||
# "user_answers_and_marks": user_answers_and_marks,
|
||||
"max_score": max_score,
|
||||
"mean": mean,
|
||||
"median": median,
|
||||
"mode": mode,
|
||||
"plot": fig_html,
|
||||
},
|
||||
template_variables,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user