diff --git a/physics/views.py b/physics/views.py index 64f03bf4..5f6c0911 100644 --- a/physics/views.py +++ b/physics/views.py @@ -1,6 +1,6 @@ from django.contrib.contenttypes.models import ContentType from django.utils import timezone -from generic.models import CidUser +from generic.models import CidUser, ExamUserStatus, CidUserExam from physics.decorators import user_is_author_or_physics_checker from physics.filters import QuestionFilter, UserAnswerFilter from generic.mixins import CheckCanEditMixin, SuperuserRequiredMixin @@ -148,6 +148,18 @@ def exam_complete(request, pk, cid=None, passcode=None): cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user) cid_user_exam.complete_exam() + try: + ct = ContentType.objects.get_for_model(exam) + ExamUserStatus.objects.create( + content_type=ct, + object_id=exam.pk, + cid_user_exam=cid_user_exam, + status="completed", + extra="physics", + ) + except Exception: + # avoid crashing the user flow if logging fails + pass return HttpResponse("") @@ -178,8 +190,29 @@ def exam_take_overview(request, pk, cid=None, passcode=None): else: question_answer_tuples.append((q, None)) + # detect whether a CidUserExam already exists so we only log the initial start once + content_type = ContentType.objects.get_for_model(exam) + existing = False + if cid is not None: + cid_user_obj = CidUser.objects.filter(cid=cid).first() + existing = CidUserExam.objects.filter(content_type=content_type, object_id=exam.pk, cid_user=cid_user_obj).exists() + else: + existing = CidUserExam.objects.filter(content_type=content_type, object_id=exam.pk, user_user=request.user).exists() + cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user) + if not existing: + try: + ExamUserStatus.objects.create( + content_type=content_type, + object_id=exam.pk, + cid_user_exam=cid_user_exam, + status="started", + extra="physics", + ) + except Exception: + pass + return render( request, "physics/exam_take_overview.html", diff --git a/requirements.txt b/requirements.txt index 7c27d67e..4ec9202c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -58,4 +58,5 @@ requests pygments celery[redis] redis -pywatchman \ No newline at end of file +pywatchman +numpy==2.4.0 \ No newline at end of file diff --git a/sbas/views.py b/sbas/views.py index 09965dec..5790808e 100644 --- a/sbas/views.py +++ b/sbas/views.py @@ -1,7 +1,7 @@ from reversion.views import RevisionMixin from generic.mixins import CheckCanEditMixin, SuperuserRequiredMixin from django.views.generic.detail import DetailView -from generic.models import CidUser +from generic.models import CidUser, ExamUserStatus, CidUserExam from sbas.forms import UserAnswerForm, ExamAuthorForm, ExamForm from django.shortcuts import render, get_object_or_404, redirect from django.views.decorators.csrf import csrf_exempt @@ -306,6 +306,17 @@ def exam_complete(request, pk, cid=None, passcode=None): cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user) cid_user_exam.complete_exam() + try: + ct = ContentType.objects.get_for_model(exam) + ExamUserStatus.objects.create( + content_type=ct, + object_id=exam.pk, + cid_user_exam=cid_user_exam, + status="completed", + extra="sbas", + ) + except Exception: + pass return HttpResponse("") @@ -366,8 +377,29 @@ def exam_take(request, pk: int, sk: int, cid: int = None, passcode: str = None): exam.check_user_can_take(cid, passcode, request.user) + # log start only when a new CidUserExam is created + content_type = ContentType.objects.get_for_model(exam) + existing = False + if cid is not None: + cid_user_obj = CidUser.objects.filter(cid=cid).first() + existing = CidUserExam.objects.filter(content_type=content_type, object_id=exam.pk, cid_user=cid_user_obj).exists() + else: + existing = CidUserExam.objects.filter(content_type=content_type, object_id=exam.pk, user_user=request.user).exists() + cid_user_exam = exam.get_or_create_cid_user_exam(cid = cid, user_user=request.user) + if not existing: + try: + ExamUserStatus.objects.create( + content_type=content_type, + object_id=exam.pk, + cid_user_exam=cid_user_exam, + status="started", + extra="sbas", + ) + except Exception: + pass + question = exam.get_questions()[sk] exam_length = len(exam.exam_questions.all())