Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
path("task-list/<subject_abbr>", default_view.tasks_list_all),
path("student-list", default_view.student_list),
path("submits/<int:task_assignment>", default_view.create_submit),
path("info", default_view.info),
path("info", default_view.info, name="api_info"),
path("classes", default_view.class_detail_list),
path("classes/all", default_view.all_classes),
path("classes/<int:class_id>/add_students", default_view.add_student_to_class),
Expand Down
14 changes: 8 additions & 6 deletions quiz/middleware.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from django.http import HttpResponseRedirect
from django.urls import reverse, resolve, Resolver404
from enum import Enum
from quiz.models import EnrolledQuiz
from kelvin.settings import DEBUG
from debug_toolbar.toolbar import DebugToolbar
from quiz.quiz_utils import quiz_running_for_user


class SubmitType(Enum):
Expand All @@ -19,15 +21,16 @@ def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
try:
enrolled_quiz = EnrolledQuiz.objects.get(student=request.user.id, submitted=False)
enrolled_quiz = quiz_running_for_user(request.user)

if enrolled_quiz is not None:
fill_url = reverse("quiz_fill")

allowed_urls = [
fill_url,
reverse("api_quiz_results", args=[enrolled_quiz.id, SubmitType.PERIODIC.value]),
reverse("api_quiz_results", args=[enrolled_quiz.id, SubmitType.MANUAL.value]),
reverse("api_info"),
reverse("cas_ng_logout"),
]

Expand All @@ -37,10 +40,9 @@ def __call__(self, request):
except Resolver404:
pass

if request.path_info not in allowed_urls:
debug_toolbar = DEBUG and DebugToolbar.is_toolbar_request(request)
if not debug_toolbar and request.path_info not in allowed_urls:
return HttpResponseRedirect(fill_url)
except EnrolledQuiz.DoesNotExist:
pass

response = self.get_response(request)

Expand Down
15 changes: 15 additions & 0 deletions quiz/quiz_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.contrib.auth.models import User

from typing import Optional
from common.models import Class
from quiz.models import Quiz, AssignedQuiz, EnrolledQuiz
from web.markdown_utils import process_markdown
Expand All @@ -13,6 +14,20 @@ class QuizException(Exception):
pass


def quiz_running_for_user(user: User) -> Optional[EnrolledQuiz]:
"""
Returns currently running quiz for given user.
If user is not running a quiz at the moment, None is returned.
"""
try:
return EnrolledQuiz.objects.get(student=user.id, submitted=False)
except EnrolledQuiz.DoesNotExist:
return None


User.add_to_class("is_running_quiz", lambda self: quiz_running_for_user(self) is not None)


def quiz_assigned_classes(quiz: Quiz, requested_by: int):
"""
Function that returns a list of classes that are/can be assigned to the quiz.
Expand Down
2 changes: 2 additions & 0 deletions templates/web/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@
<span class="ml-auto navbar-text">
<span class="d-md-none">Logged as: </span><span class="text-body-emphasis">{{ user.get_full_name }} ({{ user.username }})</span>
</span>
{% if not user.is_running_quiz %}
<kelvin-notifications></kelvin-notifications>
{% endif %}

<kelvin-color-theme></kelvin-color-theme>
<li class="nav-item"><a class="nav-link text-primary-emphasis" href="/accounts/logout/?next=/">Logout</a></li>
Expand Down
Loading